Patch last_pach62 from vodz. This patch moves all the /proc parsing
authorEric Andersen <andersen@codepoet.org>
Tue, 22 Oct 2002 12:21:15 +0000 (12:21 -0000)
committerEric Andersen <andersen@codepoet.org>
Tue, 22 Oct 2002 12:21:15 +0000 (12:21 -0000)
code into libbb so it can be shared by ps, top, etc, saving over 1.5k.

include/libbb.h
libbb/Makefile.in
libbb/find_pid_by_name.c
libbb/procps.c [new file with mode: 0644]
procps/kill.c
procps/pidof.c
procps/ps.c
procps/top.c

index 3b5f297..bc81123 100644 (file)
@@ -127,7 +127,7 @@ extern void write_mtab(char* blockDevice, char* directory,
        char* filesystemType, long flags, char* string_flags);
 extern void erase_mtab(const char * name);
 extern long atoi_w_units (const char *cp);
-extern long* find_pid_by_name( char* pidName);
+extern long* find_pid_by_name( const char* pidName);
 extern char *find_real_root_device_name(const char* name);
 extern char *get_line_from_file(FILE *file);
 extern void print_file(FILE *file);
@@ -337,4 +337,23 @@ extern ssize_t xread_all_eof(int fd, void *buf, size_t count);
 extern void xread_all(int fd, void *buf, size_t count);
 extern unsigned char xread_char(int fd);
 
+typedef struct {
+       int pid;
+       char user[9];
+       char state[4];
+       unsigned long rss;
+       int ppid;
+#ifdef FEATURE_CPU_USAGE_PERCENTAGE
+       unsigned pcpu;
+       unsigned long stime, utime;
+#endif
+       char *cmd;
+
+       /* basename of executable file in call to exec(2),
+               size from kernel headers */
+       char short_cmd[16];
+} procps_status_t;
+
+extern procps_status_t * procps_scan(int save_user_arg0);
+
 #endif /* __LIBCONFIG_H__ */
index f4ef0b8..6703cf1 100644 (file)
@@ -43,7 +43,8 @@ LIBBB_SRC:= \
        arith.c simplify_path.c inet_common.c inode_hash.c obscure.c \
        pwd2spwd.c xfuncs.c correct_password.c change_identity.c \
        setup_environment.c run_shell.c pw_encrypt.c restricted_shell.c \
-       xgethostbyname2.c create_icmp6_socket.c xconnect.c bb_asprintf.c
+       xgethostbyname2.c create_icmp6_socket.c xconnect.c bb_asprintf.c \
+       procps.c
 
 LIBBB_OBJS=$(patsubst %.c,$(LIBBB_DIR)%.o, $(LIBBB_SRC))
 
index 4eaee03..a648137 100644 (file)
@@ -22,7 +22,6 @@
 #include <stdio.h>
 #include <ctype.h>
 #include <string.h>
-#include <dirent.h>
 #include <stdlib.h>
 #include "libbb.h"
 
@@ -40,7 +39,7 @@
  *
  *  Returns a list of all matching PIDs
  */
