]> granicus.if.org Git - procps-ng/commitdiff
w: add --pids option to display the pid of the login and best processes.
authorJan Pazdziora <jpazdziora@redhat.com>
Wed, 22 Jun 2022 10:07:55 +0000 (12:07 +0200)
committerCraig Small <csmall@dropbear.xyz>
Sun, 15 Jan 2023 04:15:32 +0000 (04:15 +0000)
man/w.1
src/w.c
testsuite/w.test/w.exp

diff --git a/man/w.1 b/man/w.1
index 15a94dc176fb7930ce1ac90021c4aaea85fd97b8..0c1293cfbbbff67679ce1fe8760a5934edc37f4a 100644 (file)
--- a/man/w.1
+++ b/man/w.1
@@ -56,6 +56,9 @@ Display help text and exit.
 \fB\-i\fR, \fB\-\-ip\-addr\fR
 Display IP address instead of hostname for \fBfrom\fR field.
 .TP
+\fB\-p\fR, \fB\-\-pids\fR
+Display pid of the login process/the "what" process in the "what" field.
+.TP
 \fB\-V\fR, \fB\-\-version\fR
 Display version information.
 .TP
diff --git a/src/w.c b/src/w.c
index 63f81c725f6824a4f38d09cbdb04625382711897..2ce2a2e4ed7a6de430df66778fdc4552e6fe9a18 100644 (file)
--- a/src/w.c
+++ b/src/w.c
@@ -357,7 +357,8 @@ static int find_best_proc(
         const char *restrict const tty,
         unsigned long long *restrict const jcpu,
         unsigned long long *restrict const pcpu,
-        char *cmdline)
+        char *cmdline,
+        pid_t *pid)
 {
 #define PIDS_GETINT(e) PIDS_VAL(EU_ ## e, s_int, reap->stacks[i], info)
 #define PIDS_GETUNT(e) PIDS_VAL(EU_ ## e, u_int, reap->stacks[i], info)
@@ -372,6 +373,7 @@ static int find_best_proc(
     struct pids_info *info=NULL;
     struct pids_fetch *reap;
     enum pids_item items[] = {
+        PIDS_ID_PID,
         PIDS_ID_TGID,
         PIDS_TICS_BEGAN,
         PIDS_ID_EUID,
@@ -382,7 +384,7 @@ static int find_best_proc(
         PIDS_TICS_ALL,
         PIDS_CMDLINE};
     enum rel_items {
-        EU_TGID, EU_START, EU_EUID, EU_RUID, EU_TPGID, EU_PGRP, EU_TTY,
+        EU_PID, EU_TGID, EU_START, EU_EUID, EU_RUID, EU_TPGID, EU_PGRP, EU_TTY,
         EU_TICS_ALL, EU_CMDLINE};
 
     *jcpu = 0;
@@ -400,7 +402,7 @@ static int find_best_proc(
 
     line = get_tty_device(tty);
 
-    if (procps_pids_new(&info, items, 9) < 0)
+    if (procps_pids_new(&info, items, 10) < 0)
         xerrx(EXIT_FAILURE,
               _("Unable to create pid info structure"));
     if ((reap = procps_pids_reap(info, PIDS_FETCH_TASKS_ONLY)) == NULL)
@@ -415,6 +417,7 @@ static int find_best_proc(
             if (!best_time) {
                 best_time = PIDS_GETULL(START);
                 strncpy(cmdline, PIDS_GETSTR(CMDLINE), MAX_CMD_WIDTH);
+                *pid = PIDS_GETULL(PID);
                 *pcpu = PIDS_GETULL(TICS_ALL);
             }
 
@@ -426,6 +429,7 @@ static int find_best_proc(
             secondbest_time = PIDS_GETULL(START);
             if (cmdline[0] == '-' && cmdline[1] == '\0') {
                 strncpy(cmdline, PIDS_GETSTR(CMDLINE), MAX_CMD_WIDTH);
+                *pid = PIDS_GETULL(PID);
                 *pcpu = PIDS_GETULL(TICS_ALL);
             }
         }
@@ -438,6 +442,7 @@ static int find_best_proc(
             continue;
         best_time = PIDS_GETULL(START);
         strncpy(cmdline, PIDS_GETSTR(CMDLINE), MAX_CMD_WIDTH);
+        *pid = PIDS_GETULL(PID);
         *pcpu = PIDS_GETULL(TICS_ALL);
     }
     procps_pids_unref(&info);
@@ -450,13 +455,16 @@ static int find_best_proc(
 
 static void showinfo(
             utmp_t * u, int formtype, int maxcmd, int from,
-            const int userlen, const int fromlen, const int ip_addresses)
+            const int userlen, const int fromlen, const int ip_addresses,
+            const int pids)
 {
     unsigned long long jcpu, pcpu;
     unsigned i;
     char uname[UT_NAMESIZE + 1] = "", tty[5 + UT_LINESIZE + 1] = "/dev/";
     long hertz;
     char cmdline[MAX_CMD_WIDTH + 1];
+    pid_t best_pid;
+    int pids_length = 0;
 
     strcpy(cmdline, "-");
 
@@ -468,7 +476,7 @@ static void showinfo(
         else
             tty[i + 5] = '\0';
 
-    if (find_best_proc(u, tty + 5, &jcpu, &pcpu, cmdline) == 0)
+    if (find_best_proc(u, tty + 5, &jcpu, &pcpu, cmdline, &best_pid) == 0)
     /*
      * just skip if stale utmp entry (i.e. login proc doesn't
      * exist). If there is a desire a cmdline flag could be
@@ -513,6 +521,14 @@ static void showinfo(
         else
             print_time_ival7(idletime(tty), 0, stdout);
     }
+    if (pids) {
+        pids_length = printf(" %d/%d", u->ut_pid, best_pid);
+        if (pids_length > maxcmd) {
+            maxcmd = 0;
+        } else if (pids_length > 0) {
+            maxcmd -= pids_length;
+        }
+    }
     printf(" %.*s\n", maxcmd, cmdline);
 }
 
@@ -529,6 +545,7 @@ static void __attribute__ ((__noreturn__))
        fputs(_(" -f, --from          show remote hostname field\n"),out);
        fputs(_(" -o, --old-style     old style output\n"),out);
        fputs(_(" -i, --ip-addr       display IP address instead of hostname (if possible)\n"), out);
+       fputs(_(" -p, --pids          show the PID(s) of processes in WHAT\n"), out);
        fputs(USAGE_SEPARATOR, out);
        fputs(_("     --help     display this help and exit\n"), out);
        fputs(USAGE_VERSION, out);
@@ -553,6 +570,7 @@ int main(int argc, char **argv)
        int longform = 1;
        int from = 1;
        int ip_addresses = 0;
+       int pids = 0;
 
        enum {
                HELP_OPTION = CHAR_MAX + 1
@@ -565,6 +583,7 @@ int main(int argc, char **argv)
                {"from", no_argument, NULL, 'f'},
                {"old-style", no_argument, NULL, 'o'},
                {"ip-addr", no_argument, NULL, 'i'},
+               {"pids", no_argument, NULL, 'p'},
                {"help", no_argument, NULL, HELP_OPTION},
                {"version", no_argument, NULL, 'V'},
                {NULL, 0, NULL, 0}
@@ -583,7 +602,7 @@ int main(int argc, char **argv)
 #endif
 
        while ((ch =
-               getopt_long(argc, argv, "husfoVi", longopts, NULL)) != -1)
+               getopt_long(argc, argv, "husfoVip", longopts, NULL)) != -1)
                switch (ch) {
                case 'h':
                        header = 0;
@@ -607,6 +626,9 @@ int main(int argc, char **argv)
                        ip_addresses = 1;
                        from = 1;
                        break;
+               case 'p':
+                       pids = 1;
+                       break;
                case HELP_OPTION:
                        usage(stdout);
                default:
@@ -686,7 +708,7 @@ int main(int argc, char **argv)
                                continue;
                        if (!strncmp(u->ut_user, user, UT_NAMESIZE))
                                showinfo(u, longform, maxcmd, from, userlen,
-                                        fromlen, ip_addresses);
+                                        fromlen, ip_addresses, pids);
                }
        } else {
                for (;;) {
@@ -701,7 +723,7 @@ int main(int argc, char **argv)
                                continue;
                        if (*u->ut_user)
                                showinfo(u, longform, maxcmd, from, userlen,
-                                        fromlen, ip_addresses);
+                                        fromlen, ip_addresses, pids);
                }
        }
 #ifdef HAVE_UTMPX_H
index 5f1064d78f004d9d806c2f94f8685b6110e10e44..f0da8034a9392aca26361d473a162401835efbd7 100644 (file)
@@ -17,10 +17,12 @@ set w_login "\(\\d+\[A-Z\]\[a-z\]{2}\\d+\|\[A-Z\]\[a-z\]{2}\\d+\|\\d+:\\d+\)"
 set w_idle  "\(\\?xdm\\?\|\\?\|\\d+days\|\\d+:\\d+m?\|\\d+.\\d+s\)"
 set w_ival7  "\(\\?\|\\d+days\|\\d+:\\d+m?\|\\d+.\\d+s\)"
 set w_what  "\[A-Za-z0-9_\/\\-\]+"
+set w_pids  "\\d+/\\d+"
 set w_std_userlines "\(${w_user}\\s+${w_tty}\\s+${w_login}\\s+${w_idle}\\s+${w_ival7}\\s+${w_ival7}\\s+${w_what}\\s*\)*"
 set w_short_userlines "\(${w_user}\\s+${w_tty}\\s+${w_idle}\\s+${w_what}\\s*\)*"
 set w_from_userlines "\(${w_user}\\s+${w_tty}\\s+${w_from}\\s+${w_login}\\s+${w_idle}\\s+${w_ival7}\\s+${w_ival7}\\s+${w_what}\\s*\)*"
 set w_fromshort_userlines "\(${w_user}\\s+${w_tty}\\s+${w_from}\\s+${w_idle}\\s+${w_what}\\s*\)*"
+set w_pid_userlines "\(${w_user}\\s+${w_tty}\\s+${w_idle}\\s+%{w_pids}\s+${w_what}\\s*\)*"
 
 set test "w with no arguments"
 spawn $w
@@ -51,3 +53,7 @@ set test "w with short and from flags"
 spawn $w -sf
 expect_pass "$test" "^${w_fromshort_header}${w_fromshort_userlines}"
 
+set test "w with pids display"
+spawn $w -p
+expect_pass "$test" "^${w_std_header}${w_pid_userlines}"
+