Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-4]: src/bin/ps pull up revs 1.5-1.7 from trunk (requested by jd...



details:   https://anonhg.NetBSD.org/src/rev/a175e32da4d4
branches:  netbsd-1-4
changeset: 469677:a175e32da4d4
user:      cgd <cgd%NetBSD.org@localhost>
date:      Mon Nov 08 06:40:19 1999 +0000

description:
pull up revs 1.5-1.7 from trunk (requested by jdolecek):
  When using the procfs for extracting process information, extract process
  start time, arguments, and session leadership status.  Also, fall back to
  procfs when kvm_openfiles() completely fails (e.g. when /dev/mem is not
  readable).  Fixes PR#7772.

diffstat:

 bin/ps/procfs_ops.c |  398 +++++++++++++++++++++++++++++++++------------------
 1 files changed, 257 insertions(+), 141 deletions(-)

diffs (truncated from 519 to 300 lines):

diff -r 5f99c7985981 -r a175e32da4d4 bin/ps/procfs_ops.c
--- a/bin/ps/procfs_ops.c       Mon Nov 08 06:40:14 1999 +0000
+++ b/bin/ps/procfs_ops.c       Mon Nov 08 06:40:19 1999 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: procfs_ops.c,v 1.4 1999/03/28 00:46:47 bgrayson Exp $ */
+/*     $NetBSD: procfs_ops.c,v 1.4.2.1 1999/11/08 06:40:19 cgd Exp $   */
 
 /*
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -17,8 +17,8 @@
  *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
- *        This product includes software developed by the NetBSD
- *        Foundation, Inc. and its contributors.
+ *     This product includes software developed by the NetBSD
+ *     Foundation, Inc. and its contributors.
  * 4. Neither the name of The NetBSD Foundation nor the names of its
  *    contributors may be used to endorse or promote products derived
  *    from this software without specific prior written permission.
@@ -42,6 +42,7 @@
 #include <sys/sysctl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/resource.h> /* for rusage */
 
 #include <fcntl.h>
 #include <dirent.h>
@@ -52,136 +53,168 @@
 #include <err.h>
 #include <kvm.h>
 
-/*  Assume that no process status file will ever be larger than this.  */
+#include "ps.h"
+
+/* Assume that no process status file will ever be larger than this. */
 #define STATUS_SIZE    8192
 
-/* Handy macro for only printing a warning once.  Notice that
+/*
+ * Handy macro for only printing a warning once.  Notice that
  * one needs to use two sets of parentheses when invoking the
- * macro:  WARNX_ONLY_ONCE(("mesgstr", arg1, arg2, ...));  */
-#define WARNX_ONLY_ONCE(x)     {       \
-       static int firsttime=1;         \
-       if (firsttime) {                \
-               firsttime=0;            \
-               warnx x ;               \
-       }                               \
+ * macro:  WARNX_ONLY_ONCE(("mesgstr", arg1, arg2, ...));
+ */
+#define WARNX_ONLY_ONCE(x)                                             \
+{                                                                      \
+       static int firsttime = 1;                                       \
+       if (firsttime) {                                                \
+               firsttime = 0;                                          \
+               warnx x ;                                               \
+       }                                                               \
 }
 
-static int             verify_procfs_fd __P((int, const char *));
-static int             parsekinfo __P((const char *, struct kinfo_proc *));
-struct kinfo_proc *    procfs_getprocs __P((int, int, int *));
+static int verify_procfs_fd __P((int, const char *));
+static int parsekinfo __P((const char *, KINFO *));
 
 static int
-verify_procfs_fd (fd, path)
-       int fd;
+verify_procfs_fd(fd, path)
+       int     fd;
        const char *path;
 {
        struct statfs procfsstat;
 
-       /*  If the fstatfs fails, die immediately.  Since we
-        *  already have the FD open, any error is probably one
-        *  that can't be worked around.  */
-       if (fstatfs(fd, &procfsstat)) {
+       /*
+        * If the fstatfs fails, die immediately.  Since we already have the
+        * FD open, any error is probably one that can't be worked around.
+        */
+       if (fstatfs(fd, &procfsstat))
                err(1, "fstatfs on %s", path);
-       }
-       /*  Now verify that the open file is truly on a procfs
-        *  filesystem.  */
+
+       /* Now verify that the open file is truly on a procfs filesystem. */
        if (strcmp(procfsstat.f_fstypename, MOUNT_PROCFS)) {
-               warnx("%s is on a '%s' filesystem, not 'procfs'???", path,
-                               procfsstat.f_fstypename);
+               warnx("%s is on a `%s' filesystem, not `procfs'", path,
+                   procfsstat.f_fstypename);
                return -1;
        }
        return 0;
 }
 
 static int
-parsekinfo (path, kp)
+parsekinfo(path, ki)
        const char *path;
-       struct kinfo_proc *kp;
+       KINFO *ki;
 {
-       char fullpath[MAXPATHLEN];
-       int dirfd, fd, nbytes, devmajor, devminor;
+       char    fullpath[MAXPATHLEN];
+       int     dirfd, fd, nbytes, devmajor, devminor;
        struct timeval usertime, systime, starttime;
-       char buff[STATUS_SIZE];
-       char flagstr[256];
+       char    buff[STATUS_SIZE];
+       char    flagstr[256];
+       struct kinfo_proc *kp = ki->ki_p;
 
-       /*  Verify that /proc/<pid> is a procfs file (and that no
-        *  one has mounted anything on top of it).  If we didn't
-        *  do this, an intruder could hide processes by simply
-        *  mount_null'ing /tmp on top of the /proc/<pid>
-        *  directory.  (And we can't just print warnings if we fail
-        *  to open /proc/<pid>/status, because the process may
-        *  have died since our getdents() call.)  */
+       /*
+        * Verify that /proc/<pid> is a procfs file (and that no one has
+        * mounted anything on top of it).  If we didn't do this, an intruder
+        * could hide processes by simply mount_null'ing /tmp on top of the
+        * /proc/<pid> directory.  (And we can't just print warnings if we
+        * fail to open /proc/<pid>/status, because the process may have died
+        * since our getdents() call.)
+        */
        snprintf(fullpath, MAXPATHLEN, "/proc/%s", path);
-       dirfd=open(fullpath, O_RDONLY, 0);
+       dirfd = open(fullpath, O_RDONLY, 0);
        if (verify_procfs_fd(dirfd, fullpath)) {
                close(dirfd);
                return -1;
        }
-       /*  Open /proc/"path"/status, and parse it into the kinfo_proc.  */
+
+       /* Open /proc/<pid>/status, and parse it into the kinfo_proc. */
        snprintf(fullpath, MAXPATHLEN, "/proc/%s/status", path);
-       fd=open(fullpath, O_RDONLY, 0);
+       fd = open(fullpath, O_RDONLY, 0);
        close(dirfd);
        if (fd == -1) {
-               /*  Don't print warning, as the process may have
-                *  died since our scan of the directory entries.  */
-               /*warn("Open failed for %s", fullpath);*/
-               close(fd);
-               return -1;  /*  Process may no longer exist.  */
+               /*
+                * Don't print warning, as the process may have died since our
+                * scan of the directory entries.
+                */
+               return -1;      /* Process may no longer exist. */
        }
-       /*  Bail out for this process attempt if it isn't on a
-        *  procfs.  Some intruder could have mounted something
-        *  on top of portions of /proc.  */
+
+       /*
+        * Bail out for this process attempt if it isn't on a procfs.  Some
+        * intruder could have mounted something on top of portions of /proc.
+        */
        if (verify_procfs_fd(fd, fullpath)) {
                close(fd);
                return -1;
        }
-       nbytes=read(fd, buff, STATUS_SIZE);
+
+       nbytes = read(fd, buff, STATUS_SIZE - 1);
        close(fd);
        if (nbytes <= 0) {
-               /*  Don't print warning, as the process may have
-                *  died since our scan of the directory entries.  */
-               /*warn("Read failed for %s", fullpath);*/
-               return -1;  /*  Process may no longer exist.  */
+               /*
+                * Don't print warning, as the process may have died since our
+                * scan of the directory entries.
+                */
+               return -1;      /* Process may no longer exist. */
        }
-       /*  Terminate the buffer.  */
+
+       /* Make sure the buffer is terminated. */
        buff[nbytes] = '\0';
+
        sscanf(buff, "%s %d %d %d %d %d,%d %s %ld,%ld %ld,%ld %ld,%ld %s %d",
-                       kp->kp_proc.p_comm, &kp->kp_proc.p_pid,
-                       &kp->kp_eproc.e_ppid, &kp->kp_eproc.e_pgid,
-                       &kp->kp_eproc.e_sid, &devmajor, &devminor,
-                       flagstr, &starttime.tv_sec, &starttime.tv_usec,
-                       &usertime.tv_sec, &usertime.tv_usec,
-                       &systime.tv_sec, &systime.tv_usec,
-                       kp->kp_eproc.e_wmesg, &kp->kp_eproc.e_ucred.cr_uid);
+           kp->kp_proc.p_comm, &kp->kp_proc.p_pid,
+           &kp->kp_eproc.e_ppid, &kp->kp_eproc.e_pgid,
+           &kp->kp_eproc.e_sid, &devmajor, &devminor,
+           flagstr, &starttime.tv_sec, &starttime.tv_usec,
+           &usertime.tv_sec, &usertime.tv_usec,
+           &systime.tv_sec, &systime.tv_usec,
+           kp->kp_eproc.e_wmesg, &kp->kp_eproc.e_ucred.cr_uid);
+
        kp->kp_proc.p_wmesg = kp->kp_eproc.e_wmesg;
-       kp->kp_proc.p_wchan = (void*)1; /*  Set it to _something_.  */
+       kp->kp_proc.p_wchan = (void *) 1;       /* XXX Set it to _something_. */
        kp->kp_eproc.e_tdev = makedev(devmajor, devminor);
-       /*  Put both user and sys time into rtime field.  */
+
+       /* Put both user and sys time into rtime field.  */
        kp->kp_proc.p_rtime.tv_sec = usertime.tv_sec + systime.tv_sec;
        kp->kp_proc.p_rtime.tv_usec = usertime.tv_usec + systime.tv_usec;
-       /*  CPU time isn't shown unless the ki_u.u_valid flag is
-        *  set.  Unfortunately, we don't have access to that here.  */
-       /*  Set the flag for whether or not there is
-        *  a controlling terminal.  */
+
+       /* if starttime.[u]sec is != -1, it's in-memory process */
+       if (starttime.tv_sec != -1 && starttime.tv_usec != -1) {
+               kp->kp_proc.p_flag |= P_INMEM;
+               ki->ki_u.u_valid = 1;
+               ki->ki_u.u_start.tv_sec = starttime.tv_sec;
+               ki->ki_u.u_start.tv_usec = starttime.tv_usec;
+       }
+
+       /*
+        * CPU time isn't shown unless the ki_u.u_valid flag is set.
+        * Unfortunately, we don't have access to that here.
+        */
+
+       /* Set the flag for whether or not there is a controlling terminal. */
        if (strstr(flagstr, "ctty"))
                kp->kp_proc.p_flag |= P_CONTROLT;
+
+       /* Set the flag for whether or not this process is session leader */
+       if (strstr(flagstr, "sldr"))
+               kp->kp_eproc.e_flag |= EPROC_SLEADER;
+
        return 0;
 }
 
