diff options
author | Martin Baulig <martin@src.gnome.org> | 1998-08-16 18:46:53 +0000 |
---|---|---|
committer | Martin Baulig <martin@src.gnome.org> | 1998-08-16 18:46:53 +0000 |
commit | 59bb8d0ced4e3a255bb77e07b5abb4d8aead05f8 (patch) | |
tree | c6400967a6a4b2ead897b6d164f7c6deb3649e79 /sysdeps/linux | |
parent | 739ce693dcc33b3ec3c5c75d4c7b8f200f2608a8 (diff) | |
download | libgtop-59bb8d0ced4e3a255bb77e07b5abb4d8aead05f8.tar.gz |
Major code cleanups. We now use open () and read ().
Diffstat (limited to 'sysdeps/linux')
-rw-r--r-- | sysdeps/linux/glibtop_server.h | 64 | ||||
-rw-r--r-- | sysdeps/linux/prockernel.c | 50 | ||||
-rw-r--r-- | sysdeps/linux/procmem.c | 69 | ||||
-rw-r--r-- | sysdeps/linux/procsegment.c | 77 | ||||
-rw-r--r-- | sysdeps/linux/procsignal.c | 42 | ||||
-rw-r--r-- | sysdeps/linux/procstate.c | 62 | ||||
-rw-r--r-- | sysdeps/linux/proctime.c | 60 | ||||
-rw-r--r-- | sysdeps/linux/procuid.c | 97 |
8 files changed, 252 insertions, 269 deletions
diff --git a/sysdeps/linux/glibtop_server.h b/sysdeps/linux/glibtop_server.h index 2d3abe49..7526b661 100644 --- a/sysdeps/linux/glibtop_server.h +++ b/sysdeps/linux/glibtop_server.h @@ -27,6 +27,8 @@ __BEGIN_DECLS +#ifdef _IN_LIBGTOP + static inline char * skip_token (const char *p) { @@ -36,12 +38,74 @@ skip_token (const char *p) } static inline char * +skip_multiple_token (const char *p, int count) +{ + int i; + + for (i = 0; i < count; i++) + p = skip_token (p); + + return (char *)p; +} + +static inline char * skip_line (const char *p) { while (*p != '\n') p++; return (char *) p++; } +static inline int +proc_file_to_buffer (char *buffer, const char *fmt, pid_t pid) +{ + char filename [BUFSIZ]; + int fd, len; + + sprintf (filename, fmt, pid); + + fd = open (filename, O_RDONLY); + if (fd < 0) return -1; + + len = read (fd, buffer, BUFSIZ-1); + if (len < 0) return -1; + + close (fd); + + buffer [len] = '\0'; + + return 0; +} + +static inline int +proc_stat_to_buffer (char *buffer, pid_t pid) +{ + return proc_file_to_buffer (buffer, "/proc/%d/stat", pid); +} + +static inline int +proc_status_to_buffer (char *buffer, pid_t pid) +{ + return proc_file_to_buffer (buffer, "/proc/%d/status", pid); +} + +static inline int +proc_statm_to_buffer (char *buffer, pid_t pid) +{ + return proc_file_to_buffer (buffer, "/proc/%d/statm", pid); +} + +static inline char * +proc_stat_after_cmd (char *p) +{ + p = strrchr (p, ')'); + if (!p) return p; + + *p++ = '\0'; + return p; +} + +#endif + #define GLIBTOP_SUID_CPU 0 #define GLIBTOP_SUID_MEM 0 #define GLIBTOP_SUID_SWAP 0 diff --git a/sysdeps/linux/prockernel.c b/sysdeps/linux/prockernel.c index 2ea12ddd..5ca9159e 100644 --- a/sysdeps/linux/prockernel.c +++ b/sysdeps/linux/prockernel.c @@ -42,44 +42,34 @@ glibtop_init_proc_kernel_s (glibtop *server) void glibtop_get_proc_kernel_s (glibtop *server, glibtop_proc_kernel *buf, pid_t pid) { - char input [BUFSIZ], *tmp; - int nread; - FILE *f; + char buffer [BUFSIZ], *p; glibtop_init_s (&server, GLIBTOP_SYSDEPS_PROC_KERNEL, 0); memset (buf, 0, sizeof (glibtop_proc_kernel)); - sprintf (input, "/proc/%d/stat", pid); - - f = fopen (input, "r"); - if (!f) return; - - nread = fread (input, 1, BUFSIZ, f); - - if (nread < 0) { - fclose (f); + if (proc_stat_to_buffer (buffer, pid)) return; - } - - input [nread] = 0; - - /* This is from guile-utils/gtop/proc/readproc.c */ + + p = proc_stat_after_cmd (buffer); + if (!p) return; + + p = skip_multiple_token (p, 6); + + buf->k_flags = strtoul (p, &p, 0); + buf->min_flt = strtoul (p, &p, 0); + buf->cmin_flt = strtoul (p, &p, 0); + buf->maj_flt = strtoul (p, &p, 0); + buf->cmaj_flt = strtoul (p, &p, 0); + + p = skip_multiple_token (p, 15); + + buf->kstk_esp = strtoul (p, &p, 0); + buf->kstk_eip = strtoul (p, &p, 0); - /* split into "PID (cmd" and "<rest>" */ - tmp = strrchr (input, ')'); - *tmp = '\0'; /* replace trailing ')' with NUL */ - /* parse these two strings separately, skipping the leading "(". */ - - sscanf(tmp + 2, /* skip space after ')' too */ - "%*c %*d %*d %*d %*d %*d %Lu %Lu %Lu %Lu %Lu " - "%*d %*d %*d %*d %*d %*d %*u %*u %*d %*u " - "%*u %*u %*u %*u %*u %Lu %Lu %*d %*d %*d %*d %Lu", - &buf->k_flags, &buf->min_flt, &buf->cmin_flt, - &buf->maj_flt, &buf->cmaj_flt, &buf->kstk_esp, - &buf->kstk_eip, &buf->wchan); + p = skip_multiple_token (p, 4); - fclose (f); + buf->nwchan = strtoul (p, &p, 0); buf->flags = _glibtop_sysdeps_proc_kernel; } diff --git a/sysdeps/linux/procmem.c b/sysdeps/linux/procmem.c index 813eb696..355259d5 100644 --- a/sysdeps/linux/procmem.c +++ b/sysdeps/linux/procmem.c @@ -24,9 +24,12 @@ #include <glibtop/procmem.h> static const unsigned long _glibtop_sysdeps_proc_mem = -(1 << GLIBTOP_PROC_MEM_SIZE) + (1 << GLIBTOP_PROC_MEM_VSIZE) + -(1 << GLIBTOP_PROC_MEM_RESIDENT) + (1 << GLIBTOP_PROC_MEM_SHARE) + -(1 << GLIBTOP_PROC_MEM_RSS) + (1 << GLIBTOP_PROC_MEM_RSS_RLIM); +(1 << GLIBTOP_PROC_MEM_VSIZE) + (1 << GLIBTOP_PROC_MEM_RSS) + +(1 << GLIBTOP_PROC_MEM_RSS_RLIM); + +static const unsigned long _glibtop_sysdeps_proc_mem_statm = +(1 << GLIBTOP_PROC_MEM_SIZE) + (1 << GLIBTOP_PROC_MEM_RESIDENT) + +(1 << GLIBTOP_PROC_MEM_SHARE); #ifndef LOG1024 #define LOG1024 10 @@ -45,7 +48,8 @@ glibtop_init_proc_mem_s (glibtop *server) { register int pagesize; - server->sysdeps.proc_mem = _glibtop_sysdeps_proc_mem; + server->sysdeps.proc_mem = _glibtop_sysdeps_proc_mem | + _glibtop_sysdeps_proc_mem_statm; /* get the page size with "getpagesize" and calculate pageshift * from it */ @@ -62,64 +66,37 @@ glibtop_init_proc_mem_s (glibtop *server) void glibtop_get_proc_mem_s (glibtop *server, glibtop_proc_mem *buf, pid_t pid) { - char input [BUFSIZ], *tmp; - int nread; - FILE *f; + char buffer [BUFSIZ], *p; glibtop_init_s (&server, GLIBTOP_SYSDEPS_MEM, 0); memset (buf, 0, sizeof (glibtop_proc_mem)); - sprintf (input, "/proc/%d/stat", pid); - - f = fopen (input, "r"); - if (!f) return; - - nread = fread (input, 1, BUFSIZ, f); - - if (nread < 0) { - fclose (f); + if (proc_stat_to_buffer (buffer, pid)) return; - } - - input [nread] = 0; - - /* This is from guile-utils/gtop/proc/readproc.c */ - - /* split into "PID (cmd" and "<rest>" */ - tmp = strrchr (input, ')'); - *tmp = '\0'; /* replace trailing ')' with NUL */ - /* parse these two strings separately, skipping the leading "(". */ - sscanf(tmp + 2, /* skip space after ')' too */ - "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u " - "%*d %*d %*d %*d %*d %*d %*u %*u %*d %Lu " - "%Lu %Lu", &buf->vsize, &buf->rss, &buf->rss_rlim); - - fclose (f); - sprintf (input, "/proc/%d/statm", pid); + p = proc_stat_after_cmd (buffer); + if (!p) return; - f = fopen (input, "r"); - if (!f) return; + p = skip_multiple_token (p, 20); - nread = fread (input, 1, BUFSIZ, f); + buf->vsize = strtoul (p, &p, 0); + buf->rss = strtoul (p, &p, 0); + buf->rss_rlim = strtoul (p, &p, 0); - if (nread < 0) { - fclose (f); - return; - } + buf->flags = _glibtop_sysdeps_proc_mem; - input [nread] = 0; + if (proc_statm_to_buffer (buffer, pid)) + return; - sscanf (input, "%Lu %Lu %Lu", - &buf->size, &buf->resident, &buf->share); + buf->size = strtoul (buffer, &p, 0); + buf->resident = strtoul (p, &p, 0); + buf->share = strtoul (p, &p, 0); buf->size <<= pageshift; buf->resident <<= pageshift; buf->share <<= pageshift; buf->rss <<= pageshift; - fclose (f); - - buf->flags = _glibtop_sysdeps_proc_mem; + buf->flags |= _glibtop_sysdeps_proc_mem_statm; } diff --git a/sysdeps/linux/procsegment.c b/sysdeps/linux/procsegment.c index 9e6e479d..1082cabd 100644 --- a/sysdeps/linux/procsegment.c +++ b/sysdeps/linux/procsegment.c @@ -24,14 +24,17 @@ #include <glibtop/procsegment.h> static const unsigned long _glibtop_sysdeps_proc_segment = -(1 << GLIBTOP_PROC_SEGMENT_TEXT_RSS) + -(1 << GLIBTOP_PROC_SEGMENT_SHLIB_RSS) + -(1 << GLIBTOP_PROC_SEGMENT_DATA_RSS) + -(1 << GLIBTOP_PROC_SEGMENT_DIRTY_SIZE) + (1 << GLIBTOP_PROC_SEGMENT_START_CODE) + (1 << GLIBTOP_PROC_SEGMENT_END_CODE) + (1 << GLIBTOP_PROC_SEGMENT_START_STACK); +static const unsigned long _glibtop_sysdeps_proc_segment_statm = +(1 << GLIBTOP_PROC_SEGMENT_TEXT_RSS) + +/* Disabled due to bug in the Linux Kernel. */ +/* (1 << GLIBTOP_PROC_SEGMENT_SHLIB_RSS) + */ +(1 << GLIBTOP_PROC_SEGMENT_DATA_RSS) + +(1 << GLIBTOP_PROC_SEGMENT_DIRTY_SIZE); + #ifndef LOG1024 #define LOG1024 10 #endif @@ -49,7 +52,8 @@ glibtop_init_proc_segment_s (glibtop *server) { register int pagesize; - server->sysdeps.proc_segment = _glibtop_sysdeps_proc_segment; + server->sysdeps.proc_segment = _glibtop_sysdeps_proc_segment | + _glibtop_sysdeps_proc_segment_statm; /* get the page size with "getpagesize" and calculate pageshift * from it */ @@ -67,66 +71,43 @@ void glibtop_get_proc_segment_s (glibtop *server, glibtop_proc_segment *buf, pid_t pid) { - char input [BUFSIZ], *tmp; - int nread; - FILE *f; + char buffer [BUFSIZ], *p; glibtop_init_s (&server, GLIBTOP_SYSDEPS_PROC_SEGMENT, 0); memset (buf, 0, sizeof (glibtop_proc_segment)); - sprintf (input, "/proc/%d/stat", pid); - - f = fopen (input, "r"); - if (!f) return; - - nread = fread (input, 1, BUFSIZ, f); - - if (nread < 0) { - fclose (f); + if (proc_stat_to_buffer (buffer, pid)) return; - } - - input [nread] = 0; - - /* This is from guile-utils/gtop/proc/readproc.c */ - - /* split into "PID (cmd" and "<rest>" */ - tmp = strrchr (input, ')'); - *tmp = '\0'; /* replace trailing ')' with NUL */ - /* parse these two strings separately, skipping the leading "(". */ - sscanf(tmp + 2, /* skip space after ')' too */ - "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u " - "%*d %*d %*d %*d %*d %*d %*u %*u %*d %*u " - "%*u %*u %Lu %Lu %Lu", &buf->start_code, - &buf->end_code, &buf->start_stack); - - fclose (f); - sprintf (input, "/proc/%d/statm", pid); + p = proc_stat_after_cmd (buffer); + if (!p) return; - f = fopen (input, "r"); - if (!f) return; + p = skip_multiple_token (p, 23); - nread = fread (input, 1, BUFSIZ, f); + buf->start_code = strtoul (p, &p, 0); + buf->end_code = strtoul (p, &p, 0); + buf->start_stack = strtoul (p, &p, 0); + + buf->flags = _glibtop_sysdeps_proc_segment; - if (nread < 0) { - fclose (f); + if (proc_statm_to_buffer (buffer, pid)) return; - } - input [nread] = 0; + p = skip_multiple_token (buffer, 3); + + /* This doesn't work very well due to a bug in the Linux kernel. + * I'll submit a patch to the kernel mailing list soon. */ - sscanf (input, "%*d %*d %*d %Lu %Lu %Lu %Lu", - &buf->text_rss, &buf->shlib_rss, - &buf->data_rss, &buf->dirty_size); + buf->text_rss = strtoul (p, &p, 0); + buf->shlib_rss = strtoul (p, &p, 0); + buf->data_rss = strtoul (p, &p, 0); + buf->dirty_size = strtoul (p, &p, 0); buf->text_rss <<= pageshift; buf->shlib_rss <<= pageshift; buf->data_rss <<= pageshift; buf->dirty_size <<= pageshift; - fclose (f); - - buf->flags = _glibtop_sysdeps_proc_segment; + buf->flags |= _glibtop_sysdeps_proc_segment_statm; } diff --git a/sysdeps/linux/procsignal.c b/sysdeps/linux/procsignal.c index 67763a15..51a167df 100644 --- a/sysdeps/linux/procsignal.c +++ b/sysdeps/linux/procsignal.c @@ -40,42 +40,24 @@ glibtop_init_proc_signal_s (glibtop *server) void glibtop_get_proc_signal_s (glibtop *server, glibtop_proc_signal *buf, pid_t pid) { - char input [BUFSIZ], *tmp; - int nread; - FILE *f; + char buffer [BUFSIZ], *p; glibtop_init_s (&server, GLIBTOP_SYSDEPS_PROC_SIGNAL, 0); memset (buf, 0, sizeof (glibtop_proc_signal)); - sprintf (input, "/proc/%d/stat", pid); - - f = fopen (input, "r"); - if (!f) return; - - nread = fread (input, 1, BUFSIZ, f); - - if (nread < 0) { - fclose (f); + if (proc_stat_to_buffer (buffer, pid)) return; - } - - input [nread] = 0; - - /* This is from guile-utils/gtop/proc/readproc.c */ - - /* split into "PID (cmd" and "<rest>" */ - tmp = strrchr (input, ')'); - *tmp = '\0'; /* replace trailing ')' with NUL */ - /* parse these two strings separately, skipping the leading "(". */ - sscanf(tmp + 2, /* skip space after ')' too */ - "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u " - "%*d %*d %*d %*d %*d %*d %*u %*u %*d %*u " - "%*u %*u %*u %*u %*u %*u %*u %Lu %Lu %Lu %Lu", - &buf->signal, &buf->blocked, &buf->sigignore, - &buf->sigcatch); - - fclose (f); + + p = proc_stat_after_cmd (buffer); + if (!p) return; + + p = skip_multiple_token (p, 28); + + buf->signal = strtoul (p, &p, 0); + buf->blocked = strtoul (p, &p, 0); + buf->sigignore = strtoul (p, &p, 0); + buf->sigcatch = strtoul (p, &p, 0); buf->flags = _glibtop_sysdeps_proc_signal; } diff --git a/sysdeps/linux/procstate.c b/sysdeps/linux/procstate.c index 006dd026..666ebf11 100644 --- a/sysdeps/linux/procstate.c +++ b/sysdeps/linux/procstate.c @@ -26,7 +26,9 @@ #include <sys/stat.h> static const unsigned long _glibtop_sysdeps_proc_state = -(1 << GLIBTOP_PROC_STATE_CMD) + (1 << GLIBTOP_PROC_STATE_STATE) + +(1 << GLIBTOP_PROC_STATE_CMD) + (1 << GLIBTOP_PROC_STATE_STATE); + +static const unsigned long _glibtop_sysdeps_proc_state_uid = (1 << GLIBTOP_PROC_STATE_UID) + (1 << GLIBTOP_PROC_STATE_GID); /* Init function. */ @@ -34,7 +36,8 @@ static const unsigned long _glibtop_sysdeps_proc_state = void glibtop_init_proc_state_s (glibtop *server) { - server->sysdeps.proc_state = _glibtop_sysdeps_proc_state; + server->sysdeps.proc_state = _glibtop_sysdeps_proc_state | + _glibtop_sysdeps_proc_state_uid; } /* Provides detailed information about a process. */ @@ -42,52 +45,45 @@ glibtop_init_proc_state_s (glibtop *server) void glibtop_get_proc_state_s (glibtop *server, glibtop_proc_state *buf, pid_t pid) { - char input [BUFSIZ], *tmp; + char buffer [BUFSIZ], *p; struct stat statb; - int nread; - FILE *f; glibtop_init_s (&server, GLIBTOP_SYSDEPS_PROC_STATE, 0); memset (buf, 0, sizeof (glibtop_proc_state)); - sprintf (input, "/proc/%d/stat", pid); - /* IMPORTANT NOTICE: For security reasons it is extremely important * that the 'uid' and 'gid' fields have correct * values; NEVER set their flags values if this * is not the case !!! */ - if (stat (input, &statb)) return; + sprintf (buffer, "/proc/%d/stat", pid); + + if (stat (buffer, &statb)) + return; - /* For security reasons we use stat () that is more failsafe than sscanf (). */ + /* For security reasons we use stat () since it is + * more failsafe than parsing the file. */ buf->uid = statb.st_uid; buf->gid = statb.st_gid; - - f = fopen (input, "r"); - if (!f) return; - - nread = fread (input, 1, BUFSIZ, f); - - if (nread < 0) { - fclose (f); + + buf->flags = _glibtop_sysdeps_proc_state_uid; + + /* Now we read the remaining fields. */ + + if (proc_stat_to_buffer (buffer, pid)) return; - } - - fclose (f); - - input [nread] = 0; - /* This is from guile-utils/gtop/proc/readproc.c */ - - /* split into "PID (cmd" and "<rest>" */ - tmp = strrchr (input, ')'); - *tmp = '\0'; /* replace trailing ')' with NUL */ - /* parse these two strings separately, skipping the leading "(". */ - memset (buf->cmd, 0, sizeof (buf->cmd)); - sscanf (input, "%d (%39c", &pid, buf->cmd); - sscanf(tmp + 2, "%c", &buf->state); /* skip space after ')' too */ - - buf->flags = _glibtop_sysdeps_proc_state; + p = strrchr (buffer, ')'); *p = '\0'; + buf->state = p [2]; + + p = skip_token (buffer); p++; /* pid */ + if (*p++ != '(') + glibtop_error_r (server, "Bad data in /proc/%d/stat", pid); + + strncpy (buf->cmd, p, sizeof (buf->cmd)-1); + buf->cmd [sizeof (buf->cmd)-1] = 0; + + buf->flags |= _glibtop_sysdeps_proc_state; } diff --git a/sysdeps/linux/proctime.c b/sysdeps/linux/proctime.c index 86e2bd73..b871c1ac 100644 --- a/sysdeps/linux/proctime.c +++ b/sysdeps/linux/proctime.c @@ -24,10 +24,11 @@ #include <glibtop/proctime.h> static const unsigned long _glibtop_sysdeps_proc_time = -(1 << GLIBTOP_PROC_TIME_START_TIME) + (1 << GLIBTOP_PROC_TIME_UTIME) + -(1 << GLIBTOP_PROC_TIME_STIME) + (1 << GLIBTOP_PROC_TIME_CUTIME) + -(1 << GLIBTOP_PROC_TIME_CSTIME) + (1 << GLIBTOP_PROC_TIME_TIMEOUT) + -(1 << GLIBTOP_PROC_TIME_IT_REAL_VALUE); +(1 << GLIBTOP_PROC_TIME_UTIME) + (1 << GLIBTOP_PROC_TIME_CUTIME) + +(1 << GLIBTOP_PROC_TIME_STIME) + (1 << GLIBTOP_PROC_TIME_CSTIME) + +(1 << GLIBTOP_PROC_TIME_RTIME) + (1 << GLIBTOP_PROC_TIME_FREQUENCY) + +(1 << GLIBTOP_PROC_TIME_TIMEOUT) + (1 << GLIBTOP_PROC_TIME_IT_REAL_VALUE) + +(1 << GLIBTOP_PROC_TIME_START_TIME); /* Init function. */ @@ -42,41 +43,34 @@ glibtop_init_proc_time_s (glibtop *server) void glibtop_get_proc_time_s (glibtop *server, glibtop_proc_time *buf, pid_t pid) { - char input [BUFSIZ], *tmp; - int nread; - FILE *f; + char buffer [BUFSIZ], *p; glibtop_init_s (&server, GLIBTOP_SYSDEPS_PROC_TIME, 0); memset (buf, 0, sizeof (glibtop_proc_time)); - sprintf (input, "/proc/%d/stat", pid); - - f = fopen (input, "r"); - if (!f) return; - - nread = fread (input, 1, BUFSIZ, f); - - if (nread < 0) { - fclose (f); + if (proc_stat_to_buffer (buffer, pid)) return; - } - - input [nread] = 0; - - /* This is from guile-utils/gtop/proc/readproc.c */ - - /* split into "PID (cmd" and "<rest>" */ - tmp = strrchr (input, ')'); - *tmp = '\0'; /* replace trailing ')' with NUL */ - /* parse these two strings separately, skipping the leading "(". */ - sscanf(tmp + 2, /* skip space after ')' too */ - "%*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u " - "%Lu %Lu %Lu %Lu %*d %*d %Lu %Lu %Lu", - &buf->utime, &buf->stime, &buf->cutime, &buf->cstime, - &buf->timeout, &buf->it_real_value, &buf->start_time); - - fclose (f); + + p = proc_stat_after_cmd (buffer); + if (!p) return; + + p = skip_multiple_token (p, 11); + + buf->utime = strtoul (p, &p, 0); + buf->stime = strtoul (p, &p, 0); + buf->cutime = strtoul (p, &p, 0); + buf->cstime = strtoul (p, &p, 0); + + buf->rtime = buf->utime + buf->stime; + + p = skip_multiple_token (p, 2); + + buf->timeout = strtoul (p, &p, 0); + buf->it_real_value = strtoul (p, &p, 0); + buf->start_time = strtoul (p, &p, 0); + + buf->frequency = 100; buf->flags = _glibtop_sysdeps_proc_time; } diff --git a/sysdeps/linux/procuid.c b/sysdeps/linux/procuid.c index 5551fbf8..e5b491bb 100644 --- a/sysdeps/linux/procuid.c +++ b/sysdeps/linux/procuid.c @@ -25,7 +25,9 @@ static const unsigned long _glibtop_sysdeps_proc_uid = (1 << GLIBTOP_PROC_UID_UID) + (1 << GLIBTOP_PROC_UID_EUID) + -(1 << GLIBTOP_PROC_UID_GID) + (1 << GLIBTOP_PROC_UID_EGID) + +(1 << GLIBTOP_PROC_UID_GID) + (1 << GLIBTOP_PROC_UID_EGID); + +static const unsigned long _glibtop_sysdeps_proc_uid_stat = (1 << GLIBTOP_PROC_UID_PID) + (1 << GLIBTOP_PROC_UID_PPID) + (1 << GLIBTOP_PROC_UID_PGRP) + (1 << GLIBTOP_PROC_UID_SESSION) + (1 << GLIBTOP_PROC_UID_TTY) + (1 << GLIBTOP_PROC_UID_TPGID) + @@ -38,7 +40,8 @@ static const unsigned long _glibtop_sysdeps_proc_uid = void glibtop_init_proc_uid_s (glibtop *server) { - server->sysdeps.proc_uid = _glibtop_sysdeps_proc_uid; + server->sysdeps.proc_uid = _glibtop_sysdeps_proc_uid | + _glibtop_sysdeps_proc_uid_stat; } /* Provides detailed information about a process. */ @@ -46,65 +49,63 @@ glibtop_init_proc_uid_s (glibtop *server) void glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid) { - char input [BUFSIZ], *tmp; - int nread; - FILE *f; + char buffer [BUFSIZ], *p; glibtop_init_s (&server, GLIBTOP_SYSDEPS_PROC_UID, 0); memset (buf, 0, sizeof (glibtop_proc_uid)); - sprintf (input, "/proc/%d/status", pid); - - f = fopen (input, "r"); - if (!f) return; - - nread = fread (input, 1, BUFSIZ, f); - - if (nread < 0) { - fclose (f); + if (proc_status_to_buffer (buffer, pid)) return; - } - - input [nread] = 0; /* Search substring 'Pid:' */ - tmp = strstr (input, "Pid:"); + p = strstr (buffer, "\nPid:"); + if (!p) return; - if (tmp == NULL) return; + p = skip_token (p); /* "Pid:" */ + buf->pid = strtoul (p, &p, 0); - sscanf (tmp, "\nPid: %u\nPPid: %u\nUid: %u %u %*u %*u\n" - "Gid: %u %u %*u %*u\n", &buf->pid, &buf->ppid, - &buf->uid, &buf->euid, &buf->gid, &buf->egid); - - fclose (f); + p = skip_token (p); /* "PPid:" */ + buf->ppid = strtoul (p, &p, 0); - sprintf (input, "/proc/%d/stat", pid); + /* Maybe future Linux versions place something between + * "PPid" and "Uid", so we catch this here. */ + p = strstr (p, "\nUid:"); + if (!p) return; - f = fopen (input, "r"); - if (!f) return; - - nread = fread (input, 1, BUFSIZ, f); - - if (nread < 0) { - fclose (f); + p = skip_token (p); /* "Uid:" */ + buf->uid = strtoul (p, &p, 0); + buf->euid = strtoul (p, &p, 0); + + /* We don't know how many entries on the "Uid:" line + * future Linux version will have, so we catch this here. */ + p = strstr (p, "\nGid:"); + if (!p) return; + + p = skip_token (p); /* "Gid:" */ + buf->gid = strtoul (p, &p, 0); + buf->egid = strtoul (p, &p, 0); + + buf->flags = _glibtop_sysdeps_proc_uid; + + if (proc_stat_to_buffer (buffer, pid)) return; - } - - input [nread] = 0; - - /* This is from guile-utils/gtop/proc/readproc.c */ + + p = proc_stat_after_cmd (buffer); + if (!p) return; + + p = skip_multiple_token (p, 2); + + buf->pgrp = strtoul (p, &p, 0); + buf->session = strtoul (p, &p, 0); + buf->tty = strtoul (p, &p, 0); + buf->tpgid = strtoul (p, &p, 0); + + p = skip_multiple_token (p, 9); - /* split into "PID (cmd" and "<rest>" */ - tmp = strrchr (input, ')'); - *tmp = '\0'; /* replace trailing ')' with NUL */ - /* parse these two strings separately, skipping the leading "(". */ - sscanf(tmp + 2, /* skip space after ')' too */ - "%*c %*d %d %d %d %d %*u %*u %*u %*u %*u " - "%*d %*d %*d %*d %d %d", - &buf->pgrp, &buf->session, &buf->tty, &buf->tpgid, - &buf->priority, &buf->nice); + buf->priority = strtoul (p, &p, 0); + buf->nice = strtoul (p, &p, 0); if (buf->tty == 0) /* the old notty val, update elsewhere bef. moving to 0 */ @@ -119,7 +120,5 @@ glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid) /* when tty wasn't full devno */ buf->tty = 4*0x100 + buf->tty; - fclose (f); - - buf->flags = _glibtop_sysdeps_proc_uid; + buf->flags |= _glibtop_sysdeps_proc_uid_stat; } |