ps: adaptions for level 2 handling
authorAlan Cox <alan@linux.intel.com>
Sun, 10 Jan 2016 12:33:31 +0000 (12:33 +0000)
committerAlan Cox <alan@linux.intel.com>
Sun, 10 Jan 2016 12:33:31 +0000 (12:33 +0000)
Actually more generally fix it to be far less fragile about struct sizes

Applications/util/ps.c
Kernel/include/kernel.h
Library/include/proc.h

index 9acf355..ce12106 100644 (file)
@@ -10,6 +10,8 @@
 #define        F_r     0x04            /* running only flag */
 #define        F_n     0x08            /* numeric output flag */
 
+#define PTABSIZE       128
+
 int flags;
 
 char *mapstat(char s)
@@ -30,10 +32,11 @@ char *mapstat(char s)
 
 int do_ps(void)
 {
-    int i, j, uid, pfd, ptsize;
+    int i, j, uid, pfd, ptsize, nodesize;
     struct passwd *pwd;
+    struct p_tab_buffer *ppbuf;
     struct p_tab *pp;
-    static struct p_tab ptab[PTABSIZE];
+    static struct p_tab_buffer ptab[PTABSIZE];
     static char name[10], uname[20];
 
     uid = getuid();
@@ -43,6 +46,16 @@ int do_ps(void)
         return 1;
     }
         
+    if (ioctl(pfd, 2, (char *) &nodesize) != 0) {
+        perror("ioctl");
+        close(pfd);
+        return 1;
+    }
+
+    if (nodesize > sizeof(struct p_tab_buffer)) {
+        fprintf(stderr, "kernel/user include mismatch.\n");
+        exit(1);
+    }
     if (ioctl(pfd, 1, (char *) &ptsize) != 0) {
         perror("ioctl");
         close(pfd);
@@ -51,9 +64,10 @@ int do_ps(void)
     
     if (ptsize > PTABSIZE) ptsize = PTABSIZE;
     
+    /* FIXME: we don't need to buffer these first - it's silly */
     for (i = 0; i < ptsize; ++i) {
-        if (read(pfd, (char * ) &ptab[i], sizeof(struct p_tab)) !=
-                                          sizeof(struct p_tab)) {
+        if (read(pfd, (char * ) &ptab[i], nodesize) !=
+                                          nodesize) {
             fprintf(stderr, "ps: error reading from /dev/proc\n");
             close(pfd);
             return 1;
@@ -68,7 +82,8 @@ int do_ps(void)
            printf("USER\t  PID\tSTAT\tWCHAN\tALARM\tCOMMAND\n");
     }
 
-    for (pp = ptab, i = 0; i < ptsize; ++i, ++pp) {
+    for (ppbuf = ptab, i = 0; i < ptsize; ++i, ++ppbuf) {
+        pp = &ppbuf->p_tab;
        if (pp->p_status == 0)
            continue;
 
index 4d8d539..eb79c7f 100644 (file)
@@ -624,6 +624,7 @@ struct sysinfoblk {
   uint16_t config;             /* Config flag mask */
 #define CONF_PROFIL            1
 #define CONF_NET               2       /* Hah.. 8) */
+#define CONF_LEVEL_2           4
   uint16_t loadavg[3];
   uint32_t spare2;
                                /* Followed by uname strings */
index ccc7c5f..2929a09 100644 (file)
@@ -19,7 +19,7 @@
 
 /* Process table entry */
 
-typedef struct p_tab {
+struct p_tab {
     /* WRS: UPDATE kernel.def IF YOU CHANGE THIS STRUCTURE */
     uint8_t     p_status;       /* Process status: MUST BE FIRST MEMBER OF STRUCT */
     uint8_t     p_tty;          /* Process' controlling tty minor # */
@@ -48,16 +48,27 @@ typedef struct p_tab {
     uint16_t    p_pgrp;         /* Process group */
     uint8_t     p_nice;
     uint16_t   p_top;          /* Copy of u_top : FIXME: usize_t */
-#ifdef CONFIG_PROFIL
+};
+
+/* Followed by this structure if profiling supported */
+struct p_prof {
     uint8_t     p_profscale;
     void *      p_profbuf;
     uint16_t    p_profsize;
     uint16_t    p_profoff;
-#endif
 };
 
-#ifndef PTABSIZE
-#define PTABSIZE 15      /* Process table size. */
-#endif
+/* Then this one if level 2 */
+struct p_level_2 {
+    uint16_t   p_session;
+};
+
+/* The offsets of the prof and l2 are not guaranteed to be as per this
+   structure. Use this only for sizing */
+struct p_tab_buffer {
+    struct p_tab       p_tab;
+    struct p_prof      _prof;
+    struct p_level_2   _l2;
+};
 
 #endif /* __PROC_H */