-extern long* find_pid_by_name( char* pidName)
+extern long* find_pid_by_name( const char* pidName)
 {
        int fd, i, j;
        char device[] = "/dev/ps";
@@ -112,61 +111,28 @@ extern long* find_pid_by_name( char* pidName)
 
 /* find_pid_by_name()
  *  
+ *  Modified by Vladimir Oleynik for use with libbb/procps.c
  *  This finds the pid of the specified process.
  *  Currently, it's implemented by rummaging through 
  *  the proc filesystem.
  *
  *  Returns a list of all matching PIDs
  */
-extern long* find_pid_by_name( char* pidName)
+extern long* find_pid_by_name( const char* pidName)
 {
-       DIR *dir;
-       struct dirent *next;
-       long* pidList=NULL;
+       long* pidList;
        int i=0;
+       procps_status_t * p;
 
-       dir = opendir("/proc");
-       if (!dir)
-               perror_msg_and_die("Cannot open /proc");
-       
-       while ((next = readdir(dir)) != NULL) {
-               FILE *status;
-               char filename[READ_BUF_SIZE];
-               char buffer[READ_BUF_SIZE];
-               char name[READ_BUF_SIZE];
-
-               /* Must skip ".." since that is outside /proc */
-               if (strcmp(next->d_name, "..") == 0)
-                       continue;
-
-               /* If it isn't a number, we don't want it */
-               if (!isdigit(*next->d_name))
-                       continue;
-
-               sprintf(filename, "/proc/%s/status", next->d_name);
-               if (! (status = fopen(filename, "r")) ) {
-                       continue;
-               }
-               if (fgets(buffer, READ_BUF_SIZE-1, status) == NULL) {
-                       fclose(status);
-                       continue;
-               }
-               fclose(status);
-
-               /* Buffer should contain a string like "Name:   binary_name" */
-               sscanf(buffer, "%*s %s", name);
-               if (strcmp(name, pidName) == 0) {
+       pidList = xmalloc(sizeof(long));
+       while ((p = procps_scan(0)) != 0) {
+               if (strcmp(p->short_cmd, pidName) == 0) {
                        pidList=xrealloc( pidList, sizeof(long) * (i+2));
-                       pidList[i++]=strtol(next->d_name, NULL, 0);
+                       pidList[i++]=p->pid;
                }
        }
 
-       if (pidList) {
-               pidList[i]=0;
-       } else {
-               pidList=xrealloc( pidList, sizeof(long));
-               pidList[0]=-1;
-       }
+       pidList[i] = i==0 ? -1 : 0;
        return pidList;
 }
 #endif                                                 /* CONFIG_FEATURE_USE_DEVPS_PATCH */
diff --git a/libbb/procps.c b/libbb/procps.c
new file mode 100644 (file)
index 0000000..9ac5be0
--- /dev/null
@@ -0,0 +1,137 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Utility routines.
+ *
+ * Copyright 1998 by Albert Cahalan; all rights reserved.
+ * Copyright (C) 2002 by Vladimir Oleynik <dzo@simtreas.ru>
+ * GNU Library General Public License Version 2, or any later version
+ *
+ */
+
+#include "libbb.h"
+
+#if ! defined CONFIG_FEATURE_USE_DEVPS_PATCH
+#include <dirent.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <asm/page.h>
+
+
+extern procps_status_t * procps_scan(int save_user_arg0)
+{
+       static DIR *dir;
+       struct dirent *entry;
+       static procps_status_t ret_status;
+       char *name;
+       int n;
+       char status[32];
+       char buf[1024];
+       FILE *fp;
+       procps_status_t curstatus;
+       int pid;
+       long tasknice;
+       struct stat sb;
+
+       if (!dir) {
+               dir = opendir("/proc");
+               if(!dir)
+                       error_msg_and_die("Can't open /proc");
+       }
+       for(;;) {
+               if((entry = readdir(dir)) == NULL) {
+                       closedir(dir);
+                       dir = 0;
+                       return 0;
+               }
+               name = entry->d_name;
+               if (!(*name >= '0' && *name <= '9'))
+                       continue;
+
+               memset(&curstatus, 0, sizeof(procps_status_t));
+               pid = atoi(name);
+               curstatus.pid = pid;
+
+               sprintf(status, "/proc/%d/stat", pid);
+               if((fp = fopen(status, "r")) == NULL)
+                       continue;
+               if(fstat(fileno(fp), &sb))
+                       continue;
+               my_getpwuid(curstatus.user, sb.st_uid);
+               name = fgets(buf, sizeof(buf), fp);
+               fclose(fp);
+               if(name == NULL)
+                       continue;
+               name = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */
+               if(name == 0 || name[1] != ' ')
+                       continue;
+               *name = 0;
+               sscanf(buf, "%*s (%15c", curstatus.short_cmd);
+               n = sscanf(name+2,
+               "%c %d "
+               "%*s %*s %*s %*s "     /* pgrp, session, tty, tpgid */
+               "%*s %*s %*s %*s %*s " /* flags, min_flt, cmin_flt, maj_flt, cmaj_flt */
+#ifdef FEATURE_CPU_USAGE_PERCENTAGE
+               "%lu %lu "
+#else
+               "%*s %*s "
+#endif
+               "%*s %*s %*s "         /* cutime, cstime, priority */
+               "%ld "
+               "%*s %*s %*s "         /* timeout, it_real_value, start_time */
+               "%*s "                 /* vsize */
+               "%ld",
+               curstatus.state, &curstatus.ppid,
+#ifdef FEATURE_CPU_USAGE_PERCENTAGE
+               &curstatus.utime, &curstatus.stime,
+#endif
+               &tasknice,
+               &curstatus.rss);
+#ifdef FEATURE_CPU_USAGE_PERCENTAGE
+               if(n != 6)
+#else
+               if(n != 4)
+#endif
+                       continue;
+
+               if (curstatus.rss == 0 && curstatus.state[0] != 'Z')
+                       curstatus.state[1] = 'W';
+               else
+                       curstatus.state[1] = ' ';
+               if (tasknice < 0)
+                       curstatus.state[2] = '<';
+               else if (tasknice > 0)
+                       curstatus.state[2] = 'N';
+               else
+                       curstatus.state[2] = ' ';
+
+               curstatus.rss <<= (PAGE_SHIFT - 10);     /* 2**10 = 1kb */
+
+               sprintf(status, "/proc/%d/cmdline", pid);
+               if(save_user_arg0) {
+                       if((fp = fopen(status, "r")) == NULL)
+                               continue;
+                       if(fgets(buf, sizeof(buf), fp) != NULL) {
+                               name = strchr(buf, '\n');
+                               if(name != NULL)
+                                       *name = 0;
+                               if(buf[0])
+                                       curstatus.cmd = strdup(buf);
+                               /* if NULL it work true also */
+                       }
+                       fclose(fp);
+               }
+               return memcpy(&ret_status, &curstatus, sizeof(procps_status_t));
+       }
+}
+
+#endif /* CONFIG_FEATURE_USE_DEVPS_PATCH. Else this file is empty */
+
+/* END CODE */
+/*
+Local Variables:
+c-file-style: "linux"
+c-basic-offset: 4
+tab-width: 4
+End:
+*/
index 2ef87ae..cf5c412 100644 (file)
@@ -127,7 +127,7 @@ do_it_now:
                        long* pidList;
 
                        pidList = find_pid_by_name(*argv);
-                       if (!pidList || *pidList<=0) {
+                       if (*pidList <= 0) {
                                errors++;
                                if (quiet==0)
                                        error_msg( "%s: no process killed", *argv);
@@ -142,9 +142,7 @@ do_it_now:
                                        }
                                }
                        }
-                       /* Note that we don't bother to free the memory
-                        * allocated in find_pid_by_name().  It will be freed
-                        * upon exit, so we can save a byte or two */
+                       free(pidList);
                        argv++;
                }
        }