-struct kinfo_proc *
-procfs_getprocs(op, arg, cnt)
-       int op, arg;
-       int *cnt;
+KINFO *
+getkinfo_procfs(op, arg, cnt)
+       int     op, arg;
+       int    *cnt;
 {
        struct stat statbuf;
-       int procdirfd, nbytes, knum=0, maxknum=0;
-       char *direntbuff;
+       int     procdirfd, nbytes, knum = 0, maxknum = 0;
+       char   *direntbuff;
        struct kinfo_proc *kp;
-       int mib[4];
-       size_t len;
+       KINFO   *ki;
+       int     mib[4];
+       size_t  len;
        struct statfs procfsstat;
 
-       /*  First, make sure that /proc is a procfs filesystem.  */
+       /* First, make sure that /proc is a procfs filesystem. */
        if (statfs("/proc", &procfsstat)) {
                warn("statfs on /proc failed");
                return 0;
@@ -191,12 +224,15 @@
                return 0;
        }
 
-       /* Try to stat /proc/1/status.  If we can't do
-        * that, then just return right away. */
+       /*
+        * Try to stat /proc/1/status.  If we can't do that, then just return
+        * right away.
+        */
        if (stat("/proc/1/status", &statbuf)) {
                warn("stat of /proc/1/status");
                return 0;
        }
+
        /* Now, try to open /proc, and read in all process' information. */
        procdirfd = open("/proc", O_RDONLY, 0);
        if (procdirfd == -1) {
@@ -215,75 +251,82 @@
                close(procdirfd);
                return 0;
        }
-       /* Use sysctl to find out the total number of processes.
-        * There's still a race condition -- once we do the
-        * sysctl, someone could use a sysctl to bump it, and
-        * fork off a lot of processes.  So, to be _really_
-        * safe, let's allocate twice as much memory. */
+



Home | Main Index | Thread Index | Old Index