Patch last_pach62 from vodz. This patch moves all the /proc parsing code into libbb so it can be shared by ps, top, etc, saving over 1.5k.
No binary (build failed)
—
(log yok)
| @@ -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__ */ | |
| @@ -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)) | |
| @@ -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 */ | |
| @@ -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 <[email protected]> |
| + | * 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: |
| + | */ |
| @@ -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++; | |
| } | |
| } | |
| @@ -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"); | |
| @@ -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; | |
| } | |
| @@ -31,10 +31,8 @@ | |
| #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" | |
| @@ -49,30 +47,13 @@ | |
| #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) { | |