summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Baulig <martin@home-of-linux.org>1998-06-07 20:38:02 +0000
committerMartin Baulig <martin@src.gnome.org>1998-06-07 20:38:02 +0000
commit9c9ad03d60e25892821169680ff4490a0bf48592 (patch)
treeab64803e130be2e97f1bfa51d4c1bf3c0fb8bae6
parentc84923132a0aaade80a48eb762b27d87640d3921 (diff)
downloadlibgtop-9c9ad03d60e25892821169680ff4490a0bf48592.tar.gz
New file.
1998-06-07 Martin Baulig <martin@home-of-linux.org> * sysdeps/linux/glibtop_machine.h: New file. * sysdeps/linux/*.c: Performance optimizations. We now use `open' and `read' instead of `fopen' and `fscanf'.
-rw-r--r--sysdeps/linux/cpu.c32
-rw-r--r--sysdeps/linux/glibtop_machine.h43
-rw-r--r--sysdeps/linux/loadavg.c32
-rw-r--r--sysdeps/linux/mem.c35
-rw-r--r--sysdeps/linux/prockernel.c51
-rw-r--r--sysdeps/linux/procmem.c85
-rw-r--r--sysdeps/linux/procsegment.c87
-rw-r--r--sysdeps/linux/procsignal.c51
-rw-r--r--sysdeps/linux/procstate.c44
-rw-r--r--sysdeps/linux/proctime.c51
-rw-r--r--sysdeps/linux/procuid.c81
-rw-r--r--sysdeps/linux/swap.c32
-rw-r--r--sysdeps/linux/uptime.c21
13 files changed, 451 insertions, 194 deletions
diff --git a/sysdeps/linux/cpu.c b/sysdeps/linux/cpu.c
index 058f3586..6dc68c6a 100644
--- a/sysdeps/linux/cpu.c
+++ b/sysdeps/linux/cpu.c
@@ -20,6 +20,7 @@
Boston, MA 02111-1307, USA. */
#include <config.h>
+#include <glibtop/error.h>
#include <glibtop/cpu.h>
static const unsigned long _glibtop_sysdeps_cpu =
@@ -29,10 +30,13 @@ static const unsigned long _glibtop_sysdeps_cpu =
/* Provides information about cpu usage. */
+#define FILENAME "/proc/stat"
+
void
glibtop_get_cpu_s (glibtop *server, glibtop_cpu *buf)
{
- FILE *f;
+ char buffer [BUFSIZ];
+ int fd = 0, ret;
glibtop_init_r (&server, 0, 0);
@@ -40,15 +44,33 @@ glibtop_get_cpu_s (glibtop *server, glibtop_cpu *buf)
buf->flags = _glibtop_sysdeps_cpu;
- f = fopen ("/proc/stat", "r");
- if (!f) return;
+#ifdef GLIBTOP_CACHE_OPEN
+ fd = server->machine.fd_stat;
+#endif
+ if (fd == 0) {
+ fd = open (FILENAME, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ FILENAME, strerror (errno));
+ } else {
+ lseek (fd, 0, SEEK_SET);
+ }
+
+ ret = read (fd, buffer, BUFSIZ);
+ if (ret == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ FILENAME, strerror (errno));
- fscanf (f, "cpu %lu %lu %lu %lu\n",
+ sscanf (buffer, "cpu %lu %lu %lu %lu\n",
&buf->user, &buf->nice, &buf->sys, &buf->idle);
buf->total = buf->user + buf->nice + buf->sys + buf->idle;
buf->frequency = 100;
- fclose (f);
+#ifdef GLIBTOP_CACHE_OPEN
+ server->machine.fd_stat = fd;
+#else
+ close (fd);
+#endif
}
diff --git a/sysdeps/linux/glibtop_machine.h b/sysdeps/linux/glibtop_machine.h
new file mode 100644
index 00000000..600d562c
--- /dev/null
+++ b/sysdeps/linux/glibtop_machine.h
@@ -0,0 +1,43 @@
+/* $Id$ */
+
+/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+ This file is part of the Gnome Top Library.
+ Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998.
+
+ The Gnome Top Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Top Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef __GLIBTOP_MACHINE_H__
+#define __GLIBTOP_MACHINE_H__
+
+#include <unistd.h>
+#include <fcntl.h>
+
+__BEGIN_DECLS
+
+typedef struct _glibtop_machine glibtop_machine;
+
+struct _glibtop_machine
+{
+ pid_t last_pid;
+ int no_update;
+ int fd_stat, fd_meminfo, fd_loadavg;
+ char proc_stat [BUFSIZ], proc_statm [BUFSIZ];
+ char proc_status [BUFSIZ];
+};
+
+__END_DECLS
+
+#endif
diff --git a/sysdeps/linux/loadavg.c b/sysdeps/linux/loadavg.c
index fbfa310f..96565610 100644
--- a/sysdeps/linux/loadavg.c
+++ b/sysdeps/linux/loadavg.c
@@ -20,17 +20,21 @@
Boston, MA 02111-1307, USA. */
#include <config.h>
+#include <glibtop/error.h>
#include <glibtop/loadavg.h>
static const unsigned long _glibtop_sysdeps_loadavg =
(1 << GLIBTOP_LOADAVG_LOADAVG);
+#define FILENAME "/proc/loadavg"
+
/* Provides load load averange. */
void
glibtop_get_loadavg_s (glibtop *server, glibtop_loadavg *buf)
{
- FILE *f;
+ char buffer [BUFSIZ];
+ int fd = 0, ret;
glibtop_init_r (&server, 0, 0);
@@ -38,11 +42,29 @@ glibtop_get_loadavg_s (glibtop *server, glibtop_loadavg *buf)
buf->flags = _glibtop_sysdeps_loadavg;
- f = fopen ("/proc/loadavg", "r");
- if (!f) return;
+#ifdef GLIBTOP_CACHE_OPEN
+ fd = server->machine.fd_loadavg;
+#endif
+ if (fd == 0) {
+ fd = open (FILENAME, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ FILENAME, strerror (errno));
+ } else {
+ lseek (fd, 0, SEEK_SET);
+ }
+
+ ret = read (fd, buffer, BUFSIZ);
+ if (ret == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ FILENAME, strerror (errno));
- fscanf (f, "%lf %lf %lf\n",
+ sscanf (buffer, "%lf %lf %lf\n",
&buf->loadavg [0], &buf->loadavg [1], &buf->loadavg [2]);
- fclose (f);
+#ifdef GLIBTOP_CACHE_OPEN
+ server->machine.fd_loadavg = fd;
+#else
+ close (fd);
+#endif
}
diff --git a/sysdeps/linux/mem.c b/sysdeps/linux/mem.c
index 937a6c81..41b54323 100644
--- a/sysdeps/linux/mem.c
+++ b/sysdeps/linux/mem.c
@@ -20,6 +20,7 @@
Boston, MA 02111-1307, USA. */
#include <config.h>
+#include <glibtop/error.h>
#include <glibtop/mem.h>
static const unsigned long _glibtop_sysdeps_mem =
@@ -28,12 +29,15 @@ static const unsigned long _glibtop_sysdeps_mem =
(1 << GLIBTOP_MEM_BUFFER) + (1 << GLIBTOP_MEM_CACHED) +
(1 << GLIBTOP_MEM_USER);
+#define FILENAME "/proc/meminfo"
+
/* Provides information about memory usage. */
void
glibtop_get_mem_s (glibtop *server, glibtop_mem *buf)
{
- FILE *f;
+ char buffer [BUFSIZ];
+ int fd = 0, ret;
glibtop_init_r (&server, 0, 0);
@@ -41,13 +45,32 @@ glibtop_get_mem_s (glibtop *server, glibtop_mem *buf)
buf->flags = _glibtop_sysdeps_mem;
- f = fopen ("/proc/meminfo", "r");
- if (!f) return;
+#ifdef GLIBTOP_CACHE_OPEN
+ fd = server->machine.fd_meminfo;
+#endif
+ if (fd == 0) {
+ fd = open (FILENAME, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ FILENAME, strerror (errno));
+ } else {
+ lseek (fd, 0, SEEK_SET);
+ }
+
+ ret = read (fd, buffer, BUFSIZ);
+ if (ret == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ FILENAME, strerror (errno));
- fscanf (f, "%*[^\n]\nMem: %lu %lu %lu %lu %lu %lu\n",
- &buf->total, &buf->used, &buf->free, &buf->shared, &buf->buffer, &buf->cached);
+ sscanf (buffer, "%*[^\n]\nMem: %lu %lu %lu %lu %lu %lu\n",
+ &buf->total, &buf->used, &buf->free, &buf->shared,
+ &buf->buffer, &buf->cached);
buf->user = buf->total - buf->free - buf->shared - buf->buffer;
- fclose (f);
+#ifdef GLIBTOP_CACHE_OPEN
+ server->machine.fd_meminfo = fd;
+#else
+ close (fd);
+#endif
}
diff --git a/sysdeps/linux/prockernel.c b/sysdeps/linux/prockernel.c
index 13e56b62..e9fc8eb9 100644
--- a/sysdeps/linux/prockernel.c
+++ b/sysdeps/linux/prockernel.c
@@ -20,6 +20,7 @@
Boston, MA 02111-1307, USA. */
#include <glibtop.h>
+#include <glibtop/error.h>
#include <glibtop/prockernel.h>
static const unsigned long _glibtop_sysdeps_proc_kernel =
@@ -33,9 +34,8 @@ static const unsigned long _glibtop_sysdeps_proc_kernel =
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], input [BUFSIZ], *tmp;
+ int fd = 0, nread;
glibtop_init_r (&server, 0, 0);
@@ -47,24 +47,41 @@ glibtop_get_proc_kernel_s (glibtop *server, glibtop_proc_kernel *buf, pid_t pid)
return;
}
- sprintf (input, "/proc/%d/stat", pid);
+ if (pid != server->machine.last_pid) {
+ server->machine.last_pid = pid;
+ server->machine.no_update = 0;
+ }
- f = fopen (input, "r");
- if (!f) return;
-
- nread = fread (input, 1, BUFSIZ, f);
-
- if (nread < 0) {
- fclose (f);
- return;
+ if (!server->machine.no_update) {
+ server->machine.proc_status [0] = 0;
+ server->machine.proc_statm [0] = 0;
+ server->machine.proc_stat [0] = 0;
}
-
- input [nread] = 0;
-
+
+ if (server->machine.proc_stat [0]) {
+ strcpy (buffer, server->machine.proc_stat);
+ } else {
+ sprintf (input, "/proc/%d/stat", pid);
+
+ fd = open (input, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ input, strerror (errno));
+
+ nread = read (fd, buffer, BUFSIZ);
+ if (nread == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ input, strerror (errno));
+
+ buffer [nread] = 0;
+ strcpy (server->machine.proc_stat, buffer);
+ close (fd);
+ }
+
/* This is from guile-utils/gtop/proc/readproc.c */
/* split into "PID (cmd" and "<rest>" */
- tmp = strrchr (input, ')');
+ tmp = strrchr (buffer, ')');
*tmp = '\0'; /* replace trailing ')' with NUL */
/* parse these two strings separately, skipping the leading "(". */
@@ -75,8 +92,6 @@ glibtop_get_proc_kernel_s (glibtop *server, glibtop_proc_kernel *buf, pid_t pid)
&buf->k_flags, &buf->min_flt, &buf->cmin_flt,
&buf->maj_flt, &buf->cmaj_flt, &buf->kstk_esp,
&buf->kstk_eip, &buf->wchan);
-
- fclose (f);
buf->flags = _glibtop_sysdeps_proc_kernel;
}
diff --git a/sysdeps/linux/procmem.c b/sysdeps/linux/procmem.c
index 22e0c128..fb03466e 100644
--- a/sysdeps/linux/procmem.c
+++ b/sysdeps/linux/procmem.c
@@ -20,6 +20,7 @@
Boston, MA 02111-1307, USA. */
#include <glibtop.h>
+#include <glibtop/error.h>
#include <glibtop/procmem.h>
static const unsigned long _glibtop_sysdeps_proc_mem =
@@ -32,9 +33,8 @@ static const unsigned long _glibtop_sysdeps_proc_mem =
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], input [BUFSIZ], *tmp;
+ int fd = 0, nread;
glibtop_init_r (&server, 0, 0);
@@ -46,24 +46,41 @@ glibtop_get_proc_mem_s (glibtop *server, glibtop_proc_mem *buf, pid_t pid)
return;
}
- sprintf (input, "/proc/%d/stat", pid);
+ if (pid != server->machine.last_pid) {
+ server->machine.last_pid = pid;
+ server->machine.no_update = 0;
+ }
- f = fopen (input, "r");
- if (!f) return;
-
- nread = fread (input, 1, BUFSIZ, f);
-
- if (nread < 0) {
- fclose (f);
- return;
+ if (!server->machine.no_update) {
+ server->machine.proc_status [0] = 0;
+ server->machine.proc_statm [0] = 0;
+ server->machine.proc_stat [0] = 0;
+ }
+
+ if (server->machine.proc_stat [0]) {
+ strcpy (buffer, server->machine.proc_stat);
+ } else {
+ sprintf (input, "/proc/%d/stat", pid);
+
+ fd = open (input, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ input, strerror (errno));
+
+ nread = read (fd, buffer, BUFSIZ);
+ if (nread == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ input, strerror (errno));
+
+ buffer [nread] = 0;
+ strcpy (server->machine.proc_stat, buffer);
+ close (fd);
}
-
- input [nread] = 0;
/* This is from guile-utils/gtop/proc/readproc.c */
/* split into "PID (cmd" and "<rest>" */
- tmp = strrchr (input, ')');
+ tmp = strrchr (buffer, ')');
*tmp = '\0'; /* replace trailing ')' with NUL */
/* parse these two strings separately, skipping the leading "(". */
sscanf(tmp + 2, /* skip space after ')' too */
@@ -71,26 +88,28 @@ glibtop_get_proc_mem_s (glibtop *server, glibtop_proc_mem *buf, pid_t pid)
"%*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);
-
- f = fopen (input, "r");
- if (!f) return;
-
- nread = fread (input, 1, BUFSIZ, f);
-
- if (nread < 0) {
- fclose (f);
- return;
+ if (server->machine.proc_statm [0]) {
+ strcpy (buffer, server->machine.proc_statm);
+ } else {
+ sprintf (input, "/proc/%d/statm", pid);
+
+ fd = open (input, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ input, strerror (errno));
+
+ nread = read (fd, buffer, BUFSIZ);
+ if (nread == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ input, strerror (errno));
+
+ buffer [nread] = 0;
+ strcpy (server->machine.proc_statm, buffer);
+ close (fd);
}
-
- input [nread] = 0;
-
- sscanf (input, "%ld %ld %ld",
+
+ sscanf (buffer, "%ld %ld %ld",
&buf->size, &buf->resident, &buf->share);
- fclose (f);
-
buf->flags = _glibtop_sysdeps_proc_mem;
}
diff --git a/sysdeps/linux/procsegment.c b/sysdeps/linux/procsegment.c
index d5ce5652..1ecefa2a 100644
--- a/sysdeps/linux/procsegment.c
+++ b/sysdeps/linux/procsegment.c
@@ -20,6 +20,7 @@
Boston, MA 02111-1307, USA. */
#include <config.h>
+#include <glibtop/error.h>
#include <glibtop/procsegment.h>
static const unsigned long _glibtop_sysdeps_proc_segment =
@@ -32,11 +33,10 @@ static const unsigned long _glibtop_sysdeps_proc_segment =
void
glibtop_get_proc_segment_s (glibtop *server, glibtop_proc_segment *buf,
- pid_t pid)
+ pid_t pid)
{
- char input [BUFSIZ], *tmp;
- int nread;
- FILE *f;
+ char buffer [BUFSIZ], input [BUFSIZ], *tmp;
+ int fd = 0, nread;
glibtop_init_r (&server, 0, 0);
@@ -48,24 +48,41 @@ glibtop_get_proc_segment_s (glibtop *server, glibtop_proc_segment *buf,
return;
}
- sprintf (input, "/proc/%d/stat", pid);
+ if (pid != server->machine.last_pid) {
+ server->machine.last_pid = pid;
+ server->machine.no_update = 0;
+ }
- f = fopen (input, "r");
- if (!f) return;
-
- nread = fread (input, 1, BUFSIZ, f);
-
- if (nread < 0) {
- fclose (f);
- return;
+ if (!server->machine.no_update) {
+ server->machine.proc_status [0] = 0;
+ server->machine.proc_statm [0] = 0;
+ server->machine.proc_stat [0] = 0;
}
-
- input [nread] = 0;
-
+
+ if (server->machine.proc_stat [0]) {
+ strcpy (buffer, server->machine.proc_stat);
+ } else {
+ sprintf (input, "/proc/%d/stat", pid);
+
+ fd = open (input, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ input, strerror (errno));
+
+ nread = read (fd, buffer, BUFSIZ);
+ if (nread == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ input, strerror (errno));
+
+ buffer [nread] = 0;
+ strcpy (server->machine.proc_stat, buffer);
+ close (fd);
+ }
+
/* This is from guile-utils/gtop/proc/readproc.c */
/* split into "PID (cmd" and "<rest>" */
- tmp = strrchr (input, ')');
+ tmp = strrchr (buffer, ')');
*tmp = '\0'; /* replace trailing ')' with NUL */
/* parse these two strings separately, skipping the leading "(". */
sscanf(tmp + 2, /* skip space after ')' too */
@@ -74,26 +91,28 @@ glibtop_get_proc_segment_s (glibtop *server, glibtop_proc_segment *buf,
"%*u %*u %lu %lu %lu", &buf->start_code,
&buf->end_code, &buf->start_stack);
- fclose (f);
-
- sprintf (input, "/proc/%d/statm", pid);
-
- f = fopen (input, "r");
- if (!f) return;
-
- nread = fread (input, 1, BUFSIZ, f);
-
- if (nread < 0) {
- fclose (f);
- return;
+ if (server->machine.proc_statm [0]) {
+ strcpy (buffer, server->machine.proc_statm);
+ } else {
+ sprintf (input, "/proc/%d/statm", pid);
+
+ fd = open (input, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ input, strerror (errno));
+
+ nread = read (fd, buffer, BUFSIZ);
+ if (nread == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ input, strerror (errno));
+
+ buffer [nread] = 0;
+ strcpy (server->machine.proc_statm, buffer);
+ close (fd);
}
- input [nread] = 0;
-
- sscanf (input, "%*d %*d %*d %ld %ld %ld %ld",
+ sscanf (buffer, "%*d %*d %*d %ld %ld %ld %ld",
&buf->trs, &buf->lrs, &buf->drs, &buf->dt);
- fclose (f);
-
buf->flags = _glibtop_sysdeps_proc_segment;
}
diff --git a/sysdeps/linux/procsignal.c b/sysdeps/linux/procsignal.c
index 6cd51788..7ae451a1 100644
--- a/sysdeps/linux/procsignal.c
+++ b/sysdeps/linux/procsignal.c
@@ -20,6 +20,7 @@
Boston, MA 02111-1307, USA. */
#include <glibtop.h>
+#include <glibtop/error.h>
#include <glibtop/procsignal.h>
static const unsigned long _glibtop_sysdeps_proc_signal =
@@ -31,9 +32,8 @@ static const unsigned long _glibtop_sysdeps_proc_signal =
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], input [BUFSIZ], *tmp;
+ int fd = 0, nread;
glibtop_init_r (&server, 0, 0);
@@ -45,24 +45,41 @@ glibtop_get_proc_signal_s (glibtop *server, glibtop_proc_signal *buf, pid_t pid)
return;
}
- sprintf (input, "/proc/%d/stat", pid);
+ if (pid != server->machine.last_pid) {
+ server->machine.last_pid = pid;
+ server->machine.no_update = 0;
+ }
- f = fopen (input, "r");
- if (!f) return;
-
- nread = fread (input, 1, BUFSIZ, f);
-
- if (nread < 0) {
- fclose (f);
- return;
+ if (!server->machine.no_update) {
+ server->machine.proc_status [0] = 0;
+ server->machine.proc_statm [0] = 0;
+ server->machine.proc_stat [0] = 0;
}
-
- input [nread] = 0;
-
+
+ if (server->machine.proc_stat [0]) {
+ strcpy (buffer, server->machine.proc_stat);
+ } else {
+ sprintf (input, "/proc/%d/stat", pid);
+
+ fd = open (input, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ input, strerror (errno));
+
+ nread = read (fd, buffer, BUFSIZ);
+ if (nread == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ input, strerror (errno));
+
+ buffer [nread] = 0;
+ strcpy (server->machine.proc_stat, buffer);
+ close (fd);
+ }
+
/* This is from guile-utils/gtop/proc/readproc.c */
/* split into "PID (cmd" and "<rest>" */
- tmp = strrchr (input, ')');
+ tmp = strrchr (buffer, ')');
*tmp = '\0'; /* replace trailing ')' with NUL */
/* parse these two strings separately, skipping the leading "(". */
sscanf(tmp + 2, /* skip space after ')' too */
@@ -72,7 +89,5 @@ glibtop_get_proc_signal_s (glibtop *server, glibtop_proc_signal *buf, pid_t pid)
&buf->signal, &buf->blocked, &buf->sigignore,
&buf->sigcatch);
- fclose (f);
-
buf->flags = _glibtop_sysdeps_proc_signal;
}
diff --git a/sysdeps/linux/procstate.c b/sysdeps/linux/procstate.c
index 48d83209..4a504961 100644
--- a/sysdeps/linux/procstate.c
+++ b/sysdeps/linux/procstate.c
@@ -20,6 +20,7 @@
Boston, MA 02111-1307, USA. */
#include <glibtop.h>
+#include <glibtop/error.h>
#include <glibtop/procstate.h>
#include <sys/stat.h>
@@ -33,10 +34,9 @@ static const unsigned long _glibtop_sysdeps_proc_state =
void
glibtop_get_proc_state_s (glibtop *server, glibtop_proc_state *buf, pid_t pid)
{
- char input [BUFSIZ], *tmp;
+ char buffer [BUFSIZ], input [BUFSIZ], *tmp;
struct stat statb;
- int nread;
- FILE *f;
+ int fd, nread;
glibtop_init_r (&server, 0, 0);
@@ -48,6 +48,12 @@ glibtop_get_proc_state_s (glibtop *server, glibtop_proc_state *buf, pid_t pid)
return;
}
+ server->machine.last_pid = pid;
+ server->machine.no_update = 0;
+ server->machine.proc_status [0] = 0;
+ server->machine.proc_statm [0] = 0;
+ server->machine.proc_stat [0] = 0;
+
sprintf (input, "/proc/%d/stat", pid);
/* IMPORTANT NOTICE: For security reasons it is extremely important
@@ -61,28 +67,34 @@ glibtop_get_proc_state_s (glibtop *server, glibtop_proc_state *buf, pid_t pid)
buf->uid = statb.st_uid;
buf->gid = statb.st_gid;
+
+ fd = open (input, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ input, strerror (errno));
+
+ nread = read (fd, buffer, BUFSIZ);
+ if (nread == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ input, strerror (errno));
- f = fopen (input, "r");
- if (!f) return;
-
- nread = fread (input, 1, BUFSIZ, f);
-
- if (nread < 0) {
- fclose (f);
- return;
- }
-
- input [nread] = 0;
+ buffer [nread] = 0;
+
+ server->machine.no_update = 1;
+ server->machine.last_pid = pid;
+ strcpy (server->machine.proc_stat, buffer);
/* This is from guile-utils/gtop/proc/readproc.c */
/* split into "PID (cmd" and "<rest>" */
- tmp = strrchr (input, ')');
+ tmp = strrchr (buffer, ')');
*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 (buffer, "%d (%39c", &pid, buf->cmd);
sscanf(tmp + 2, "%c", &buf->state); /* skip space after ')' too */
+ close (fd);
+
buf->flags = _glibtop_sysdeps_proc_state;
}
diff --git a/sysdeps/linux/proctime.c b/sysdeps/linux/proctime.c
index 7393215a..949deb2a 100644
--- a/sysdeps/linux/proctime.c
+++ b/sysdeps/linux/proctime.c
@@ -20,6 +20,7 @@
Boston, MA 02111-1307, USA. */
#include <glibtop.h>
+#include <glibtop/error.h>
#include <glibtop/proctime.h>
static const unsigned long _glibtop_sysdeps_proc_time =
@@ -33,9 +34,8 @@ static const unsigned long _glibtop_sysdeps_proc_time =
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], input [BUFSIZ], *tmp;
+ int fd = 0, nread;
glibtop_init_r (&server, 0, 0);
@@ -47,24 +47,41 @@ glibtop_get_proc_time_s (glibtop *server, glibtop_proc_time *buf, pid_t pid)
return;
}
- sprintf (input, "/proc/%d/stat", pid);
+ if (pid != server->machine.last_pid) {
+ server->machine.last_pid = pid;
+ server->machine.no_update = 0;
+ }
- f = fopen (input, "r");
- if (!f) return;
-
- nread = fread (input, 1, BUFSIZ, f);
-
- if (nread < 0) {
- fclose (f);
- return;
+ if (!server->machine.no_update) {
+ server->machine.proc_status [0] = 0;
+ server->machine.proc_statm [0] = 0;
+ server->machine.proc_stat [0] = 0;
}
-
- input [nread] = 0;
-
+
+ if (server->machine.proc_stat [0]) {
+ strcpy (buffer, server->machine.proc_stat);
+ } else {
+ sprintf (input, "/proc/%d/stat", pid);
+
+ fd = open (input, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ input, strerror (errno));
+
+ nread = read (fd, buffer, BUFSIZ);
+ if (nread == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ input, strerror (errno));
+
+ buffer [nread] = 0;
+ strcpy (server->machine.proc_stat, buffer);
+ close (fd);
+ }
+
/* This is from guile-utils/gtop/proc/readproc.c */
/* split into "PID (cmd" and "<rest>" */
- tmp = strrchr (input, ')');
+ tmp = strrchr (buffer, ')');
*tmp = '\0'; /* replace trailing ')' with NUL */
/* parse these two strings separately, skipping the leading "(". */
sscanf(tmp + 2, /* skip space after ')' too */
@@ -73,7 +90,5 @@ glibtop_get_proc_time_s (glibtop *server, glibtop_proc_time *buf, pid_t pid)
&buf->utime, &buf->stime, &buf->cutime, &buf->cstime,
&buf->timeout, &buf->it_real_value, &buf->start_time);
- fclose (f);
-
buf->flags = _glibtop_sysdeps_proc_time;
}
diff --git a/sysdeps/linux/procuid.c b/sysdeps/linux/procuid.c
index 783589a1..0c25bddd 100644
--- a/sysdeps/linux/procuid.c
+++ b/sysdeps/linux/procuid.c
@@ -20,6 +20,7 @@
Boston, MA 02111-1307, USA. */
#include <glibtop.h>
+#include <glibtop/error.h>
#include <glibtop/procuid.h>
static const unsigned long _glibtop_sysdeps_proc_uid =
@@ -37,9 +38,8 @@ static const unsigned long _glibtop_sysdeps_proc_uid =
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], input [BUFSIZ], *tmp;
+ int fd = 0, nread;
glibtop_init_r (&server, 0, 0);
@@ -51,23 +51,40 @@ glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid)
return;
}
- sprintf (input, "/proc/%d/status", pid);
-
- f = fopen (input, "r");
- if (!f) return;
+ if (pid != server->machine.last_pid) {
+ server->machine.last_pid = pid;
+ server->machine.no_update = 0;
+ }
- nread = fread (input, 1, BUFSIZ, f);
-
- if (nread < 0) {
- fclose (f);
- return;
+ if (!server->machine.no_update) {
+ server->machine.proc_status [0] = 0;
+ server->machine.proc_statm [0] = 0;
+ server->machine.proc_stat [0] = 0;
}
+
+ if (server->machine.proc_status [0]) {
+ strcpy (buffer, server->machine.proc_status);
+ } else {
+ sprintf (input, "/proc/%d/status", pid);
+
+ fd = open (input, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ input, strerror (errno));
+
+ nread = read (fd, buffer, BUFSIZ);
+ if (nread == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ input, strerror (errno));
- input [nread] = 0;
+ buffer [nread] = 0;
+ strcpy (server->machine.proc_status, buffer);
+ close (fd);
+ }
/* Search substring 'Pid:' */
- tmp = strstr (input, "Pid:");
+ tmp = strstr (buffer, "Pid:");
if (tmp == NULL) return;
@@ -75,26 +92,30 @@ glibtop_get_proc_uid_s (glibtop *server, glibtop_proc_uid *buf, pid_t pid)
"Gid: %u %u %*u %*u\n", &buf->pid, &buf->ppid,
&buf->uid, &buf->euid, &buf->gid, &buf->egid);
- fclose (f);
-
- sprintf (input, "/proc/%d/stat", pid);
-
- f = fopen (input, "r");
- if (!f) return;
-
- nread = fread (input, 1, BUFSIZ, f);
-
- if (nread < 0) {
- fclose (f);
- return;
+ if (server->machine.proc_stat [0]) {
+ strcpy (buffer, server->machine.proc_stat);
+ } else {
+ sprintf (input, "/proc/%d/stat", pid);
+
+ fd = open (input, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ input, strerror (errno));
+
+ nread = read (fd, buffer, BUFSIZ);
+ if (nread == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ input, strerror (errno));
+
+ buffer [nread] = 0;
+ strcpy (server->machine.proc_stat, buffer);
+ close (fd);
}
- input [nread] = 0;
-
/* This is from guile-utils/gtop/proc/readproc.c */
/* split into "PID (cmd" and "<rest>" */
- tmp = strrchr (input, ')');
+ tmp = strrchr (buffer, ')');
*tmp = '\0'; /* replace trailing ')' with NUL */
/* parse these two strings separately, skipping the leading "(". */
sscanf(tmp + 2, /* skip space after ')' too */
@@ -116,7 +137,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;
}
diff --git a/sysdeps/linux/swap.c b/sysdeps/linux/swap.c
index 73ee5000..fd8b29f7 100644
--- a/sysdeps/linux/swap.c
+++ b/sysdeps/linux/swap.c
@@ -20,18 +20,22 @@
Boston, MA 02111-1307, USA. */
#include <config.h>
+#include <glibtop/error.h>
#include <glibtop/swap.h>
static unsigned long _glibtop_sysdeps_swap =
(1 << GLIBTOP_SWAP_TOTAL) + (1 << GLIBTOP_SWAP_USED) +
(1 << GLIBTOP_SWAP_FREE);
+#define FILENAME "/proc/meminfo"
+
/* Provides information about swap usage. */
void
glibtop_get_swap_s (glibtop *server, glibtop_swap *buf)
{
- FILE *f;
+ char buffer [BUFSIZ];
+ int fd = 0, ret;
glibtop_init_r (&server, 0, 0);
@@ -39,11 +43,29 @@ glibtop_get_swap_s (glibtop *server, glibtop_swap *buf)
buf->flags = _glibtop_sysdeps_swap;
- f = fopen ("/proc/meminfo", "r");
- if (!f) return;
+#ifdef GLIBTOP_CACHE_OPEN
+ fd = server->machine.fd_meminfo;
+#endif
+ if (fd == 0) {
+ fd = open (FILENAME, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ FILENAME, strerror (errno));
+ } else {
+ lseek (fd, 0, SEEK_SET);
+ }
+
+ ret = read (fd, buffer, BUFSIZ);
+ if (ret == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ FILENAME, strerror (errno));
- fscanf (f, "%*[^\n]\n%*[^\n]\nSwap: %lu %lu %lu\n",
+ sscanf (buffer, "%*[^\n]\n%*[^\n]\nSwap: %lu %lu %lu\n",
&buf->total, &buf->used, &buf->free);
- fclose (f);
+#ifdef GLIBTOP_CACHE_OPEN
+ server->machine.fd_meminfo = fd;
+#else
+ close (fd);
+#endif
}
diff --git a/sysdeps/linux/uptime.c b/sysdeps/linux/uptime.c
index 26dd355b..17b263cb 100644
--- a/sysdeps/linux/uptime.c
+++ b/sysdeps/linux/uptime.c
@@ -20,17 +20,21 @@
Boston, MA 02111-1307, USA. */
#include <config.h>
+#include <glibtop/error.h>
#include <glibtop/uptime.h>
static unsigned long _glibtop_sysdeps_uptime =
(1 << GLIBTOP_UPTIME_UPTIME) + (1 << GLIBTOP_UPTIME_IDLETIME);
+#define FILENAME "/proc/uptime"
+
/* Provides uptime and idle time. */
void
glibtop_get_uptime_s (glibtop *server, glibtop_uptime *buf)
{
- FILE *f;
+ int fd, ret;
+ char buffer [BUFSIZ];
glibtop_init_r (&server, 0, 0);
@@ -38,10 +42,17 @@ glibtop_get_uptime_s (glibtop *server, glibtop_uptime *buf)
buf->flags = _glibtop_sysdeps_uptime;
- f = fopen ("/proc/uptime", "r");
- if (!f) return;
+ fd = open (FILENAME, O_RDONLY);
+ if (fd == -1)
+ glibtop_error_r (server, "open (%s): %s",
+ FILENAME, strerror (errno));
+
+ ret = read (fd, buffer, BUFSIZ);
+ if (ret == -1)
+ glibtop_error_r (server, "read (%s): %s",
+ FILENAME, strerror (errno));
- fscanf (f, "%lf %lf\n", &buf->uptime, &buf->idletime);
+ sscanf (buffer, "%lf %lf\n", &buf->uptime, &buf->idletime);
- fclose (f);
+ close (fd);
}