summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Baulig <martin@src.gnome.org>1998-08-16 18:46:53 +0000
committerMartin Baulig <martin@src.gnome.org>1998-08-16 18:46:53 +0000
commit59bb8d0ced4e3a255bb77e07b5abb4d8aead05f8 (patch)
treec6400967a6a4b2ead897b6d164f7c6deb3649e79
parent739ce693dcc33b3ec3c5c75d4c7b8f200f2608a8 (diff)
downloadlibgtop-59bb8d0ced4e3a255bb77e07b5abb4d8aead05f8.tar.gz
Major code cleanups. We now use open () and read ().
-rw-r--r--sysdeps/linux/glibtop_server.h64
-rw-r--r--sysdeps/linux/prockernel.c50
-rw-r--r--sysdeps/linux/procmem.c69
-rw-r--r--sysdeps/linux/procsegment.c77
-rw-r--r--sysdeps/linux/procsignal.c42
-rw-r--r--sysdeps/linux/procstate.c62
-rw-r--r--sysdeps/linux/proctime.c60
-rw-r--r--sysdeps/linux/procuid.c97
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;
}