index d0d65e0..169a920 100644 (file)
@@ -54,21 +54,16 @@ extern int pidof_main(int argc, char **argv)
        while(optind < argc) {
                long* pidList;
 
-               pidList = find_pid_by_name( argv[optind]);
-               if (!pidList || *pidList<=0) {
-                       break;
-               }
-
-               for(; pidList && *pidList!=0; pidList++) {
+               pidList = find_pid_by_name(argv[optind]);
+               for(; *pidList > 0; pidList++) {
                        printf("%s%ld", (n++ ? " " : ""), (long)*pidList);
                        fail = 0;
                        if (single_flag)
                                break;
                }
-               /* Note that we don't bother to free the memory
-                * allocated in find_pid_by_name().  It will be freed
-                * upon exit, so we can save a byte or two */
+               free(pidList);
                optind++;
+
        }
        printf("\n");
 
index 6036ffc..cf2f2b0 100644 (file)
@@ -44,82 +44,10 @@ static const int TERMINAL_WIDTH = 79;      /* not 80 in case terminal has linefo
 
 #if ! defined CONFIG_FEATURE_USE_DEVPS_PATCH
 
-/* The following is the first ps implementation --
- * the one using the /proc virtual filesystem.
- */
-
-typedef struct proc_s {
-       char cmd[16];                                   /* basename of executable file in call to exec(2) */
-       int ruid;                                               /* real only (sorry) */
-       int pid;                                                /* process id */
-       int ppid;                                               /* pid of parent process */
-       char state;                                             /* single-char code for process state (S=sleeping) */
-       unsigned int vmsize;                    /* size of process as far as the vm is concerned */
-} proc_t;
-
-
-
-static int file2str(char *filename, char *ret, int cap)
-{
-       int fd, num_read;
-
-       if ((fd = open(filename, O_RDONLY, 0)) == -1)
-               return -1;
-       if ((num_read = read(fd, ret, cap - 1)) <= 0)
-               return -1;
-       ret[num_read] = 0;
-       close(fd);
-       return num_read;
-}
-
-
-static void parse_proc_status(char *S, proc_t * P)
-{
-       char *tmp;
-
-       memset(P->cmd, 0, sizeof P->cmd);
-       sscanf(S, "Name:\t%15c", P->cmd);
-       tmp = strchr(P->cmd, '\n');
-       if (tmp)
-               *tmp = '\0';
-       tmp = strstr(S, "State");
-       sscanf(tmp, "State:\t%c", &P->state);
-
-       P->pid = 0;
-       P->ppid = 0;
-       tmp = strstr(S, "Pid:");
-       if (tmp)
-               sscanf(tmp, "Pid:\t%d\n" "PPid:\t%d\n", &P->pid, &P->ppid);
-       else
-               error_msg("Internal error!");
-
-       /* For busybox, ignoring effective, saved, etc. */
-       P->ruid = 0;
-       tmp = strstr(S, "Uid:");
-       if (tmp)
-               sscanf(tmp, "Uid:\t%d", &P->ruid);
-       else
-               error_msg("Internal error!");
-       
-       P->vmsize = 0;
-       tmp = strstr(S, "VmSize:");
-       if (tmp)
-               sscanf(tmp, "VmSize:\t%d", &P->vmsize);
-#if 0
-       else
-               error_msg("Internal error!");
-#endif
-}
-
 extern int ps_main(int argc, char **argv)
 {
-       proc_t p;
-       DIR *dir;
-       FILE *file;
-       struct dirent *entry;
-       char path[32], sbuf[512];
-       char uidName[9];
-       int len, i, c;
+       procps_status_t * p;
+       int i, len;
 #ifdef CONFIG_FEATURE_AUTOWIDTH
        struct winsize win = { 0, 0, 0, 0 };
        int terminal_width = TERMINAL_WIDTH;
@@ -128,11 +56,6 @@ extern int ps_main(int argc, char **argv)
 #endif
 
 
-
-       dir = opendir("/proc");
-       if (!dir)
-               error_msg_and_die("Can't open /proc");
-
 #ifdef CONFIG_FEATURE_AUTOWIDTH
                ioctl(fileno(stdout), TIOCGWINSZ, &win);
                if (win.ws_col > 0)
@@ -140,38 +63,31 @@ extern int ps_main(int argc, char **argv)
 #endif
 
        printf("  PID  Uid     VmSize Stat Command\n");
-       while ((entry = readdir(dir)) != NULL) {
-               if (!isdigit(*entry->d_name))
-                       continue;
-               sprintf(path, "/proc/%s/status", entry->d_name);
-               if ((file2str(path, sbuf, sizeof sbuf)) != -1) {
-                       parse_proc_status(sbuf, &p);
-               }
+       while ((p = procps_scan(1)) != 0) {
+               char *namecmd = p->cmd;
 
-               /* Make some adjustments as needed */
-               my_getpwuid(uidName, p.ruid);
+               if(p->rss == 0)
+                       len = printf("%5d %-8s        %s ", p->pid, p->user, p->state);
+               else
+                       len = printf("%5d %-8s %6ld %s ", p->pid, p->user, p->rss, p->state);
+               i = terminal_width-len;
 
-               sprintf(path, "/proc/%s/cmdline", entry->d_name);
-               file = fopen(path, "r");
-               if (file == NULL)
-                       continue;
+               if(namecmd != 0 && namecmd[0] != 0) {
+                       if(i < 0)
                i = 0;
-               if(p.vmsize == 0)
-                       len = printf("%5d %-8s        %c    ", p.pid, uidName, p.state);
-               else
-                       len = printf("%5d %-8s %6d %c    ", p.pid, uidName, p.vmsize, p.state);
-               while (((c = getc(file)) != EOF) && (i < (terminal_width-len))) {
-                       i++;
-                       if (c == '\0')
-                               c = ' ';
-                       putc(c, stdout);
+                       if(strlen(namecmd) > i)
+                               namecmd[i] = 0;
+                       printf("%s\n", namecmd);
+               } else {
+                       namecmd = p->short_cmd;
+                       if(i < 2)
+                               i = 2;
+                       if(strlen(namecmd) > (i-2))
+                               namecmd[i-2] = 0;
+                       printf("[%s]\n", namecmd);
                }
-               fclose(file);
-               if (i == 0)
-                       printf("[%s]", p.cmd);
-               putchar('\n');
+               free(p->cmd);
        }
-       closedir(dir);
        return EXIT_SUCCESS;
 }
 
index 06ae771..4204dea 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <dirent.h>
 #include <string.h>
 #include <sys/ioctl.h>
-#include <sys/stat.h>
 /* get page info */
 #include <asm/page.h>
 #include "busybox.h"
 #endif
 
 
-typedef struct {
-       int pid;
-       char user[9];
-       char state[4];
-       unsigned long rss;
-       int ppid;
-#ifdef FEATURE_CPU_USAGE_PERCENTAGE
-       unsigned pcpu;
-       unsigned long stime, utime;
-#endif
-       char *cmd;
-
-       /* basename of executable file in call to exec(2),
-               size from kernel headers */
-       char short_cmd[16];
-} status_t;
-
-typedef int (*cmp_t)(status_t *P, status_t *Q);
+typedef int (*cmp_t)(procps_status_t *P, procps_status_t *Q);
 
-static status_t *top;   /* Hehe */
+static procps_status_t *top;   /* Hehe */
 static int ntop;
 
 
-static int pid_sort (status_t *P, status_t *Q)
+static int pid_sort (procps_status_t *P, procps_status_t *Q)
 {
     int p = P->pid;
     int q = Q->pid;
@@ -82,7 +63,7 @@ static int pid_sort (status_t *P, status_t *Q)
     return 0;
 }
 
-static int mem_sort (status_t *P, status_t *Q)
+static int mem_sort (procps_status_t *P, procps_status_t *Q)
 {
     long p = P->rss;
     long q = Q->rss;
@@ -97,7 +78,7 @@ static int mem_sort (status_t *P, status_t *Q)
 #define sort_depth 3
 static cmp_t sort_function[sort_depth];
 
-static int pcpu_sort (status_t *P, status_t *Q)
+static int pcpu_sort (procps_status_t *P, procps_status_t *Q)
 {
     int p = P->pcpu;
     int q = Q->pcpu;
@@ -107,7 +88,7 @@ static int pcpu_sort (status_t *P, status_t *Q)
     return 0;
 }
 
-static int time_sort (status_t *P, status_t *Q)
+static int time_sort (procps_status_t *P, procps_status_t *Q)
 {
     long p = P->stime;
     long q = Q->stime;
@@ -253,7 +234,7 @@ static void do_stats(void)
     struct timezone timez;
     float elapsed_time;
 
-    status_t *cur;
+    procps_status_t *cur;
     int total_time, i, n;
     static int prev_count;
     int systime, usrtime, pid;
@@ -317,7 +298,7 @@ static void do_stats(void)
     save_history = memcpy(xmalloc(sizeof(struct save_hist)*n), New_save_hist,
                                                sizeof(struct save_hist)*n);
     prev_count = n;
-    qsort(top, n, sizeof(status_t), (void*)mult_lvl_cmp);
+    qsort(top, n, sizeof(procps_status_t), (void*)mult_lvl_cmp);
 }
 #else
 static cmp_t sort_function;
@@ -370,7 +351,7 @@ static unsigned long display_generic(void)
 /* display process statuses */
 static void display_status(int count, int col)
 {
-       status_t *s = top;
+       procps_status_t *s = top;
        char rss_str_buf[8];
        unsigned long total_memory = display_generic();
        
@@ -382,7 +363,7 @@ static void display_status(int count, int col)
 #endif
 
        while (count--) {
-               char *namecmd = s->cmd;
+               char *namecmd = s->short_cmd;
                int pmem;
 
                pmem = 1000.0 * s->rss / total_memory;
@@ -402,130 +383,17 @@ static void display_status(int count, int col)
                        s->pcpu/10, s->pcpu%10,
 #endif
                        pmem/10, pmem%10);
-               if(namecmd != 0 && namecmd[0] != 0) {
                        if(strlen(namecmd) > col)
                                namecmd[col] = 0;
                        printf("%s\n", namecmd);
-                       } else {
-                       namecmd = s->short_cmd;
-                       if(strlen(namecmd) > (col-2))
-                               namecmd[col-2] = 0;
-                       printf("[%s]\n", namecmd);
-                       }
                s++;
-               }
+       }
 }
 
-/* returns true for file names which are PID dirs
- * (i.e. start with number)
- */
-static int filter_pids(const struct dirent *dir)
+static void clearmems(void)
 {
-       char *name = dir->d_name;
-       int n;
-       char status[20];
-       char buf[1024];
-       FILE *fp;
-       status_t curstatus;
-       int pid;
-       long tasknice;
-       struct stat sb;
-
-       if (!(*name >= '0' && *name <= '9'))
-               return 0;
-       if(stat(name, &sb))
-               return 0;
-
-       memset(&curstatus, 0, sizeof(status_t));
-       pid = atoi(name);
-       curstatus.pid = pid;
-       
-       my_getpwuid(curstatus.user, sb.st_uid);
-
-       sprintf(status, "%d/stat", pid);
-       if((fp = fopen(status, "r")) == NULL)
-               return 0;
-       name = fgets(buf, sizeof(buf), fp);
-                       fclose(fp);
-       if(name == NULL)
-               return 0;
-       name = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */
-       if(name == 0 || name[1] != ' ')
-               return 0;
-       *name = 0;
-       sscanf(buf, "%*s (%15c", curstatus.short_cmd);
-       n = sscanf(name+2,
-        "%c %d "
-        "%*s %*s %*s %*s "     /* pgrp, session, tty, tpgid */
-        "%*s %*s %*s %*s %*s " /* flags, min_flt, cmin_flt, maj_flt, cmaj_flt */
-#ifdef FEATURE_CPU_USAGE_PERCENTAGE
-        "%lu %lu "
-#else
-        "%*s %*s "
-#endif
-        "%*s %*s %*s "         /* cutime, cstime, priority */
-        "%ld "
-        "%*s %*s %*s "         /* timeout, it_real_value, start_time */
-        "%*s "                 /* vsize */
-        "%ld",
-        curstatus.state, &curstatus.ppid,
-#ifdef FEATURE_CPU_USAGE_PERCENTAGE
-       &curstatus.utime, &curstatus.stime,
-#endif
-       &tasknice,
-       &curstatus.rss);
-#ifdef FEATURE_CPU_USAGE_PERCENTAGE
-       if(n != 6)
-#else
-       if(n != 4)
-#endif
-               return 0;
-
-       if (curstatus.rss == 0 && curstatus.state[0] != 'Z')
-               curstatus.state[1] = 'W';
-        else
-               curstatus.state[1] = ' ';
-       if (tasknice < 0)
-               curstatus.state[2] = '<';
-        else if (tasknice > 0)
-               curstatus.state[2] = 'N';
-        else
-               curstatus.state[2] = ' ';
-
-       curstatus.rss <<= (PAGE_SHIFT - 10);     /* 2**10 = 1kb */
-
-       sprintf(status, "%d/cmdline", pid);
-       if((fp = fopen(status, "r")) == NULL)
-               return 0;
-       if(fgets(buf, sizeof(buf), fp) != NULL) {
-            name = strchr(buf, '\n');
-            if(name != NULL)
-               *name = 0;
-            if(buf[0])
-               curstatus.cmd = strdup(buf); /* if NULL it work true also */
-               }
-               fclose(fp);
-               
-       n = ntop;
-       top = xrealloc(top, (++ntop)*sizeof(status_t));
-       memcpy(top + n, &curstatus, sizeof(status_t));
-       return 1;
-}
-
-
-static struct dirent **namelist;
-
-static void clearmems(void) {
-       int i;
-
-       for(i = 0; i < ntop; i++) {
-               free(top[i].cmd);
-               free(namelist[i]);
-       }
        free(top);
-       free(namelist);
        top = 0;
-       namelist = 0;
        ntop = 0;
 }
 
@@ -591,7 +459,7 @@ int top_main(int argc, char **argv)
 #else
        col = 35;
 #endif
-       /* change to proc */
+       /* change to /proc */
        if (chdir("/proc") < 0) {
                perror_msg_and_die("chdir('/proc')");
        }
@@ -631,7 +499,15 @@ int top_main(int argc, char **argv)
 #endif
        while (1) {
                /* read process IDs & status for all the processes */
-               if (scandir(".", &namelist, filter_pids, 0) < 0) {
+               procps_status_t * p;
+
+               while ((p = procps_scan(0)) != 0) {
+                       int n = ntop;
+
+                       top = xrealloc(top, (++ntop)*sizeof(procps_status_t));
+                       memcpy(top + n, p, sizeof(procps_status_t));
+               }
+               if (ntop == 0) {
                perror_msg_and_die("scandir('/proc')");
        }
 #ifdef FEATURE_CPU_USAGE_PERCENTAGE
@@ -644,7 +520,7 @@ int top_main(int argc, char **argv)
        }
                do_stats();
 #else
-               qsort(top, ntop, sizeof(status_t), (void*)sort_function);
+               qsort(top, ntop, sizeof(procps_status_t), (void*)sort_function);
 #endif
                opt = lines;
                if (opt > ntop) {