Hello community,

here is the log from the commit of package forkstat for openSUSE:Factory 
checked in at 2017-06-27 10:21:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/forkstat (Old)
 and      /work/SRC/openSUSE:Factory/.forkstat.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "forkstat"

Tue Jun 27 10:21:47 2017 rev:4 rq:506335 version:0.02.00

Changes:
--------
--- /work/SRC/openSUSE:Factory/forkstat/forkstat.changes        2017-06-26 
15:53:32.992775741 +0200
+++ /work/SRC/openSUSE:Factory/.forkstat.new/forkstat.changes   2017-06-27 
10:21:54.329825789 +0200
@@ -1,0 +2,24 @@
+Sun Jun 25 19:12:00 UTC 2017 - [email protected]
+
+- update to version 0.02.00
+  * Makefile: update version and change codename
+  * Minor tweaks to the manual, cosmetic changes
+  * Move arrays to end of stacks to help avoid any stack smashing
+  * Minor source clean-up
+  * Avoid TOCTOU race on stat + open
+  * Use alternative ptrace pid info
+  * Add -x extra UID and TTY information option
+  * Add uid/sid event tracing
+  * Display name of events on -e option when invalid event used
+  * Add ptrace event spying
+  * Fix realtime flag opts mask
+  * Fix -r help option
+  * Add extra spacing in heading as it is offset by one after PID
+  * Remove old set_priority code now that -r replaces it
+  * Manpage: fix pdf warning:
+  * Makefile: add pdf man page rule and add .PHONEYs
+  * Add Philipp Gesang to the man page for kudos for contributions.
+  * Add -r real time scheduling option
+  * Put help options into one large printf statement
+
+-------------------------------------------------------------------

Old:
----
  forkstat-0.01.19.tar.gz

New:
----
  forkstat-0.02.00.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ forkstat.spec ++++++
--- /var/tmp/diff_new_pack.Sc9sQb/_old  2017-06-27 10:21:54.889746653 +0200
+++ /var/tmp/diff_new_pack.Sc9sQb/_new  2017-06-27 10:21:54.889746653 +0200
@@ -18,7 +18,7 @@
 
 
 Name:           forkstat
-Version:        0.01.19
+Version:        0.02.00
 Release:        0
 Summary:        Process fork/exec/exit monitoring tool
 License:        GPL-2.0+

++++++ forkstat-0.01.19.tar.gz -> forkstat-0.02.00.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/forkstat-0.01.19/Makefile 
new/forkstat-0.02.00/Makefile
--- old/forkstat-0.01.19/Makefile       2017-06-21 18:59:39.000000000 +0200
+++ new/forkstat-0.02.00/Makefile       2017-06-24 21:43:28.000000000 +0200
@@ -16,9 +16,9 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 
USA.
 #
 
-VERSION=0.01.19
+VERSION=0.02.00
 #
-# Version "Frantic Forking Finder"
+# Version "Perspicacious Process Peeker"
 #
 
 CFLAGS += -Wall -Wextra -DVERSION='"$(VERSION)"' -O2
@@ -43,6 +43,7 @@
 forkstat.8.gz: forkstat.8
        gzip -c $< > $@
 
+.PHONEY: dist
 dist:
        rm -rf forkstat-$(VERSION)
        mkdir forkstat-$(VERSION)
@@ -51,10 +52,17 @@
        tar -zcf forkstat-$(VERSION).tar.gz forkstat-$(VERSION)
        rm -rf forkstat-$(VERSION)
 
+.PHONEY: pdf
+pdf:
+       man -t ./forkstat.8 | ps2pdf - > forkstat.pdf
+
+.PHONEY: clean
 clean:
        rm -f forkstat forkstat.o forkstat.8.gz
        rm -f forkstat-$(VERSION).tar.gz
+       rm -f forkstat.pdf
 
+.PHONEY: install
 install: forkstat forkstat.8.gz
        mkdir -p ${DESTDIR}${BINDIR}
        cp forkstat ${DESTDIR}${BINDIR}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/forkstat-0.01.19/forkstat.8 
new/forkstat-0.02.00/forkstat.8
--- old/forkstat-0.01.19/forkstat.8     2017-06-21 18:59:39.000000000 +0200
+++ new/forkstat-0.02.00/forkstat.8     2017-06-24 21:43:28.000000000 +0200
@@ -2,7 +2,7 @@
 .\" First parameter, NAME, should be all caps
 .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
 .\" other parameters are allowed: see man(7), man(1)
-.TH FORKSTAT 8 "21 June, 2017"
+.TH FORKSTAT 8 "24 June, 2017"
 .\" Please adjust this date whenever revising the manpage.
 .\"
 .\" Some roff macros, for reference:
@@ -26,9 +26,11 @@
 .RI [ \-e ]
 .RI [ \-h ]
 .RI [ \-l ]
+.RI [ \-r ]
 .RI [ \-s ]
 .RI [ \-S ]
 .RI [ \-q ]
+.RI [ \-x ]
 .br
 
 .SH DESCRIPTION
@@ -43,12 +45,12 @@
 
 Forkstat will display several columns of process related information:
 .TS
-l lw(5i).
+l l.
 \fBTitle       Description\fR
 Time   When the fork/exec/exit event occurred.
 Event  Type of event.
 PID    Process or thread ID.
-Info   Parent or child if a fork, or exit value.
+Info   Parent or child if a fork, or process exit(2) value.
 Duration       T{
 On exit, the duration the command ran for in seconds.
 Process        The process name. The name will be in [ ] brackets if it is a 
kernel thread.
@@ -67,7 +69,7 @@
 specify events to trace as a comma seperated list. By default the fork, exec 
and exit 
 events are traced. Available events are:
 .TS
-l lw(5i).
+l lw(4i).
 \fBEvent       Description\fR
 fork   forks
 exec   execs
@@ -75,12 +77,22 @@
 core   core dumps
 comm   process name changes in comm field
 clone  clone (normally on thread creation)
+ptrce  ptrace attach or detach
+uid    uid/gid events
+sid    sid events
 all    all the events above
 .TE
 .TP
 .B \-h
 show brief help summary.
 .TP
+.B \-l
+set stdout to line-buffered mode.
+.TP
+.B \-r
+run with real time FIFO scheduling with maximum priority to keep up with high 
volumes
+of process events.
+.TP
 .B \-s
 show short process name information.
 .TP
@@ -90,8 +102,8 @@
 .B \-q
 run quietly and enable the \-S option.
 .TP
-.B \-l
-set stdout to line-buffered mode.
+.B \-x
+show extra process related information: user ID and TTY of the process.
 .SH EXAMPLES
 .LP
 Show process activity with short process names and directory base path 
stripped off:
@@ -121,7 +133,8 @@
 .SH SEE ALSO
 .BR vmstat (8)
 .SH AUTHOR
-forkstat was written by Colin King <[email protected]>
+forkstat was written by Colin King <[email protected]>. Thanks also
+for contributions from Philipp Gesang.
 .PP
 This manual page was written by Colin King <[email protected]>,
 for the Ubuntu project (but may be used by others).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/forkstat-0.01.19/forkstat.c 
new/forkstat-0.02.00/forkstat.c
--- old/forkstat-0.01.19/forkstat.c     2017-06-21 18:59:39.000000000 +0200
+++ new/forkstat-0.02.00/forkstat.c     2017-06-24 21:43:28.000000000 +0200
@@ -39,6 +39,7 @@
 #include <time.h>
 #include <getopt.h>
 #include <sched.h>
+#include <pwd.h>
 
 #include <sys/ioctl.h>
 #include <sys/time.h>
@@ -52,24 +53,32 @@
 #include <linux/cn_proc.h>
 
 #define APP_NAME               "forkstat"
-#define MAX_PIDS               (32769) /* Hash Max PIDs */
+#define MAX_PIDS               (32769)         /* Hash Max PIDs */
 
-#define NULL_PID               (-1)
-
-#define OPT_CMD_LONG           (0x00000001)
-#define OPT_CMD_SHORT          (0x00000002)
-#define OPT_CMD_DIRNAME_STRIP  (0x00000004)
-#define OPT_STATS              (0x00000008)
-#define OPT_QUIET              (0x00000010)
-
-#define OPT_EV_FORK            (0x00000100)
-#define OPT_EV_EXEC            (0x00000200)
-#define OPT_EV_EXIT            (0x00000400)
-#define OPT_EV_CORE            (0x00000800)
-#define OPT_EV_COMM            (0x00001000)
-#define OPT_EV_CLNE            (0x00002000)
-#define OPT_EV_MASK            (0x00003f00)
-#define OPT_EV_ALL             (OPT_EV_MASK)
+#define NULL_PID               (pid_t)(-1)
+#define NULL_UID               (uid_t)(-1)
+#define NULL_GID               (gid_t)(-1)
+#define NULL_TTY               (dev_t)(-1)
+
+#define OPT_CMD_LONG           (0x00000001)    /* Long command line info */
+#define OPT_CMD_SHORT          (0x00000002)    /* Short command line info */
+#define OPT_CMD_DIRNAME_STRIP  (0x00000004)    /* Strip dirpath from command */
+#define OPT_STATS              (0x00000008)    /* Show stats at end of run */
+#define OPT_QUIET              (0x00000010)    /* Run quietly */
+#define OPT_REALTIME           (0x00000020)    /* Run with Real Time 
scheduling */
+#define OPT_EXTRA              (0x00000040)    /* Show extra stats */
+
+#define OPT_EV_FORK            (0x00000100)    /* Fork event */
+#define OPT_EV_EXEC            (0x00000200)    /* Exec event */
+#define OPT_EV_EXIT            (0x00000400)    /* Exit event */
+#define OPT_EV_CORE            (0x00000800)    /* Coredump event */
+#define OPT_EV_COMM            (0x00001000)    /* Comm proc info event */
+#define OPT_EV_CLNE            (0x00002000)    /* Clone event */
+#define OPT_EV_PTRC            (0x00004000)    /* Ptrace event */
+#define OPT_EV_UID             (0x00008000)    /* UID event */
+#define OPT_EV_SID             (0x00010000)    /* SID event */
+#define OPT_EV_MASK            (0x0001ff00)    /* Event mask */
+#define OPT_EV_ALL             (OPT_EV_MASK)   /* All events */
 
 #define        GOT_TGID                (0x01)
 #define GOT_PPID               (0x02)
@@ -79,11 +88,13 @@
 #define LINUX_VERSION_CODE KERNEL_VERSION(2,0,0)
 #endif
 
-
 /* /proc info cache */
 typedef struct proc_info {
        struct proc_info *next; /* next proc info in hashed linked list */
        pid_t   pid;            /* Process ID */
+       uid_t   uid;            /* User ID */
+       gid_t   gid;            /* GUID */
+       dev_t   tty;            /* TTY dev */
        char    *cmdline;       /* /proc/pid/cmdline text */
        bool    kernel_thread;  /* true if a kernel thread */
        struct timeval start;   /* time when process started */
@@ -96,13 +107,16 @@
 } kernel_task_info;
 
 typedef enum {
-       STAT_FORK = 0,
-       STAT_EXEC,
-       STAT_EXIT,
-       STAT_CORE,
-       STAT_COMM,
-       STAT_CLNE,
-       STAT_LAST
+       STAT_FORK = 0,          /* Fork */
+       STAT_EXEC,              /* Exec */
+       STAT_EXIT,              /* Exit */
+       STAT_CORE,              /* Core dump */
+       STAT_COMM,              /* Proc comm field change */
+       STAT_CLNE,              /* Clone */
+       STAT_PTRC,              /* Ptrace */
+       STAT_UID,               /* UID change */
+       STAT_SID,               /* SID change */
+       STAT_LAST               /* Always last sentinal */
 } event_t;
 
 typedef struct proc_stats {
@@ -127,6 +141,9 @@
        { "core", "Coredump",   OPT_EV_CORE,    STAT_CORE },
        { "comm", "Comm",       OPT_EV_COMM,    STAT_COMM },
        { "clone","Clone",      OPT_EV_CLNE,    STAT_CLNE },
+       { "ptrce","Ptrace",     OPT_EV_PTRC,    STAT_PTRC },
+       { "uid",  "Uid",        OPT_EV_UID,     STAT_UID  },
+       { "sid",  "Sid",        OPT_EV_SID,     STAT_SID  },
        { "all",  "",           OPT_EV_ALL,     0 },
        { NULL,   NULL,         0,              0 }
 };
@@ -144,6 +161,7 @@
 /* Default void no process info struct */
 static proc_info_t no_info = {
        .pid = NULL_PID,
+       .uid = NULL_UID,
        .cmdline = "<unknown>",
        .kernel_thread = false,
        .start = { 0, 0 },
@@ -206,6 +224,102 @@
 static proc_info_t *proc_info_get(pid_t pid);
 
 /*
+ *  get_username()
+ *     get username from a given user id
+ */
+static char *get_username(const uid_t uid)
+{
+       struct passwd *pwd;
+       static char buf[12];
+
+       pwd = getpwuid(uid);
+       if (pwd)
+               return pwd->pw_name;
+
+       snprintf(buf, sizeof(buf), "%d", uid);
+       return buf;
+}
+
+/*
+ *  get_tty()
+ *     get a TTY name with device ID dev
+ */
+static char *get_tty(const dev_t dev)
+{
+       DIR *dir;
+       struct dirent *dirent;
+       static char tty[16];
+
+       strncpy(tty, "?", sizeof(tty));
+
+       dir = opendir("/dev/pts");
+       if (!dir)
+               goto err;
+
+       while ((dirent = readdir(dir))) {
+               struct stat buf;
+               char path[PATH_MAX];
+
+               if (dirent->d_name[0] == '.')
+                       continue;
+
+               snprintf(path, sizeof(path), "/dev/pts/%s", dirent->d_name);
+               if (stat(path, &buf) < 0)
+                       continue;
+
+               if (buf.st_rdev == dev) {
+                       snprintf(tty, sizeof(tty), "pts/%s", dirent->d_name);
+                       break;
+               }
+       }
+
+       (void)closedir(dir);
+err:
+       return tty;
+}
+
+/*
+ *  get_extra()
+ *     quick and dirty way to get UID and GID from a PID,
+ *     note that this does not cater of changes
+ *     because of use of an effective ID.
+ */
+static void get_extra(const pid_t pid, proc_info_t *info)
+{
+       ssize_t ret;
+       long dev;
+       int fd;
+       char path[PATH_MAX];
+       char buffer[4096];
+       struct stat buf;
+
+       info->uid = NULL_UID;
+       info->gid = NULL_GID;
+       info->tty = NULL_TTY;
+
+       if (!(opt_flags & OPT_EXTRA))
+               return;
+
+       snprintf(path, sizeof(path), "/proc/%u/stat", pid);
+       fd = open(path, O_RDONLY);
+       if (fd < 0)
+               return;
+
+       if (fstat(fd, &buf) == 0) {
+               info->uid = buf.st_uid;
+               info->gid = buf.st_gid;
+       }
+
+       ret = read(fd, buffer, sizeof(buffer));
+       (void)close(fd);
+       if (ret < 0)
+               return;
+
+       if (sscanf(buffer, "%*d %*s %*s %*d %*d %*d %ld", &dev) == 1)
+               info->tty = (dev_t)dev;
+}
+
+/*
  *  pid_max_digits()
  *     determine (or guess) maximum digits of pids
  */
@@ -249,14 +363,15 @@
 static pid_t get_parent_pid(const pid_t pid, bool *is_thread)
 {
        FILE *fp;
-       char path[PATH_MAX];
-       char buffer[4096];
        pid_t tgid = 0, ppid = 0;
        unsigned int got = 0;
+       char path[PATH_MAX];
+       char buffer[4096];
 
        *is_thread = false;
        snprintf(path, sizeof(path), "/proc/%u/status", pid);
-       if ((fp = fopen(path, "r")) == NULL)
+       fp = fopen(path, "r");
+       if (!fp)
                return 0;
 
        while (((got & GOT_ALL) != GOT_ALL) &&
@@ -300,10 +415,10 @@
  */
 static bool sane_proc_pid_info(void)
 {
-       FILE *fp;
        static const char pattern[] = "container=";
-       const char *ptr = pattern;
+       FILE *fp;
        bool ret = true;
+       const char *ptr = pattern;
 
        fp = fopen("/proc/1/environ", "r");
        if (!fp)
@@ -344,7 +459,7 @@
        } else {
                /* In side a container, make a guess at kernel threads */
                int i;
-               pid_t pgid = getpgid(id);
+               const pid_t pgid = getpgid(id);
 
                /* This fails for kernel threads inside a container */
                if (pgid >= 0)
@@ -397,7 +512,7 @@
 static int tty_height(void)
 {
 #ifdef TIOCGWINSZ
-       int fd = 0;
+       const int fd = 0;
        struct winsize ws;
 
        /* if tty and we can get a sane width, return it */
@@ -423,8 +538,9 @@
 
        pid_size = pid_max_digits();
 
-       printf("Time     Event %*.*s Info  Duration Process\n",
-               pid_size, pid_size, "PID");
+       printf("Time     Event %*.*s %sInfo   Duration Process\n",
+               pid_size, pid_size, "PID",
+               (opt_flags & OPT_EXTRA) ? "   UID TTY    " : "");
 }
 
 /*
@@ -433,7 +549,7 @@
  */
 static void row_increment(void)
 {
-       int tty_rows = tty_height();
+       const int tty_rows = tty_height();
 
        row++;
        if ((tty_rows > 2) && (row >= tty_rows)) {
@@ -504,11 +620,11 @@
                stats = stats->next;
        }
        stats = calloc(1, sizeof(*stats));
-       if (stats == NULL)
+       if (!stats)
                return;         /* silently ignore */
 
        stats->name = strdup(name);
-       if (stats->name == NULL) {
+       if (!stats->name) {
                free(stats);
                return;
        }
@@ -560,7 +676,7 @@
        printf("   Total Process\n");
 
        sorted = calloc(n, sizeof(proc_stats_t *));
-       if (sorted == NULL) {
+       if (!sorted) {
                fprintf(stderr, "Cannot sort statistics, out of memory.\n");
                return;
        }
@@ -609,9 +725,9 @@
  */
 static char *proc_comm(const pid_t pid)
 {
-       char buffer[4096];
        int fd;
        ssize_t ret;
+       char buffer[4096];
 
        snprintf(buffer, sizeof(buffer), "/proc/%d/comm", pid);
        if ((fd = open(buffer, O_RDONLY)) < 0) {
@@ -632,17 +748,17 @@
  */
 static char *proc_cmdline(const pid_t pid)
 {
-       char buffer[4096];
        char *ptr;
        int fd;
        ssize_t ret;
+       char buffer[4096];
 
        snprintf(buffer, sizeof(buffer), "/proc/%d/cmdline", pid);
        if ((fd = open(buffer, O_RDONLY)) < 0) {
                return proc_comm(pid);
        }
 
-       memset(buffer, 0, sizeof(buffer));
+       (void)memset(buffer, 0, sizeof(buffer));
        if ((ret = read(fd, buffer, sizeof(buffer) - 1)) <= 0) {
                (void)close(fd);
                return proc_comm(pid);
@@ -686,11 +802,11 @@
  */
 static proc_info_t *proc_info_get(const pid_t pid)
 {
-       size_t i = proc_info_hash(pid);
+       const size_t i = proc_info_hash(pid);
        proc_info_t *info = proc_info[i];
 
        while (info) {
-               if (proc_info[i]->pid == pid)
+               if (info->pid == pid)
                        return info;
                info = info->next;
        }
@@ -703,12 +819,14 @@
  */
 static void proc_info_free(const pid_t pid)
 {
-       size_t i = proc_info_hash(pid);
+       const size_t i = proc_info_hash(pid);
        proc_info_t *info = proc_info[i];
 
        while (info) {
                if (info->pid == pid) {
                        info->pid = NULL_PID;
+                       info->uid = NULL_UID;
+                       info->gid = NULL_GID;
                        free(info->cmdline);
                        info->cmdline = NULL;
                        return;
@@ -748,7 +866,8 @@
 
        if (info == &no_info)
                return &no_info;
-       if ((newcmd = proc_cmdline(pid)) == NULL)
+       newcmd = proc_cmdline(pid);
+       if (!newcmd)
                return &no_info;
 
        free(info->cmdline);
@@ -763,7 +882,7 @@
  */
 static proc_info_t *proc_info_add(const pid_t pid, struct timeval *tv)
 {
-       size_t i = proc_info_hash(pid);
+       const size_t i = proc_info_hash(pid);
        proc_info_t *info;
        char *cmdline;
 
@@ -779,8 +898,9 @@
                info = info->next;
        }
 
-       if (info == NULL) {
-               if ((info = calloc(1, sizeof(proc_info_t))) == NULL) {
+       if (!info) {
+               info = calloc(1, sizeof(proc_info_t));
+               if (!info) {
                        fprintf(stderr, "Cannot allocate all proc info\n");
                        free(cmdline);
                        return NULL;
@@ -790,6 +910,7 @@
        }
        info->cmdline = cmdline;
        info->pid = pid;
+       get_extra(pid, info);
        info->kernel_thread = pid_a_kernel_thread(cmdline, pid);
 
        if (tv)
@@ -814,7 +935,8 @@
 
        snprintf(path, sizeof(path), "/proc/%i/task", pid);
 
-       if ((dir = opendir(path)) == NULL)
+       dir = opendir(path);
+       if (!dir)
                return;
 
        while ((dirent = readdir(dir))) {
@@ -840,7 +962,8 @@
        DIR *dir;
        struct dirent *dirent;
 
-       if ((dir = opendir("/proc")) == NULL)
+       dir = opendir("/proc");
+       if (!dir)
                return -1;
 
        while ((dirent = readdir(dir))) {
@@ -860,6 +983,24 @@
        return 0;
 }
 
+static char *extra_info(const uid_t uid)
+{
+       static char buf[20];
+
+       *buf = '\0';
+       if (opt_flags & OPT_EXTRA) {
+               const proc_info_t *info = proc_info_get(uid);
+
+               if (info && info->uid != NULL_UID)
+                       snprintf(buf, sizeof(buf), "%6d %-6.6s ", info->uid, 
get_tty(info->tty));
+               else
+                       snprintf(buf, sizeof(buf), "%14s", "");
+       }
+
+       return buf;
+}
+
+
 /*
  *  handle_sig()
  *     catch signal and flag a stop
@@ -887,7 +1028,7 @@
                return -1;
        }
 
-       memset(&addr, 0, sizeof(addr));
+       (void)memset(&addr, 0, sizeof(addr));
        addr.nl_pid = getpid();
        addr.nl_family = AF_NETLINK;
        addr.nl_groups = CN_IDX_PROC;
@@ -908,19 +1049,19 @@
  */
 static int netlink_listen(const int sock)
 {
-       struct iovec iov[3];
+       enum proc_cn_mcast_op op;
        struct nlmsghdr nlmsghdr;
        struct cn_msg cn_msg;
-       enum proc_cn_mcast_op op;
+       struct iovec iov[3];
 
-       memset(&nlmsghdr, 0, sizeof(nlmsghdr));
+       (void)memset(&nlmsghdr, 0, sizeof(nlmsghdr));
        nlmsghdr.nlmsg_len = NLMSG_LENGTH(sizeof(cn_msg) + sizeof(op));
        nlmsghdr.nlmsg_pid = getpid();
        nlmsghdr.nlmsg_type = NLMSG_DONE;
        iov[0].iov_base = &nlmsghdr;
        iov[0].iov_len = sizeof(nlmsghdr);
 
-       memset(&cn_msg, 0, sizeof(cn_msg));
+       (void)memset(&cn_msg, 0, sizeof(cn_msg));
        cn_msg.id.idx = CN_IDX_PROC;
        cn_msg.id.val = CN_VAL_PROC;
        cn_msg.len = sizeof(enum proc_cn_mcast_op);
@@ -935,34 +1076,6 @@
 }
 
 /*
- *   set_prioity
- *     set high priority to try and get netlink activty
- *     before short lived processes die
- */
-static void set_priority(void)
-{
-       int max;
-       struct sched_param param;
-       int sched;
-
-#if defined(SCHED_DEADLINE)
-       sched = SCHED_DEADLINE;
-#elif defined(SCHED_SCHED_FIFO)
-       sched = SCHED_FIFO;
-#elif defined(SCHED_RR)
-       sched = SCHED_FIFO;
-#else
-       sched = SCHED_OTHER;    /* Oh well */
-#endif
-       if ((max = sched_get_priority_max(sched)) < 0)
-               return;
-
-       memset(&param, 0, sizeof(param));
-       param.sched_priority = max;
-       (void)sched_setscheduler(getpid(), sched, &param);
-}
-
-/*
  *   monitor()
  *     monitor system activity
  */
@@ -972,7 +1085,6 @@
        const int pid_size = pid_max_digits();
 
        print_heading();
-       set_priority();
 
        while (!stop_recv) {
                ssize_t len;
@@ -982,7 +1094,8 @@
                        return 0;
                }
                if (len == -1) {
-                       int err = errno;
+                       const int err = errno;
+
                        switch (err) {
                        case EINTR:
                                return 0;
@@ -1020,7 +1133,7 @@
                        struct tm tm;
                        char when[10];
                        time_t now;
-                       pid_t ppid;
+                       pid_t pid, ppid;
                        bool is_thread;
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
@@ -1059,32 +1172,35 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
                        case PROC_EVENT_FORK:
                                ppid = 
get_parent_pid(proc_ev->event_data.fork.child_pid, &is_thread);
+                               pid = proc_ev->event_data.fork.child_pid;
                                
proc_stats_account(proc_ev->event_data.fork.parent_pid,
                                        is_thread ? STAT_CLNE : STAT_FORK);
                                if (gettimeofday(&tv, NULL) < 0) {
-                                       memset(&tv, 0, sizeof tv);
+                                       (void)memset(&tv, 0, sizeof tv);
                                }
                                info1 = proc_info_get(ppid);
-                               info2 = 
proc_info_add(proc_ev->event_data.fork.child_pid, &tv);
+                               info2 = proc_info_add(pid, &tv);
                                if (!(opt_flags & OPT_QUIET) &&
                                        (((opt_flags & OPT_EV_FORK) && 
!is_thread) ||
                                         ((opt_flags & OPT_EV_CLNE) && 
is_thread))) {
                                        if (info1 != NULL && info2 != NULL) {
                                                char *type = is_thread ? 
"clone" : "fork";
                                                row_increment();
-                                               printf("%s %-5.5s %*d parent 
%8s %s%s%s\n",
+                                               printf("%s %-5.5s %*d %sparent 
%8s %s%s%s\n",
                                                        when,
                                                        type,
                                                        pid_size, ppid,
+                                                       extra_info(ppid),
                                                        "",
                                                        info1->kernel_thread ? 
"[" : "",
                                                        info1->cmdline,
                                                        info1->kernel_thread ? 
"]" : "");
                                                row_increment();
-                                               printf("%s %-5.5s %*d %-6.6s 
%8s %s%s%s\n",
+                                               printf("%s %-5.5s %*d %s%6.6s 
%8s %s%s%s\n",
                                                        when,
                                                        type,
-                                                       pid_size, 
proc_ev->event_data.fork.child_pid,
+                                                       pid_size, pid,
+                                                       extra_info(pid),
                                                        is_thread ? "thread" : 
"child",
                                                        "",
                                                        info1->kernel_thread ? 
"[" : "",
@@ -1095,12 +1211,14 @@
                                break;
                        case PROC_EVENT_EXEC:
                                
proc_stats_account(proc_ev->event_data.exec.process_pid, STAT_EXEC);
-                               info1 = 
proc_info_update(proc_ev->event_data.exec.process_pid);
+                               pid = proc_ev->event_data.exec.process_pid;
+                               info1 = proc_info_update(pid);
                                if (!(opt_flags & OPT_QUIET) && (opt_flags & 
OPT_EV_EXEC)) {
                                        row_increment();
-                                       printf("%s exec  %*d        %8s 
%s%s%s\n",
+                                       printf("%s exec  %*d %s       %8s 
%s%s%s\n",
                                                when,
-                                               pid_size, 
proc_ev->event_data.exec.process_pid,
+                                               pid_size, pid,
+                                               extra_info(pid),
                                                "",
                                                info1->kernel_thread ? "[" : "",
                                                info1->cmdline,
@@ -1110,12 +1228,13 @@
                        case PROC_EVENT_EXIT:
                                
proc_stats_account(proc_ev->event_data.exit.process_pid, STAT_EXIT);
                                if (!(opt_flags & OPT_QUIET) && (opt_flags & 
OPT_EV_EXIT)) {
-                                       info1 = 
proc_info_get(proc_ev->event_data.exit.process_pid);
+                                       pid = 
proc_ev->event_data.exit.process_pid;
+                                       info1 = proc_info_get(pid);
                                        if (info1->start.tv_sec) {
                                                double d1, d2;
 
                                                if (gettimeofday(&tv, NULL) < 
0) {
-                                                       memset(&tv, 0, sizeof 
tv);
+                                                       (void)memset(&tv, 0, 
sizeof tv);
                                                }
                                                d1 = 
timeval_to_double(&info1->start);
                                                d2 = timeval_to_double(&tv);
@@ -1124,9 +1243,10 @@
                                                snprintf(duration, 
sizeof(duration), "unknown");
                                        }
                                        row_increment();
-                                       printf("%s exit  %*d  %5d %8s %s%s%s\n",
+                                       printf("%s exit  %*d %s%6d %8s 
%s%s%s\n",
                                                when,
-                                               pid_size, 
proc_ev->event_data.exit.process_pid,
+                                               pid_size, pid,
+                                               extra_info(pid),
                                                
proc_ev->event_data.exit.exit_code,
                                                duration,
                                                info1->kernel_thread ? "[" : "",
@@ -1135,16 +1255,64 @@
                                }
                                
proc_info_free(proc_ev->event_data.exit.process_pid);
                                break;
+                       case PROC_EVENT_UID:
+                               
proc_stats_account(proc_ev->event_data.exec.process_pid, STAT_UID);
+                               info1 = 
proc_info_update(proc_ev->event_data.exec.process_pid);
+                               if (!(opt_flags & OPT_QUIET) && (opt_flags & 
OPT_EV_UID)) {
+                                       row_increment();
+                                       pid = 
proc_ev->event_data.exec.process_pid;
+                                       if (proc_ev->what == PROC_EVENT_UID) {
+                                               printf("%s uid   %*d %s%6s %8s 
%s%s%s\n",
+                                                       when,
+                                                       pid_size, pid,
+                                                       extra_info(pid),
+                                                       
get_username(proc_ev->event_data.id.e.euid),
+                                                       "",
+                                                       info1->kernel_thread ? 
"[" : "",
+                                                       info1->cmdline,
+                                                       info1->kernel_thread ? 
"]" : "");
+                                       } else {
+                                               printf("%s gid   %*d %6s %s%8s 
%s%s%s\n",
+                                                       when,
+                                                       pid_size, pid,
+                                                       extra_info(pid),
+                                                       
get_username(proc_ev->event_data.id.e.euid),
+                                                       "",
+                                                       info1->kernel_thread ? 
"[" : "",
+                                                       info1->cmdline,
+                                                       info1->kernel_thread ? 
"]" : "");
+                                       }
+                               }
+                               break;
+                       case PROC_EVENT_SID:
+                               
proc_stats_account(proc_ev->event_data.exec.process_pid, STAT_SID);
+                               info1 = 
proc_info_update(proc_ev->event_data.exec.process_pid);
+                               if (!(opt_flags & OPT_QUIET) && (opt_flags & 
OPT_EV_UID)) {
+                                       row_increment();
+                                       pid = 
proc_ev->event_data.exec.process_pid;
+                                       printf("%s sid   %*d %s%6d %8s 
%s%s%s\n",
+                                               when,
+                                               pid_size, pid,
+                                               extra_info(pid),
+                                               
proc_ev->event_data.sid.process_pid,
+                                               "",
+                                               info1->kernel_thread ? "[" : "",
+                                               info1->cmdline,
+                                               info1->kernel_thread ? "]" : 
"");
+                               }
+                               break;
 #endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
                        case PROC_EVENT_COREDUMP:
                                
proc_stats_account(proc_ev->event_data.coredump.process_pid, STAT_CORE);
                                if (!(opt_flags & OPT_QUIET) && (opt_flags & 
OPT_EV_CORE)) {
-                                       info1 = 
proc_info_get(proc_ev->event_data.coredump.process_pid);
+                                       pid = 
proc_ev->event_data.coredump.process_pid;
+                                       info1 = proc_info_get(pid);
                                        row_increment();
-                                       printf("%s core  %*d        %8s 
%s%s%s\n",
+                                       printf("%s core  %*d %s       %8s 
%s%s%s\n",
                                                when,
-                                               pid_size, 
proc_ev->event_data.exit.process_pid,
+                                               pid_size, pid,
+                                               extra_info(pid),
                                                "",
                                                info1->kernel_thread ? "[" : "",
                                                info1->cmdline,
@@ -1152,19 +1320,47 @@
                                }
                                break;
 #endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
+                       case PROC_EVENT_PTRACE:
+                               
proc_stats_account(proc_ev->event_data.comm.process_pid, STAT_PTRC);
+                               if (!(opt_flags & OPT_QUIET) && (opt_flags & 
OPT_EV_PTRC)) {
+                                       const bool attach = 
(proc_ev->event_data.ptrace.tracer_pid != 0);
+
+#if 0
+                                       pid = attach ? 
proc_ev->event_data.ptrace.tracer_pid :
+                                                      
proc_ev->event_data.ptrace.process_pid;
+#else
+                                       pid = 
proc_ev->event_data.ptrace.process_pid;
+#endif
+                                       info1 = proc_info_get(pid);
+                                       row_increment();
+                                       printf("%s ptrce %*d %s%6s %8s 
%s%s%s\n",
+                                               when,
+                                               pid_size, pid,
+                                               extra_info(pid),
+                                               attach ? "attach" : "detach",
+                                               "",
+                                               info1->kernel_thread ? "[" : "",
+                                               attach ? info1->cmdline : "",
+                                               info1->kernel_thread ? "]" : 
"");
+                               }
+                               break;
+#endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)
                        case PROC_EVENT_COMM:
                                
proc_stats_account(proc_ev->event_data.comm.process_pid, STAT_COMM);
                                if (!(opt_flags & OPT_QUIET) && (opt_flags & 
OPT_EV_COMM)) {
-                                       info1 = 
proc_info_get(proc_ev->event_data.comm.process_pid);
-                                       comm = 
proc_comm(proc_ev->event_data.comm.process_pid);
-                                       if (comm == NULL)
+                                       pid = 
proc_ev->event_data.comm.process_pid;
+                                       info1 = proc_info_get(pid);
+                                       comm = proc_comm(pid);
+                                       if (!comm)
                                                break;
                                        row_increment();
 
-                                       printf("%s comm  %*d        %8s %s%s%s 
-> %s\n",
+                                       printf("%s comm  %*d %s       %8s 
%s%s%s -> %s\n",
                                                when,
-                                               pid_size, 
proc_ev->event_data.exit.process_pid,
+                                               pid_size, pid,
+                                               extra_info(pid),
                                                "",
                                                info1->kernel_thread ? "[" : "",
                                                info1->cmdline,
@@ -1190,14 +1386,15 @@
 {
        printf("%s, version %s\n\n", APP_NAME, VERSION);
        printf("usage: %s [-d|-D|-e|-h|-l|-s|-S|-q]\n", argv[0]);
-       printf("-d\tstrip off directory path from process name.\n");
-       printf("-D\tspecify run duration in seconds.\n");
-       printf("-e\tselect which events to monitor.\n");
-       printf("-h\tshow this help.\n");
-       printf("-l\tforce stdout line buffering.\n");
-       printf("-s\tshow short process name.\n");
-       printf("-S\tshow event statistics at end of the run.\n");
-       printf("-q\trun quietly and enable -S option.\n");
+       printf("-d\tstrip off directory path from process name.\n"
+              "-D\tspecify run duration in seconds.\n"
+              "-e\tselect which events to monitor.\n"
+              "-h\tshow this help.\n"
+              "-l\tforce stdout line buffering.\n"
+              "-r\trun with real time FIFO scheduler.\n"
+              "-s\tshow short process name.\n"
+              "-S\tshow event statistics at end of the run.\n"
+              "-q\trun quietly and enable -S option.\n");
 }
 
 /*
@@ -1219,7 +1416,10 @@
                        }
                }
                if (!found) {
-                       fprintf(stderr, "Unknown event '%s'.\n", token);
+                       fprintf(stderr, "Unknown event '%s'. Allowed events:", 
token);
+                       for (i = 0; ev_map[i].event; i++)
+                               printf(" %s", ev_map[i].event);
+                       printf("\n");
                        return -1;
                }
        }
@@ -1233,7 +1433,7 @@
        struct sigaction new_action;
 
        for (;;) {
-               int c = getopt(argc, argv, "dD:e:hlsSq");
+               const int c = getopt(argc, argv, "dD:e:hlrsSqx");
                if (c == -1)
                        break;
                switch (c) {
@@ -1254,6 +1454,9 @@
                case 'h':
                        show_help(argv);
                        exit(EXIT_SUCCESS);
+               case 'r':
+                       opt_flags |= OPT_REALTIME;
+                       break;
                case 's':
                        opt_flags &= ~OPT_CMD_LONG;
                        opt_flags |= OPT_CMD_SHORT;
@@ -1270,6 +1473,9 @@
                                exit(EXIT_FAILURE);
                        }
                        break;
+               case 'x':
+                       opt_flags |= OPT_EXTRA;
+                       break;
                default:
                        show_help(argv);
                        exit(EXIT_FAILURE);
@@ -1277,14 +1483,14 @@
        }
 
        if ((opt_flags & OPT_EV_MASK) == 0)
-               opt_flags |= (OPT_EV_FORK | OPT_EV_EXEC | OPT_EV_EXIT | 
OPT_EV_CLNE);
+               opt_flags |= (OPT_EV_FORK | OPT_EV_EXEC | OPT_EV_EXIT | 
OPT_EV_CLNE | OPT_EV_PTRC);
 
        if (geteuid() != 0) {
                fprintf(stderr, "Need to run with root access.\n");
                goto abort_sock;
        }
 
-       memset(&new_action, 0, sizeof(new_action));
+       (void)memset(&new_action, 0, sizeof(new_action));
        for (i = 0; signals[i] != -1; i++) {
                new_action.sa_handler = handle_sig;
                sigemptyset(&new_action.sa_mask);
@@ -1304,6 +1510,27 @@
                goto abort_sock;
        }
 
+       if (opt_flags & OPT_REALTIME) {
+               struct sched_param param;
+               int max_prio;
+               const int policy = SCHED_FIFO;
+
+               max_prio = sched_get_priority_max(policy);
+               if (max_prio < 0) {
+                       fprintf(stderr, "sched_get_priority_max failed: 
errno=%d (%s)\n",
+                               errno, strerror(errno));
+                       goto abort_sock;
+               }
+
+               (void)memset(&param, 0, sizeof(param));
+               param.sched_priority = max_prio;
+               if (sched_setscheduler(getpid(), policy, &param) < 0) {
+                       fprintf(stderr, "sched_setscheduler failed: errno=%d 
(%s)\n",
+                               errno, strerror(errno));
+                       goto abort_sock;
+               }
+       }
+
        sock = netlink_connect();
        if (sock == -EPROTONOSUPPORT) {
                fprintf(stderr, "Cannot show process activity with this kernel, 
netlink required.\n");


Reply via email to