Compare commits

..

73 Commits

Author SHA1 Message Date
Martin Baulig
79f5a9c667 Importing FreeBSD port of libgtop from Josh Sled. 1998-08-06 23:34:50 +00:00
Martin Baulig
864867aeeb Initial revision 1998-08-06 23:34:50 +00:00
Martin Baulig
8750ff351e Bug fixes. 1998-08-06 22:55:22 +00:00
Martin Baulig
bfcc8c3944 Enabled slave-server again. 1998-08-06 22:55:02 +00:00
Martin Baulig
bf19661382 Added 2 seconds delay to give child time to start up. 1998-08-06 22:54:46 +00:00
Martin Baulig
20016762a6 New checks.
1998-08-06  Martin Baulig  <martin@home-of-linux.org>

	* configure.in (HAVE_SOCKETS, HAVE_SOCKADDR_SUN_LEN): New checks.
1998-08-06 22:53:45 +00:00
Martin Baulig
0a7bd78704 Using GLIBTOP_GUILE' instead of HAVE_GUILE' so one should be able to use
1998-08-06  Martin Baulig  <martin@home-of-linux.org>

	* include/glibtop/*.h: Using `GLIBTOP_GUILE' instead of `HAVE_GUILE'
	so one should be able to use libgtop without guile in an application
	even if guile is installed.

	* sysdeps/common/mountlist.c: Fixed some `xstrdup' problems.

	* lib/open.c: Now correctly reading server features for
	`GLIBTOP_METHOD_PIPE'.

	* sysdeps/freebsd: New directory.
1998-08-06 21:57:45 +00:00
Martin Baulig
2e454140f1 Added pagein' and pageout'.
1998-08-01  Martin Baulig  <martin@home-of-linux.org>

	* include/glibtop/swap.h (glibtop_swap): Added `pagein' and `pageout'.

	* kernel/table20/table.h: Removed.
	* kernel/table21/table.h: Removed.
	* kernel/table.h: Added. Things are now binary compatible between
	both kernel versions.
1998-08-01 22:03:11 +00:00
Martin Baulig
fc506344ea Added.
1998-07-30  Martin Baulig  <martin@home-of-linux.org>

	* acconfig.h (u_int64_t, int64_t): Added.
1998-07-30 18:08:19 +00:00
Martin Baulig
e7f5588ee9 Using correct `(1 << GLIBTOP_SYSDEPS_<feature>)' in call to
1998-07-30  Martin Baulig  <martin@home-of-linux.org>

	* lib/lib.awk: Using correct `(1 << GLIBTOP_SYSDEPS_<feature>)'
	in call to `glibtop_init_r'.
1998-07-30 17:56:02 +00:00
Martin Baulig
b55ee6117f New check.
1998-07-30  Martin Baulig  <martin@home-of-linux.org>

	* configure.in (GNOME_LIBGTOP_TYPES): New check.
1998-07-30 17:52:29 +00:00
Martin Baulig
902b6a8f16 Using u_int64_t' instead of unsigned long' and `long' to avoid problems
1998-07-30  Martin Baulig  <martin@home-of-linux.org>

	* include/glibtop/*.h: Using `u_int64_t' instead of `unsigned long'
	and `long' to avoid problems when client is on a 32bit system and
	the server on a 64bit system.
1998-07-30 14:24:19 +00:00
Martin Baulig
d18a6cf2ce Removed debugging instruction. 1998-07-30 14:03:13 +00:00
Martin Baulig
8ced0f5889 Using `0xffffffff' instead of -1 as error code for inet_addr () since on
1998-07-30  Martin Baulig  <martin@home-of-linux.org>

	* sysdeps/common/gnuslib.c: Using `0xffffffff' instead of -1
	as error code for inet_addr () since on 64bit systems,
	`inet_addr (some_error) != (INET_ADDR) -1'.
1998-07-30 12:54:00 +00:00
Martin Baulig
a33b97ef9d Removed gnomesupport.h. 1998-07-30 10:42:34 +00:00
Martin Baulig
3c3118521d Only defining guile stuff if we really have guile.
1998-07-30  Martin Baulig  <martin@home-of-linux.org>

	* configure.in: Only defining guile stuff if
	we really have guile.
1998-07-30 08:30:40 +00:00
Martin Baulig
f07551a43d New file.
1998-07-29  Martin Baulig  <martin@home-of-linux.org>

	* guile/ChangeLog: New file.

	* features.def: New format - now includes type of return value
	and parameters.

	* lib/lib.awk: Changed to use new `features.def'.
	* sysdeps/guile/guile.awk: Dito;
	* sysdeps/guile/names/guile-names.awk: Dito.

	* libgtopConf.sh.in: Added
	`LIBGTOP_NAMES_LIBS', `LIBGTOP_NAMES_INCS',
	`LIBGTOP_GUILE_NAMES_LIBS', `LIBGTOP_GUILE_NAMES_INCS',
	`LIBGTOP_MAJOR_VERSION', `LIBGTOP_MINOR_VERSION'
	`LIBGTOP_VERSION', `libgtop_sysdeps_dir'.

	* acinclude.m4 (AC_LC_SYSDEPS): Removed since this has been
	replaced with `GNOME_LIBGTOP_SYSDEPS' long ago.

	* LIBGTOP-VERSION: New file.

	* */Makefile.am (INCLUDES): Removed; now defined in `configure.in'.

	* sysdeps/names/mountlist.c: New file.

	* lib/{init, open}.c (GTOP_SERVER): Renamed to `LIBGTOP_SERVER'.

	* configure.in (INCLUDES): Added definition.
	(libgtop_want_names): Always true; `libgtop_names.la' is now
	always created since some other programs rely upon it - but
	have to use `LIBGTOP_NAMES_LIBS' and `LIBGTOP_NAMES_INCS' to
	use it in your application.
	(libgtop_want_guile_names): Always true; but you have to use
	`LIBGTOP_GUILE_NAMES_LIBS' and `LIBGTOP_GUILE_NAMES_INCS' to
	use it in your application.
	(LIBGTOP_LIBS): Removed `-lgtop_names' and `-lgtop_guile_names'.
	(LIBGTOP_NAMES_LIBS): New variable. Use it to link your
	application with the names interface.
	(LIBGTOP_NAMES_INCS): New variable. Also #defines `GLIBTOP_NAMES'
	which is now required if your application wants to use the names
	interface.
	(LIBGTOP_GUILE_NAMES_LIBS): New variable. Use it to link your
	application with the guile names interface.
	(LIBGTOP_GUILE_NAMES_INCS): New variable. Also #defines
	`GLIBTOP_NAMES' and `GLIBTOP_GUILE_NAMES' which are now required
	if your application wants to use the guile names interface.
1998-07-29 22:01:31 +00:00
Martin Baulig
37eb76e767 *** empty log message *** 1998-07-29 21:39:50 +00:00
Martin Baulig
e2196888ca New files.
1998-07-29  Martin Baulig  <martin@home-of-linux.org>

	* dynamic.c, dynamic_names.c: New files.

	* Makefile.am: New file. Creates `libgtop.so' and
	`libnames.so' which will be installed in
	`$(datadir)/guile/libgtop'; just do a
	`(use-modules (libgtop libgtop) (libgtop names))' in
	guile to use them.
1998-07-29 21:36:49 +00:00
Martin Baulig
8b9b984701 Using #include "*.h"' instead of #include "proc/*.h"'. 1998-07-29 13:01:25 +00:00
Martin Baulig
aa6d16e47b Added `all_fs' parameter.
1998-07-24  Martin Baulig  <martin@home-of-linux.org>

	* sysdeps/common/mountlist.c (glibtop_get_mountlist_s):
	Added `all_fs' parameter.
1998-07-24 14:43:16 +00:00
Martin Baulig
f3f051ecba Replaced glibtop_init_r' with glibtop_init_s'.
1998-07-24  Martin Baulig  <martin@home-of-linux.org>

	* sysdeps/{kernel, linux}/*.c: Replaced `glibtop_init_r' with
	`glibtop_init_s'.

	* sysdeps/sun4/open.c (glibtop_init_p): Removed `program_name'
	parameter.

	* sysdeps/osf1/glibtop_suid.h: New file.

	* sysdeps/osf1/glibtop_server.h: Now correctly using
	`(1 << GLIBTOP_SYSDEPS_*)' instead of `GLIBTOP_SYSDEPS_*'.

	* sysdeps/osf1/open_suid.c (glibtop_init_p): New function.

	* sysdeps/osf1/proc*.c: Done some more work here.
1998-07-24 10:26:42 +00:00
Manish Vachharajani
51c5c3ac22 Remove init.c from libgtop_sysdeps_la_SOURCES 1998-07-24 07:46:10 +00:00
Martin Baulig
61c262dd7e Changed type for signal', blocked', sigignore' and sigcatch' to
1998-07-23  Martin Baulig  <martin@home-of-linux.org>

	* include/glibtop/procsignal.h (glibtop_proc_signal):
	Changed type for `signal', `blocked', `sigignore' and
	`sigcatch' to `unsigned long long'.
1998-07-23 18:12:04 +00:00
Martin Baulig
954a78f200 New file.
1998-07-22  Martin Baulig  <martin@home-of-linux.org>

	* include/glibtop/fsusage.h: New file.

	* features.def: Added new feature `fsusage'.

	* sysdeps/common/fsusage.c (glibtop_get_fsusage_s): New function.
	(get_fs_usage): Declared as `static'.

	* sysdeps/names/fsusage.c: New file.
1998-07-22 22:56:09 +00:00
Martin Baulig
a90bffbbf6 *** empty log message *** 1998-07-22 20:59:17 +00:00
Martin Baulig
6bf243c901 New file.
1998-07-22  Martin Baulig  <martin@home-of-linux.org>

	* include/glibtop/mountlist.h: New file.

	* features.def: Added new feature `mountlist'.

	* sysdeps/common/mountlist.c (glibtop_get_mountlist_s): New function.
	(read_filesystem_list): Declared as `static'.
1998-07-22 20:52:42 +00:00
Martin Baulig
dd5c4a716b New file.
1998-07-22  Martin Baulig  <martin@home-of-linux.org>

	* mountlist.c: New file.
1998-07-22 20:47:17 +00:00
Martin Baulig
0dc0c2d7f0 Added fsusage.[ch]' and mountlist.[ch]'.
1998-07-22  Martin Baulig  <martin@home-of-linux.org>

	* sysdeps/common/Makefile.am (libgtop_common_la_SOURCES):
	Added `fsusage.[ch]' and `mountlist.[ch]'.

	* include/glibtop/signal.h: New file.

	* sysdeps/{kernel, linux, osf1, sun4, stub}/siglist.c: New files.
1998-07-22 17:21:59 +00:00
Martin Baulig
a584809b1c Really removing this stuff. 1998-07-22 17:15:22 +00:00
Martin Baulig
5e97af535f Summary of this long ChangeLog:
* Splitted `libgtop_sysdeps.la' into `libgtop_sysdeps.la' and
   `libgtop_sysdeps_suid.la'.

   Everything that needs to be suid/sgid is in `libgtop_sysdeps_suid.la'
   and the rest in `libgtop_sysdeps.la'.

   The functions from `libgtop_sysdeps_suid.la' have the `_p' prefix and
   the ones from `libgtop_sysdeps.la' the `_s' prefix.

   The suid library uses `glibtop_open_p' and `glibtop_close_p', the
   normal one `glibtop_init_s' (found in lib/init.c), `glibtop_open_s'
   and `glibtop_close_s'.

 * Added `libgtop_suid_common.la' containing stuff from sysdeps/common
   that is required from the suid server (currently everything from
   error.c and xmalloc.c).

   This means, we can add some more stuff to `libgtop_common.la' without
   the risk that it may be dangerous in the suid server.

 * The ``library order'' is much clearer now:

   -> `libgtop.la' (from lib/) contains user-level stuff;
      all functions except `glibtop_init_r' have the `_l'
      suffix.

   -> `libgtop_common.la' (from sysdeps/common/) contains stuff
      that is common among the sysdeps directories.
      use anything from `libgtop_sysdeps.la' and
      `libgtop_sysdeps_suid.la'.

   -> `libgtop_sysdeps.la' (from sysdeps/<sysdeps_dir>/) contains
      everything from the sysdeps directory that doesn't need to
      be suid/sgid.

   -> `libgtop_suid_common.la' (from sysdeps/common/) is used from
      the suid server instead of `libgtop_common.la'.

   -> `libgtop_sysdeps_suid.la' (from sysdeps/<sysdeps_dir>/) contains
      everything from the sysdeps directory that needs to be in the
      suid server.

 * To summarize: the server is linked only with functions that need
   to be suid and everything else is linked only with functions that
   do not need to be suid.

Martin

1998-07-22  Martin Baulig  <martin@home-of-linux.org>

	* lib/init.c (glibtop_init_s): Added this init function of
	the sysdeps directory `libgtop_sysdeps.la'.

	* lib/open.c (glibtop_open_l): Unconditionally calling
	`glibtop_init_s' after server initialization.

	* lib/lib.awk: Removed references to functions from
	`libgtop_sysdeps_suid.la' to avoid undefined symbols.

	* sysdeps/stub/open.c (glibtop_open_s): Renamed this
	function from `glibtop_open_r'.

	* sysdeps/stub/close.c (glibtop_close_s): Renamed this
	function from `glibtop_close_l'.

	* sysdeps/kernel/open.c (glibtop_open_s): Renamed this
	function from `glibtop_open_r'.

	* sysdeps/kernel/close.c (glibtop_close_s): Renamed this
	function from `glibtop_close_l'.

	* sysdeps/linux/open.c (glibtop_open_s): Renamed this
	function from `glibtop_open_r'.

	* sysdeps/linux/close.c (glibtop_close_s): Renamed this
	function from `glibtop_close_l'.

	* sysdeps/osf1/Makefile.am (lib_LTLIBRARIES): Added
	`libgtop_sysdeps_suid.la' for the suid server.

	* sysdeps/osf1/open_suid.c (glibtop_open_p): New file.
	Contains all stuff that was formerly in `open.c'.

	* sysdeps/osf1/open.c: Moved everything from here into
	the new file `open_suid.c'.

	* sysdeps/osf1/open.c (glibtop_open_s): New function.

	* sysdeps/osf1/close_suid.c (glibtop_close_p): New file.

	* sysdeps/osf1/close.c (glibtop_close_s): New function.

	* sysdeps/osf1/*.c: Using the new init, open and close
	functions.

	* sysdeps/sun4/Makefile.am (lib_LTLIBRARIES): Added
	`libgtop_sysdeps_suid.la' for the suid server.

	* sysdeps/sun4/nosuid.c (glibtop_open_s, glibtop_close_s): New file

	* sysdeps/sun4/*.c: All functions now have the `_p' suffix.

	* sysdeps/common/Makefile.am (lib_LTLIBRARIES): Added
	`libgtop_suid_common.la' which only contains stuff that is
	needed in the suid parts.

	* sysdeps/common/xmalloc.c: Using `glibtop_error_io_r' instead
	of `glibtop_error_r'.

	* sysdeps/{kernel, linux, osf1, sun4, stub}/init.c: Removed.
	`glibtop_init_s' has been moved into `lib/init.c' since it's the
	same in all the sysdeps directories.

	* src/server/main.c: It is now an error to request a feature that
	does not need the suid server.

	* src/proxy: Removed.
1998-07-22 09:26:43 +00:00
Martin Baulig
7efcda3082 New file.
1998-07-21  Martin Baulig  <martin@home-of-linux.org>

	* doc/ChangeLog: New file.

	* sysdeps/kernel/*.c: Using `glibtop_error_io_r' instead
	of `glibtop_error_r'.

	* sysdeps/kernel/proclist.c: Now using the table () function, too.
	This means that currently the table () function can fetch all
	information for libgtop and you can even unmount /proc !
1998-07-21 21:13:13 +00:00
Martin Baulig
5a1fa089f3 Added note that this file is currently out of date and a link to the
1998-07-21  Martin Baulig  <martin@home-of-linux.org>

	* gnome-hackers.sgml: Added note that this file is
	currently out of date and a link to the documentation
	of the table () function.
1998-07-21 21:05:57 +00:00
Martin Baulig
a129a83c45 New file - basic documentation for the table () system call.
1998-07-21  Martin Baulig  <martin@home-of-linux.org>

	* table.sgml: New file - basic documentation for the
	table () system call.
1998-07-21 20:39:01 +00:00
Martin Baulig
65fbcf1ea3 New directory for 2.0.xx kernels.
1998-07-21  Martin Baulig  <martin@home-of-linux.org>

	* table20: New directory for 2.0.xx kernels.

	* table21: New directory for 2.1.xx kernels.

	* *: Moved into `table20' and `table21'.
1998-07-21 17:25:09 +00:00
Martin Baulig
d145edb435 The table () system call for 2.1.xx kernels. 1998-07-21 17:16:23 +00:00
Martin Baulig
fc2d1f07c3 Initial revision 1998-07-21 17:16:23 +00:00
Martin Baulig
694ad7adb7 The table () system call for 2.0.xx kernels. 1998-07-21 17:15:45 +00:00
Martin Baulig
d8a7175820 Initial revision 1998-07-21 17:15:45 +00:00
Martin Baulig
fe56feb875 Importing from procps-1.2.7.
This library is also used in gnome-utils/gtop/proc so if we change
it to use libgtop it can be used both for procps and gtop.
1998-07-18 16:15:56 +00:00
Martin Baulig
5e9d34c91a Initial revision 1998-07-18 16:15:56 +00:00
Martin Baulig
0e086aef25 Added `GLIBTOP_METHOD_PIPE' again.
1998-07-18  Martin Baulig  <martin@home-of-linux.org>

	* lib/{init, open}.c: Added `GLIBTOP_METHOD_PIPE' again.

	* src/server/main.c: Removed gettext stuff.
1998-07-18 16:09:42 +00:00
Martin Baulig
540385da7e Using library functions with '_l' prefix instead of directly calling
1998-07-17  Martin Baulig  <baulig@Stud.Informatik.uni-trier.de>

	* sysdeps/common/sysdeps.c (glibtop_get_sysdeps_r): Using
	library functions with '_l' prefix instead of directly calling
	sysdeps code with '_r' prefix. This is necessary for client/server
	mode.
1998-07-17 17:26:22 +00:00
Martin Baulig
540cd68691 Now correctly using `(1 << GLIBTOP_SYSDEPS_*)' instead of
1998-07-17  Martin Baulig  <baulig@Stud.Informatik.uni-trier.de>

	* lib/lib.awk (glibtop_get_*): Now correctly using
	`(1 << GLIBTOP_SYSDEPS_*)' instead of `GLIBTOP_SYSDEPS_*'.
1998-07-17 17:21:00 +00:00
Martin Baulig
c41d6e5a77 Added implementation of that feature.
1998-07-17  Martin Baulig  <baulig@Stud.Informatik.uni-trier.de>

	* sysdeps/sun4/proclist.c (glibtop_get_proclist_p): Added
	implementation of that feature.

	* sysdeps/sun4/proc_{uid,state}.c: Now working quite well.

	* sysdeps/sun4/proc_{mem,time,signal,kernel,segment}.c: Added
	some basic implementation; this isn't really working yet.
1998-07-17 16:40:02 +00:00
Martin Baulig
74ca45f795 Applied patch from Albert K T Hui <avatar@deva.net> for glibc 2.1.
1998-07-17  Martin Baulig  <baulig@Stud.Informatik.uni-trier.de>

	* sysdeps/linux/sem_limits.c: Applied patch from Albert K T Hui
	<avatar@deva.net> for glibc 2.1.
1998-07-17 13:56:37 +00:00
Martin Baulig
5f4131f248 New file. Imported from top 3.4.
1998-07-15  Martin Baulig  <martin@home-of-linux.org>

	* sysdeps/sun4/loadavg.h: New file. Imported from top 3.4.

	* sysdeps/sun4/uptime.c (glibtop_get_uptime_p): Added
	implementation of that function using glibtop_get_cpu ().

	* sysdeps/sun4/loadavg.c (glibtop_get_loadavg_p): Added
	implementation of that feature.

	* sysdeps/sun4/{shm_limits.c, msg_limits.c, shm_limits.c}:
	Added implementation of this features.
1998-07-14 23:30:36 +00:00
Martin Baulig
4bfef8c254 Imported the wrong file, so removing it again. 1998-07-14 23:19:19 +00:00
Martin Baulig
f77eba3d57 Importing from top-3.4. 1998-07-14 22:57:20 +00:00
Martin Baulig
f18952a9d8 Initial revision 1998-07-14 22:57:20 +00:00
Martin Baulig
16cb163bb0 Importing from top 3.4 1998-07-14 22:42:16 +00:00
Martin Baulig
f8bdfa9a43 Fixed wrong type which caused a core dump. 1998-07-14 20:24:55 +00:00
Martin Baulig
61f887fc67 Added some comments.
1998-07-14  Martin Baulig  <baulig@Stud.Informatik.uni-trier.de>

	* src/daemon/server_config.h.in: Added some comments.

	* src/daemon/server_config.pl: New file. This is a script you can use
	to create `server_config.h'. It will query you for some configuration
	options.
1998-07-14 20:06:37 +00:00
Martin Baulig
9fd8936e93 Replaced this test with explicit test for gawk' and awk' since `mawk'
1998-07-14  Martin Baulig  <baulig@Stud.Informatik.uni-trier.de>

	* configure.in (AC_PROG_AWK): Replaced this test with explicit test
	for `gawk' and `awk' since `mawk' doesn't work.
1998-07-14 10:31:17 +00:00
Martin Baulig
ef693a93bc Doing correct server initialization using `glibtop_set_parameter_l' and
1998-07-14  Martin Baulig  <martin@home-of-linux.org>

	* src/daemon/gnuserv.c: Doing correct server initialization
	using `glibtop_set_parameter_l' and `glibtop_init_r'.

	* src/daemon/main.c: Removed call to `glibtop_init_r'.

	* lib/open.c (glibtop_open_l): We now call the open function
	of the sysdeps directory (glibtop_open_r) for server method
	`GLIBTOP_METHOD_DIRECT'.

	* sysdeps/{linux, sun4, stub}/open.c: No longer `memset'
	server to zero.
1998-07-14 08:36:23 +00:00
Martin Baulig
aa04293fc3 Forgot to commit this file yesterday. 1998-07-13 23:29:31 +00:00
Martin Baulig
345a657d2c New file.
1998-07-14  Martin Baulig  <martin@home-of-linux.org>

	* src/daemon/slave.c: New file.

	* src/daemon/*.c: Done some more work on the daemon.

	* sysdeps/common/gnuslib.c: Removed IPC stuff.

	* include/glibtop/gnuserv.h: Removed IPC stuff.

	* include/glibtop/command.h (glibtop_response_unit): Added
	typedef for `struct _glibtop_response_unit'.

	* lib/Makefile.am: Using `$(top_srcdir)/features.def'
	instead of `$(top_builddir)/features.def'.

	* sysdeps/guile/Makefile.am: Using `$(top_srcdir)/features.def'
	instead of `$(top_builddir)/features.def'.

	* sysdeps/guile/names/Makefile.am: Dito.

	* sysdeps/stub/*.c: changed suffix of all functions
	from '_s' to '_r'; see also ChangeLog entry from Jun 6.
1998-07-13 23:27:10 +00:00
Martin Baulig
da7d7ff116 Fixed type in debugging statement. 1998-07-13 23:21:40 +00:00
Martin Baulig
c5263a881e Using `$(top_srcdir)/features.def' instead of
1998-07-14  Martin Baulig  <martin@home-of-linux.org>

	* sysdeps/guile/Makefile.am: Using `$(top_srcdir)/features.def'
	instead of `$(top_builddir)/features.def'.

	* sysdeps/guile/names/Makefile.am: Dito.
1998-07-13 22:37:05 +00:00
Martin Baulig
49adb94af0 Only changed indentation. 1998-07-13 22:34:23 +00:00
Martin Baulig
b991ecaf9a changed suffix of all functions from '_s' to '_r'; see also ChangeLog
1998-07-14  Martin Baulig  <martin@home-of-linux.org>

	* sysdeps/stub/*.c: changed suffix of all functions
	from '_s' to '_r'; see also ChangeLog entry from Jun 6.
1998-07-13 22:32:00 +00:00
Martin Baulig
2c8ae09776 Added `server_config.h'. 1998-07-13 15:04:40 +00:00
Martin Baulig
8ecb7f296e Removed from CVS. This is a config file which needs to be edited.
1998-07-13  Martin Baulig  <baulig@merkur.uni-trier.de>

	* src/daemon/server_config.h: Removed from CVS.
	This is a config file which needs to be edited.

	* src/daemon/server_config.h.in: Added. This is just
	an example for `server_config.h'.
1998-07-13 15:02:20 +00:00
Martin Baulig
3477d30dc5 Basically did some work on the new daemon. Things are still unstable.
1998-07-13  Martin Baulig  <martin@home-of-linux.org>

	* glibtop.h: Fixed invocation of `glibtop_close_r'.

	* sysdeps/linux/procstate.c: Added missing `fclose'.

	* include/glibtop/gnuserv.h (UNIX_DOMAIN_SOCKETS): Defining.

	* include/glibtop/open.h (GLIBTOP_METHOD_UNIX): Added.

	* lib/init.c: Added new method `GLIBTOP_METHOD_UNIX'.

	* lib/open.c: Added support for Unix Domain Sockets.

	* lib/close.c: Now closing inet and unix connections.

	* lib/parameter.c (glibtop_set_parameter_l): You can now
	set the `method' and `features' fields.

	* src/daemon/server_config.h: New file.

	* src/daemon/{gnuserv.c, main.c}: More work on the server.
1998-07-13 00:39:46 +00:00
Martin Baulig
f30dfecaf7 Changed indentation, removed some lines already commented out.
Enclosed debugging statement in '#ifdef DEBUG'.
1998-07-13 00:18:44 +00:00
Martin Baulig
8a666eb5a4 Fixed unbalanced '#endif'. 1998-07-12 14:29:30 +00:00
Martin Baulig
61071132bf Changed indentation using
'indent -br -ce -sc -pcs -cs -bs -i8 -bad -bap -fca '
1998-07-12 14:24:49 +00:00
Martin Baulig
b177c3930d Changed indentation using
'indent -br -ce -sc -pcs -cs -bs -i8 -bad -bap -fca'
1998-07-12 14:22:45 +00:00
Martin Baulig
eb8d28b694 Removed `proxy'. This directory is considered obsolete and will be removed
1998-07-10  Martin Baulig  <martin@home-of-linux.org>

	* src/Makefile.am (SUBDIRS): Removed `proxy'. This directory
	is considered obsolete and will be removed soon.
1998-07-09 23:03:27 +00:00
Martin Baulig
0b4f757b2b using functions from `xmalloc.c'.
1998-07-06  Martin Baulig  <martin@home-of-linux.org>

	* sysdeps/common/mountlist.c: using functions from `xmalloc.c'.

	* sysdeps/common/error.c: all functions now accept NULL as
	`server' argument.
1998-07-07 00:10:49 +00:00
Martin Baulig
2aa20e2060 New macros.
1998-07-06  Martin Baulig  <martin@home-of-linux.org>

	* acconfig.h (AFS, MOUNTED_FREAD, MOUNTED_FREAD_FSTYP,
	MOUNTED_GETFSSTAT, MOUNTED_GETMNT, MOUNTED_GETMNTENT1,
	MOUNTED_GETMNTENT2, MOUNTED_GETMNTINFO, MOUNTED_LISTMNTENT,
        MOUNTED_VMOUNT, STAT_STATFS3_OSF1, STAT_READ_FILSYS,
        STAT_STATFS2_BSIZE, STAT_STATFS2_FSIZE, STAT_STATFS2_FS_DATA,
        STAT_STATFS4, STAT_STATVFS, STATFS_TRUNCATES_BLOCK_COUNTS):
        New macros.

	* configure.in: added GNOME_FILEUTILS_CHECKS.
1998-07-06 23:00:48 +00:00
Martin Baulig
7d8ff8f72e *** empty log message *** 1998-07-06 22:51:12 +00:00
Martin Baulig
576dde394a using g_malloc, g_realloc and g_strdup.
* mountlist.c: using g_malloc, g_realloc and g_strdup.
1998-07-06 22:48:25 +00:00
271 changed files with 9816 additions and 2745 deletions

View File

@@ -1,8 +1,6 @@
Makefile
Makefile.in
aclocal.m4
alpha-dec-osf1
autoh31167
config.cache
config.h
config.h.in
@@ -24,3 +22,6 @@ stamp-h
sun4
sun4sol2
support
i386-freebsd
alpha-dec-osf3.0
i686-pc-linux-gnu-linux

369
ChangeLog
View File

@@ -1,3 +1,372 @@
1998-08-06 Martin Baulig <martin@home-of-linux.org>
* configure.in (HAVE_SOCKETS, HAVE_SOCKADDR_SUN_LEN): New checks.
* include/glibtop/*.h: Using `GLIBTOP_GUILE' instead of `HAVE_GUILE'
so one should be able to use libgtop without guile in an application
even if guile is installed.
* sysdeps/common/mountlist.c: Fixed some `xstrdup' problems.
* lib/open.c: Now correctly reading server features for
`GLIBTOP_METHOD_PIPE'.
* sysdeps/freebsd: New directory.
1998-08-01 Martin Baulig <martin@home-of-linux.org>
* include/glibtop/swap.h (glibtop_swap): Added `pagein' and `pageout'.
* kernel/table20/table.h: Removed.
* kernel/table21/table.h: Removed.
* kernel/table.h: Added. Things are now binary compatible between
both kernel versions.
1998-07-30 Martin Baulig <martin@home-of-linux.org>
* acconfig.h (u_int64_t, int64_t): Added.
* lib/lib.awk: Using correct `(1 << GLIBTOP_SYSDEPS_<feature>)'
in call to `glibtop_init_r'.
* configure.in (GNOME_LIBGTOP_TYPES): New check.
* include/glibtop/*.h: Using `u_int64_t' instead of `unsigned long'
and `long' to avoid problems when client is on a 32bit system and
the server on a 64bit system.
* sysdeps/common/gnuslib.c: Using `0xffffffff' instead of -1
as error code for inet_addr () since on 64bit systems,
`inet_addr (some_error) != (INET_ADDR) -1'.
* configure.in: Only defining guile stuff if
we really have guile.
1998-07-29 Martin Baulig <martin@home-of-linux.org>
* guile/ChangeLog: New file.
* features.def: New format - now includes type of return value
and parameters.
* lib/lib.awk: Changed to use new `features.def'.
* sysdeps/guile/guile.awk: Dito;
* sysdeps/guile/names/guile-names.awk: Dito.
* libgtopConf.sh.in: Added
`LIBGTOP_NAMES_LIBS', `LIBGTOP_NAMES_INCS',
`LIBGTOP_GUILE_NAMES_LIBS', `LIBGTOP_GUILE_NAMES_INCS',
`LIBGTOP_MAJOR_VERSION', `LIBGTOP_MINOR_VERSION'
`LIBGTOP_VERSION', `libgtop_sysdeps_dir'.
* acinclude.m4 (AC_LC_SYSDEPS): Removed since this has been
replaced with `GNOME_LIBGTOP_SYSDEPS' long ago.
* LIBGTOP-VERSION: New file.
* */Makefile.am (INCLUDES): Removed; now defined in `configure.in'.
* sysdeps/names/mountlist.c: New file.
* lib/{init, open}.c (GTOP_SERVER): Renamed to `LIBGTOP_SERVER'.
* configure.in (INCLUDES): Added definition.
(libgtop_want_names): Always true; `libgtop_names.la' is now
always created since some other programs rely upon it - but
have to use `LIBGTOP_NAMES_LIBS' and `LIBGTOP_NAMES_INCS' to
use it in your application.
(libgtop_want_guile_names): Always true; but you have to use
`LIBGTOP_GUILE_NAMES_LIBS' and `LIBGTOP_GUILE_NAMES_INCS' to
use it in your application.
(LIBGTOP_LIBS): Removed `-lgtop_names' and `-lgtop_guile_names'.
(LIBGTOP_NAMES_LIBS): New variable. Use it to link your
application with the names interface.
(LIBGTOP_NAMES_INCS): New variable. Also #defines `GLIBTOP_NAMES'
which is now required if your application wants to use the names
interface.
(LIBGTOP_GUILE_NAMES_LIBS): New variable. Use it to link your
application with the guile names interface.
(LIBGTOP_GUILE_NAMES_INCS): New variable. Also #defines
`GLIBTOP_NAMES' and `GLIBTOP_GUILE_NAMES' which are now required
if your application wants to use the guile names interface.
1998-07-24 Martin Baulig <martin@home-of-linux.org>
* sysdeps/common/mountlist.c (glibtop_get_mountlist_s):
Added `all_fs' parameter.
* sysdeps/{kernel, linux}/*.c: Replaced `glibtop_init_r' with
`glibtop_init_s'.
* sysdeps/sun4/open.c (glibtop_init_p): Removed `program_name'
parameter.
* sysdeps/osf1/glibtop_suid.h: New file.
* sysdeps/osf1/glibtop_server.h: Now correctly using
`(1 << GLIBTOP_SYSDEPS_*)' instead of `GLIBTOP_SYSDEPS_*'.
* sysdeps/osf1/open_suid.c (glibtop_init_p): New function.
* sysdeps/osf1/proc*.c: Done some more work here.
1998-07-23 Martin Baulig <martin@home-of-linux.org>
* include/glibtop/procsignal.h (glibtop_proc_signal):
Changed type for `signal', `blocked', `sigignore' and
`sigcatch' to `unsigned long long'.
1998-07-22 Martin Baulig <martin@home-of-linux.org>
* include/glibtop/fsusage.h: New file.
* features.def: Added new feature `fsusage'.
* sysdeps/common/fsusage.c (glibtop_get_fsusage_s): New function.
(get_fs_usage): Declared as `static'.
* sysdeps/names/fsusage.c: New file.
* include/glibtop/mountlist.h: New file.
* features.def: Added new feature `mountlist'.
* sysdeps/common/mountlist.c (glibtop_get_mountlist_s): New function.
(read_filesystem_list): Declared as `static'.
* sysdeps/common/Makefile.am (libgtop_common_la_SOURCES):
Added `fsusage.[ch]' and `mountlist.[ch]'.
* include/glibtop/signal.h: New file.
* sysdeps/{kernel, linux, osf1, sun4, stub}/siglist.c: New files.
1998-07-22 Martin Baulig <martin@home-of-linux.org>
* lib/init.c (glibtop_init_s): Added this init function of
the sysdeps directory `libgtop_sysdeps.la'.
* lib/open.c (glibtop_open_l): Unconditionally calling
`glibtop_init_s' after server initialization.
* lib/lib.awk: Removed references to functions from
`libgtop_sysdeps_suid.la' to avoid undefined symbols.
* sysdeps/stub/open.c (glibtop_open_s): Renamed this
function from `glibtop_open_r'.
* sysdeps/stub/close.c (glibtop_close_s): Renamed this
function from `glibtop_close_l'.
* sysdeps/kernel/open.c (glibtop_open_s): Renamed this
function from `glibtop_open_r'.
* sysdeps/kernel/close.c (glibtop_close_s): Renamed this
function from `glibtop_close_l'.
* sysdeps/linux/open.c (glibtop_open_s): Renamed this
function from `glibtop_open_r'.
* sysdeps/linux/close.c (glibtop_close_s): Renamed this
function from `glibtop_close_l'.
* sysdeps/osf1/Makefile.am (lib_LTLIBRARIES): Added
`libgtop_sysdeps_suid.la' for the suid server.
* sysdeps/osf1/open_suid.c (glibtop_open_p): New file.
Contains all stuff that was formerly in `open.c'.
* sysdeps/osf1/open.c: Moved everything from here into
the new file `open_suid.c'.
* sysdeps/osf1/open.c (glibtop_open_s): New function.
* sysdeps/osf1/close_suid.c (glibtop_close_p): New file.
* sysdeps/osf1/close.c (glibtop_close_s): New function.
* sysdeps/osf1/*.c: Using the new init, open and close
functions.
* sysdeps/sun4/Makefile.am (lib_LTLIBRARIES): Added
`libgtop_sysdeps_suid.la' for the suid server.
* sysdeps/sun4/nosuid.c (glibtop_open_s, glibtop_close_s): New file
* sysdeps/sun4/*.c: All functions now have the `_p' suffix.
* sysdeps/common/Makefile.am (lib_LTLIBRARIES): Added
`libgtop_suid_common.la' which only contains stuff that is
needed in the suid parts.
* sysdeps/common/xmalloc.c: Using `glibtop_error_io_r' instead
of `glibtop_error_r'.
* sysdeps/{kernel, linux, osf1, sun4, stub}/init.c: Removed.
`glibtop_init_s' has been moved into `lib/init.c' since it's the
same in all the sysdeps directories.
* src/server/main.c: It is now an error to request a feature that
does not need the suid server.
* src/proxy: Removed.
1998-07-21 Martin Baulig <martin@home-of-linux.org>
* doc/ChangeLog: New file.
* sysdeps/kernel/*.c: Using `glibtop_error_io_r' instead
of `glibtop_error_r'.
* sysdeps/kernel/proclist.c: Now using the table () function, too.
This means that currently the table () function can fetch all
information for libgtop and you can even unmount /proc !
1998-07-18 Martin Baulig <martin@home-of-linux.org>
* lib/{init, open}.c: Added `GLIBTOP_METHOD_PIPE' again.
* src/server/main.c: Removed gettext stuff.
1998-07-17 Martin Baulig <baulig@Stud.Informatik.uni-trier.de>
* sysdeps/common/sysdeps.c (glibtop_get_sysdeps_r): Using
library functions with '_l' prefix instead of directly calling
sysdeps code with '_r' prefix. This is necessary for client/server
mode.
* lib/lib.awk (glibtop_get_*): Now correctly using
`(1 << GLIBTOP_SYSDEPS_*)' instead of `GLIBTOP_SYSDEPS_*'.
* sysdeps/sun4/proclist.c (glibtop_get_proclist_p): Added
implementation of that feature.
* sysdeps/sun4/proc_{uid, state}.c: Now working quite well.
* sysdeps/sun4/proc_{mem, time, signal, kernel, segment}.c: Added
some basic implementation; this isn't really working yet.
* sysdeps/linux/sem_limits.c: Applied patch from Albert K T Hui
<avatar@deva.net> for glibc 2.1.
1998-07-15 Martin Baulig <martin@home-of-linux.org>
* sysdeps/sun4/loadavg.h: New file. Imported from top 3.4.
* sysdeps/sun4/uptime.c (glibtop_get_uptime_p): Added
implementation of that function using glibtop_get_cpu ().
* sysdeps/sun4/loadavg.c (glibtop_get_loadavg_p): Added
implementation of that feature.
* sysdeps/sun4/{shm_limits.c, msg_limits.c, shm_limits.c}:
Added implementation of this features.
1998-07-14 Martin Baulig <baulig@Stud.Informatik.uni-trier.de>
* src/daemon/server_config.h.in: Added some comments.
* src/daemon/server_config.pl: New file. This is a script you can use
to create `server_config.h'. It will query you for some configuration
options.
* configure.in (AC_PROG_AWK): Replaced this test with explicit test
for `gawk' and `awk' since `mawk' doesn't work.
1998-07-14 Martin Baulig <martin@home-of-linux.org>
* src/daemon/gnuserv.c: Doing correct server initialization
using `glibtop_set_parameter_l' and `glibtop_init_r'.
* src/daemon/main.c: Removed call to `glibtop_init_r'.
* lib/open.c (glibtop_open_l): We now call the open function
of the sysdeps directory (glibtop_open_r) for server method
`GLIBTOP_METHOD_DIRECT'.
* sysdeps/{linux, sun4, stub}/open.c: No longer `memset'
server to zero.
* src/daemon/slave.c: New file.
* src/daemon/*.c: Done some more work on the daemon.
* sysdeps/common/gnuslib.c: Removed IPC stuff.
* include/glibtop/gnuserv.h: Removed IPC stuff.
* include/glibtop/command.h (glibtop_response_unit): Added
typedef for `struct _glibtop_response_unit'.
* lib/Makefile.am: Using `$(top_srcdir)/features.def'
instead of `$(top_builddir)/features.def'.
* sysdeps/guile/Makefile.am: Using `$(top_srcdir)/features.def'
instead of `$(top_builddir)/features.def'.
* sysdeps/guile/names/Makefile.am: Dito.
* sysdeps/stub/*.c: changed suffix of all functions
from '_s' to '_r'; see also ChangeLog entry from Jun 6.
1998-07-13 Martin Baulig <baulig@merkur.uni-trier.de>
* src/daemon/server_config.h: Removed from CVS.
This is a config file which needs to be edited.
* src/daemon/server_config.h.in: Added. This is just
an example for `server_config.h'.
1998-07-13 Martin Baulig <martin@home-of-linux.org>
* glibtop.h: Fixed invocation of `glibtop_close_r'.
* sysdeps/linux/procstate.c: Added missing `fclose'.
* include/glibtop/gnuserv.h (UNIX_DOMAIN_SOCKETS): Defining.
* include/glibtop/open.h (GLIBTOP_METHOD_UNIX): Added.
* lib/init.c: Added new method `GLIBTOP_METHOD_UNIX'.
* lib/open.c: Added support for Unix Domain Sockets.
* lib/close.c: Now closing inet and unix connections.
* lib/parameter.c (glibtop_set_parameter_l): You can now
set the `method' and `features' fields.
* src/daemon/server_config.h: New file.
* src/daemon/{gnuserv.c, main.c}: More work on the server.
1998-07-10 Martin Baulig <martin@home-of-linux.org>
* src/Makefile.am (SUBDIRS): Removed `proxy'. This directory
is considered obsolete and will be removed soon.
1998-07-06 Martin Baulig <martin@home-of-linux.org>
* sysdeps/common/mountlist.c: using functions from `xmalloc.c'.
* sysdeps/common/error.c: all functions now accept NULL as
`server' argument.
* acconfig.h (AFS, MOUNTED_FREAD, MOUNTED_FREAD_FSTYP,
MOUNTED_GETFSSTAT, MOUNTED_GETMNT, MOUNTED_GETMNTENT1,
MOUNTED_GETMNTENT2, MOUNTED_GETMNTINFO, MOUNTED_LISTMNTENT,
MOUNTED_VMOUNT, STAT_STATFS3_OSF1, STAT_READ_FILSYS,
STAT_STATFS2_BSIZE, STAT_STATFS2_FSIZE, STAT_STATFS2_FS_DATA,
STAT_STATFS4, STAT_STATVFS, STATFS_TRUNCATES_BLOCK_COUNTS):
New macros.
* configure.in: added GNOME_FILEUTILS_CHECKS.
* sysdeps/common/{fsusage, mountlist}.[ch]:
Imported from GNU Fileutils 3.16.
* sysdeps/common/mountlist.c: using g_malloc, g_realloc and g_strdup.
1998-07-03 Martin baulig <martin@home-of-linux.org>
* macros/gnome-libgtop-sysdeps.m4: No longer use

7
LIBGTOP-VERSION Normal file
View File

@@ -0,0 +1,7 @@
LIBGTOP_MAJOR_VERSION=0
LIBGTOP_MINOR_VERSION=2a
LIBGTOP_VERSION=$LIBGTOP_MAJOR_VERSION.$LIBGTOP_MINOR_VERSION
# For automake.
VERSION=$LIBGTOP_VERSION
PACKAGE=libgtop

View File

@@ -1,14 +1,18 @@
## Process this file with automake to produce Makefile.in.
if GLIBTOP_EXAMPLES
examples_SUBDIRS = examples
examples_SUBDIRS = examples
if GUILE
guile_SUBDIRS = guile
else
guile_SUBDIRS =
endif
built_SUBDIRS = include sysdeps lib src
SUBDIRS = po intl support macros $(built_SUBDIRS) $(examples_SUBDIRS)
SUBDIRS = po intl support macros include sysdeps lib src \
$(guile_subdirs) $(examples_SUBDIRS)
DIST_SUBDIRS = po intl macros include sysdeps src lib examples
DIST_SUBDIRS = po intl macros include sysdeps src lib guile examples
include_HEADERS = glibtop.h
@@ -41,16 +45,21 @@ libgtopConf.sh: libgtopConf.sh.in Makefile
-e 's,\@LIBGTOP_INCLUDEDIR\@,$(includedir),g' \
-e 's,\@LIBGTOP_LIBS\@,$(LIBGTOP_LIBS),g' \
-e 's,\@LIBGTOP_INCS\@,$(LIBGTOP_INCS),g' \
-e 's,\@LIBGTOP_NAMES_LIBS\@,$(LIBGTOP_NAMES_LIBS),g' \
-e 's,\@LIBGTOP_NAMES_INCS\@,$(LIBGTOP_NAMES_INCS),g' \
-e 's,\@LIBGTOP_GUILE_LIBS\@,$(LIBGTOP_GUILE_LIBS),g' \
-e 's,\@LIBGTOP_GUILE_INCS\@,$(LIBGTOP_GUILE_INCS),g' \
-e 's,\@LIBGTOP_GUILE_NAMES_LIBS\@,$(LIBGTOP_GUILE_NAMES_LIBS),g' \
-e 's,\@LIBGTOP_GUILE_NAMES_INCS\@,$(LIBGTOP_GUILE_NAMES_INCS),g' \
-e 's,\@LIBGTOP_BINDIR\@,$(LIBGTOP_BINDIR),g' \
-e 's,\@LIBGTOP_SERVER\@,$(LIBGTOP_SERVER),g' \
-e 's,\@LIBGTOP_MAJOR_VERSION\@,$(LIBGTOP_MAJOR_VERSION),g' \
-e 's,\@LIBGTOP_MINOR_VERSION\@,$(LIBGTOP_MINOR_VERSION),g' \
-e 's,\@LIBGTOP_VERSION\@,$(LIBGTOP_VERSION),g' \
-e 's,\@libgtop_sysdeps_dir\@,$(libgtop_sysdeps_dir),g' \
-e 's,\@libgtop_need_server\@,$(libgtop_need_server),g' \
-e 's,\@libgtop_use_machine_h\@,$(libgtop_use_machine_h),g' \
-e 's,\@libgtop_guile_found\@,$(libgtop_guile_found),g' \
-e 's,\@libgtop_want_names\@,$(libgtop_want_names),g' \
-e 's,\@libgtop_want_guile_names\@,$(libgtop_want_guile_names),g' \
-e 's,\@libgtop_want_examples\@,$(libgtop_want_examples),g' \
< $(srcdir)/libgtopConf.sh.in > libgtopConf.tmp \
&& mv libgtopConf.tmp libgtopConf.sh

View File

@@ -12,10 +12,92 @@
/* Do not remove this comments and the empty lines; they are needed */
#undef HAVE_PROGRAM_INVOCATION_SHORT_NAME
/* Define if you have the Andrew File System. */
#undef AFS
/* Define one of the following to indicate how a program can
get a list of mounted filesystems. */
/* Define if there is no specific function for reading the list of
mounted filesystems. fread will be used to read /etc/mnttab. [SVR2] */
#undef MOUNTED_FREAD
/* Define if (like SVR2) there is no specific function for reading the
list of mounted filesystems, and your system has these header files:
<sys/fstyp.h> and <sys/statfs.h>. [SVR3] */
#undef MOUNTED_FREAD_FSTYP
/* Define if there is a function named getfsstat for reading the list
of mounted filesystems. [DEC Alpha running OSF/1] */
#undef MOUNTED_GETFSSTAT
/* Define if there is a function named getmnt for reading the list of
mounted filesystems. [Ultrix] */
#undef MOUNTED_GETMNT
/* Define if there is a function named getmntent for reading the list
of mounted filesystems, and that function takes a single argument.
[4.3BSD, SunOS, HP-UX, Dynix, Irix] */
#undef MOUNTED_GETMNTENT1
/* Define if there is a function named getmntent for reading the list of
mounted filesystems, and that function takes two arguments. [SVR4] */
#undef MOUNTED_GETMNTENT2
/* Define if there is a function named getmntinfo for reading the list
of mounted filesystems. [4.4BSD] */
#undef MOUNTED_GETMNTINFO
/* Define if there is a function named listmntent that can be used to
list all mounted filesystems. [UNICOS] */
#undef MOUNTED_LISTMNTENT
/* Define if there is a function named mntctl that can be used to read
the list of mounted filesystems, and there is a system header file
that declares `struct vmount.' [AIX] */
#undef MOUNTED_VMOUNT
/* Define one of the following to indicate how a program can obtain
filesystems usage information. */
/* Define if statfs takes 3 args. [DEC Alpha running OSF/1] */
#undef STAT_STATFS3_OSF1
/* Define if there is no specific function for reading filesystems usage
information and you have the <sys/filsys.h> header file. [SVR2] */
#undef STAT_READ_FILSYS
/* Define if statfs takes 2 args and struct statfs has a field named f_bsize.
[4.3BSD, SunOS 4, HP-UX, AIX PS/2] */
#undef STAT_STATFS2_BSIZE
/* Define if statfs takes 2 args and struct statfs has a field named f_fsize.
[4.4BSD, NetBSD] */
#undef STAT_STATFS2_FSIZE
/* Define if statfs takes 2 args and the second argument has
type struct fs_data. [Ultrix] */
#undef STAT_STATFS2_FS_DATA
/* Define if statfs takes 4 args. [SVR3, Dynix, Irix, Dolphin] */
#undef STAT_STATFS4
/* Define if there is a function named statvfs. [SVR4] */
#undef STAT_STATVFS
/* Define if the block counts reported by statfs may be truncated to 2GB
and the correct values may be stored in the f_spare array.
[SunOS 4.1.2, 4.1.3, and 4.1.3_U1 are reported to have this problem.
SunOS 4.1.1 seems not to be affected.] */
#undef STATFS_TRUNCATES_BLOCK_COUNTS
/* to fix a bug in autoheader on DEC OSF1. */
#undef HAVE_PROGRAM_INVOCATION_NAME
#undef HAVE_SOCKETS
#undef HAVE_SOCKADDR_SUN_LEN
#undef HAVE_LIBJPEG
#undef HAVE_LIBGIF
#undef HAVE_LIBTIFF
@@ -24,7 +106,10 @@
#undef GNOME_ENABLE_DEBUG
#undef HAVE_GMP2_INCLUDE_DIR
#undef HAVE_GUILE
#undef ssize_t
#undef u_int64_t
#undef int64_t
#undef HAVE_GLIBTOP_MACHINE_H
@@ -37,3 +122,4 @@
#undef HAVE_LINUX_TABLE
#undef HAVE_XAUTH

View File

@@ -10,97 +10,6 @@ dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
dnl PARTICULAR PURPOSE.
AC_DEFUN([AC_LC_CANONICAL_HOST],[
AC_REQUIRE([AC_CANONICAL_HOST])
# The way shlib-versions is used to generate soversions.mk uses a
# fairly simplistic model for name recognition that can't distinguish
# i486-pc-linux-gnu fully from i486-pc-gnu. So we mutate a $host_os
# of `gnu*' here to be `gnu-gnu*' just so that shlib-versions can
# tell. This doesn't get used much beyond that, so it's fairly safe.
case "$host_os" in
linux*)
;;
gnu*)
host_os=`echo $host_os | sed -e 's/gnu/gnu-gnu/'`
;;
esac
])
AC_DEFUN([AC_LC_SYSDEPS],[
AC_REQUIRE([AC_LC_CANONICAL_HOST])
AC_REQUIRE([GNOME_LIBGTOP_SYSDEPS])
AC_MSG_CHECKING(whether we need the gtop_server)
AC_ARG_ENABLE(libgtop-server,
[ --enable-libgtop-server use gtop_server [default=auto]],
[if test "x$enableval" = "xyes" ; then
libgtop_need_server=yes
elif test "x$enableval" = "xno" ; then
libgtop_need_server=no
fi])
AC_MSG_RESULT($libgtop_need_server)
AC_MSG_CHECKING(whether building of libgtop names is requested)
AC_ARG_ENABLE(libgtop-names,
[ --enable-libgtop-names enable building of 'names' subdirs [default=yes]],
[if test "x$enableval" = "xyes" ; then
libgtop_want_names=yes
else
libgtop_want_names=$enableval
fi],[libgtop_want_names=yes])
AC_MSG_RESULT($libgtop_want_names)
if test x$libgtop_want_names = xyes ; then
AC_DEFINE(GLIBTOP_NAMES)
fi
AM_CONDITIONAL(GLIBTOP_NAMES, test x$libgtop_want_names = xyes)
AC_MSG_CHECKING(whether building of the guile interface is requested)
AC_ARG_ENABLE(libgtop-guile,
[ --enable-libgtop-guile enable building of the guile interface [default=yes]],
[if test "x$enableval" = "xyes" ; then
libgtop_want_guile=yes
else
libgtop_want_guile=$enableval
fi],[libgtop_want_guile=yes])
AC_MSG_RESULT($libgtop_want_guile)
AC_MSG_CHECKING(whether building of the examples is requested)
AC_ARG_ENABLE(libgtop-examples,
[ --disable-libgtop-examples disable building of the examples],
[if test "x$enableval" = "xyes" ; then
libgtop_want_examples=yes
else
libgtop_want_examples=$enableval
fi],[libgtop_want_examples=yes])
AC_MSG_RESULT($libgtop_want_examples)
if test x$libgtop_want_examples = xyes ; then
AC_DEFINE(GLIBTOP_EXAMPLES)
fi
AM_CONDITIONAL(GLIBTOP_EXAMPLES, test x$libgtop_want_examples = xyes)
if test x$libgtop_use_machine_h = xyes ; then
machine_incs="-I\$(top_srcdir)/sysdeps/$sysdeps_dir"
fi
AC_SUBST(machine_incs)
AC_SUBST(libgtop_want_names)
AC_SUBST(libgtop_want_guile)
AC_SUBST(libgtop_want_examples)
])
######################################################################
# progtest.m4 from gettext 0.32
######################################################################

View File

@@ -6,7 +6,12 @@ AC_INIT(copyright.txt)
AM_CONFIG_HEADER(config.h)
AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE(libgtop, 0.01)
. $srcdir/LIBGTOP-VERSION
AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
AC_SUBST(LIBGTOP_MAJOR_VERSION)
AC_SUBST(LIBGTOP_MINOR_VERSION)
AC_SUBST(LIBGTOP_VERSION)
AM_ACLOCAL_INCLUDE(macros)
@@ -15,7 +20,10 @@ AC_PROG_CC
AC_STDC_HEADERS
AC_ARG_PROGRAM
AC_PROG_AWK
dnl We don't use `AC_PROG_AWK' since it checks for mawk first which
dnl does not work for libgtop.
AC_CHECK_PROGS(AWK, gawk awk, )
test -z "$AWK" && AC_MSG_ERROR([Sorry, you need a working awk interpreter.])
AC_CHECK_TOOL(CC,gcc)
AC_CHECK_TOOL(RANLIB,ranlib)
@@ -44,21 +52,18 @@ else
AM_CONDITIONAL(CROSS_COMPILING, test "x$cross_compiling" = xyes)
fi
AC_LC_SYSDEPS
GNOME_LIBGTOP_SYSDEPS
GNOME_LIBGTOP_TYPES
if test x$libgtop_want_guile = xyes ; then
GNOME_CHECK_GUILE
if test x$ac_cv_guile_found = xyes ; then
if test x$libgtop_want_names = xyes ; then
AC_DEFINE(GLIBTOP_GUILE_NAMES)
fi
guile_examples='third third_static'
guile_subdirs='guile'
else
guile_examples=
guile_subdirs=
fi
GNOME_CHECK_GUILE
if test x$ac_cv_guile_found = xyes ; then
AC_DEFINE(GLIBTOP_GUILE_NAMES)
libgtop_guile_found=yes
guile_examples='third third_static'
guile_subdirs='guile'
else
libgtop_guile_found=no
guile_examples=
guile_subdirs=
fi
@@ -92,6 +97,21 @@ AC_CHECK_LIB(kvm, kvm_open)
dnl For DEC OSF1
AC_CHECK_LIB(mach, vm_statistics)
dnl Check for Internet sockets.
AC_CHECK_FUNC(socket,
[AC_CHECK_HEADER(netinet/in.h,
[AC_CHECK_HEADER(arpa/inet.h, [
AC_DEFINE(HAVE_SOCKETS)
AC_MSG_CHECKING("for sun_len member in struct sockaddr_un")
AC_TRY_LINK([
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
],
[static struct sockaddr_un x; x.sun_len = 1;],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SOCKADDR_SUN_LEN)],
[AC_MSG_RESULT(no)])])])])
dnl Checks for library functions.
AC_FUNC_ALLOCA
AC_FUNC_MMAP
@@ -125,12 +145,8 @@ if test "$with_xauth" = "yes"; then
fi
AC_SUBST(libs_xauth)
CFLAGS="$CFLAGS -D_IN_LIBGTOP"
AC_SUBST(CFLAGS)
AC_SUBST(CPPFLAGS)
AC_SUBST(LDFLAGS)
dnl For diskusage stuff
GNOME_FILEUTILS_CHECKS
AC_ARG_ENABLE(debug, [ --enable-debug turn on debugging [default=no]],AC_DEFINE(GNOME_ENABLE_DEBUG),)
@@ -173,44 +189,47 @@ fi
AC_SUBST(libgtop_guile_found)
if test x$libgtop_want_names = xyes ; then
if test x$ac_cv_guile_found = xyes ; then
LIBGTOP_GUILE_LIBS="$LIBGTOP_GUILE_LIBS -lgtop_guile_names"
libgtop_want_guile_names=yes
else
libgtop_want_guile_names=no
fi
LIBGTOP_LIBS="$LIBGTOP_LIBS -lgtop_names"
LIBGTOP_GUILE_LIBS="$LIBGTOP_GUILE_LIBS -lgtop_names"
fi
LIBGTOP_LIBS="$LIBGTOP_LIBS -lgtop_common -lgtop_sysdeps"
LIBGTOP_GUILE_LIBS="$LIBGTOP_GUILE_LIBS -lgtop_common -lgtop_sysdeps"
AC_SUBST(libgtop_want_guile_names)
LIBGTOP_NAMES_LIBS="$LIBGTOP_LIBS -lgtop_names"
LIBGTOP_GUILE_NAMES_LIBS="$LIBGTOP_GUILE_LIBS -lgtop_guile_names"
LIBGTOP_GUILE_NAMES_LIBS="$LIBGTOP_GUILE_LIBS -lgtop_names"
LIBGTOP_LIBS="$LIBGTOP_LIBS -lgtop_common $libs_xauth"
LIBGTOP_GUILE_LIBS="$LIBGTOP_GUILE_LIBS -lgtop_common $libs_xauth"
LIBGTOP_LIBS="$LIBGTOP_LIBS $libs_xauth"
LIBGTOP_NAMES_LIBS="$LIBGTOP_NAMES_LIBS $libs_xauth"
LIBGTOP_GUILE_LIBS="$LIBGTOP_GUILE_LIBS $libs_xauth"
LIBGTOP_GUILE_NAMES_LIBS="$LIBGTOP_GUILE_NAMES_LIBS $libs_xauth"
if test "x$need_server" = "xyes" ; then
LIBGTOP_LIBS="$LIBGTOP_LIBS -lgtop"
LIBGTOP_GUILE_LIBS="$LIBGTOP_GUILE_LIBS -lgtop"
else
LIBGTOP_LIBS="$LIBGTOP_LIBS -lgtop_sysdeps"
LIBGTOP_GUILE_LIBS="$LIBGTOP_GUILE_LIBS -lgtop_sysdeps"
fi
LIBGTOP_GUILE_LIBS="$LIBGTOP_GUILE_LIBS $GUILE_LIBS"
LIBGTOP_GUILE_INCS="$LIBGTOP_GUILE_INCS $GUILE_INCS -DGLIBTOP_GUILE"
if test "x$ac_cv_guile_found" = "xyes" ; then
LIBGTOP_INCS="$LIBGTOP_INCS $GUILE_INCS"
LIBGTOP_GUILE_INCS="$LIBGTOP_INCS $GUILE_INCS"
LIBGTOP_GUILE_LIBS="$LIBGTOP_GUILE_LIBS $GUILE_LIBS"
fi
LIBGTOP_NAMES_INCS="$LIBGTOP_INCS -DGLIBTOP_NAMES"
LIBGTOP_GUILE_NAMES_INCS="$LIBGTOP_GUILE_INCS -DGLIBTOP_GUILE_NAMES"
LIBGTOP_GUILE_NAMES_INCS="$LIBGTOP_GUILE_INCS -DGLIBTOP_NAMES"
machine_incs='-I$(top_srcdir)/sysdeps/@sysdeps_dir@'
machine_incs="-I\$(top_srcdir)/sysdeps/$sysdeps_dir"
AC_SUBST(machine_incs)
if test x$libgtop_guile_found = xyes ; then
guile_def="-DGLIBTOP_GUILE -DGLIBTOP_GUILE_NAMES $GUILE_INCS "
else
guile_def=""
fi
INCLUDES="$CFLAGS -D_IN_LIBGTOP -D_GNU_SOURCE -DGLIBTOP_NAMES $guile_def -I\$(top_builddir) -I\$(top_srcdir) -I\$(top_srcdir)/sysdeps/$sysdeps_dir -I\$(top_srcdir)/include -I\$(top_srcdir)/intl "'-DGTOPLOCALEDIR=\"$(datadir)/locale\" -DLIBGTOP_VERSION=\"'"$LIBGTOP_VERSION"'\" -DLIBGTOP_SERVER=\"'"$LIBGTOP_SERVER"'\"'
AC_SUBST(INCLUDES)
AC_SUBST(LIBGTOP_LIBS)
AC_SUBST(LIBGTOP_INCS)
AC_SUBST(LIBGTOP_NAMES_LIBS)
AC_SUBST(LIBGTOP_NAMES_INCS)
AC_SUBST(LIBGTOP_GUILE_LIBS)
AC_SUBST(LIBGTOP_GUILE_INCS)
AC_SUBST(LIBGTOP_GUILE_NAMES_LIBS)
AC_SUBST(LIBGTOP_GUILE_NAMES_INCS)
AC_SUBST(LIBGTOP_BINDIR)
AC_SUBST(LIBGTOP_SERVER)
@@ -226,6 +245,13 @@ if test "$need_gnome_support" = yes; then
fi
fi
if test x$libgtop_need_server = xyes ; then
sysdeps_suid_lib="\$(top_builddir)/sysdeps/\$(sysdeps_dir)/libgtop_sysdeps_suid.la"
else
sysdeps_suid_lib=
fi
AC_SUBST(sysdeps_suid_lib)
AC_OUTPUT([
Makefile
po/Makefile.in
@@ -242,11 +268,13 @@ sysdeps/sun4/Makefile
sysdeps/osf1/Makefile
sysdeps/linux/Makefile
sysdeps/kernel/Makefile
sysdeps/freebsd/Makefile
src/Makefile
src/server/Makefile
src/proxy/Makefile
src/daemon/Makefile
lib/Makefile
guile/Makefile
examples/Makefile
perl/Makefile.PL
support/Makefile
macros/Makefile],[sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile])

View File

@@ -1,22 +1,10 @@
*.shml
*.ced
.timestamp
.timestamp2
.timestamp3
dbtohtml-1.shtml
dbtohtml-2.shtml
dbtohtml-3.shtml
dbtohtml.shtml
.timestamp4
gnome-hackers
gnome-hackers.ced
libgtop
libgtop-1.shtml
libgtop-2.shtml
libgtop-3.shtml
libgtop-4.shtml
libgtop-5.shtml
libgtop-INDEX.shtml
libgtop-ref
libgtop-ref.ced
libgtop.ced
libgtop.fot
libgtop.shtml
table

8
doc/ChangeLog Normal file
View File

@@ -0,0 +1,8 @@
1998-07-21 Martin Baulig <martin@home-of-linux.org>
* gnome-hackers.sgml: Added note that this file is
currently out of date and a link to the documentation
of the table () function.
* table.sgml: New file - basic documentation for the
table () system call.

View File

@@ -1,22 +1,37 @@
all: .timestamp .timestamp2 .timestamp3
all: .timestamp .timestamp2 .timestamp3 .timestamp4
clean:
-rm -f .timestamp*
-rm -rf libgtop gnome-hackers libgtop-ref table
.timestamp: libgtop.sgml
rm -rf libgtop
-rm -rf libgtop
mkdir libgtop
jade -D /usr/lib/sgml/jade_dsl -d libgtop.dsl -t sgml \
-rm -f .timestamp
jade -D /usr/lib/sgml -d libgtop.dsl -t sgml \
-V %no-make-index% libgtop.sgml > /dev/null && \
touch .timestamp
.timestamp2: gnome-hackers.sgml
rm -rf gnome-hackers
-rm -rf gnome-hackers
mkdir gnome-hackers
jade -D /usr/lib/sgml/jade_dsl -d gnome-hackers.dsl -t sgml \
-rm -f .timestamp2
jade -D /usr/lib/sgml -d gnome-hackers.dsl -t sgml \
-V %no-make-index% gnome-hackers.sgml > /dev/null && \
touch .timestamp2
.timestamp3: libgtop-ref.sgml ../guile/reference.sgml
rm -rf libgtop-ref
-rm -rf libgtop-ref
mkdir libgtop-ref
jade -D /usr/lib/sgml/jade_dsl -d libgtop-ref.dsl -t sgml \
-rm -f .timestamp3
jade -D /usr/lib/sgml -d libgtop-ref.dsl -t sgml \
-V %no-make-index% libgtop-ref.sgml > /dev/null && \
touch .timestamp3
.timestamp4: table.sgml
-rm -rf table
mkdir table
-rm -f .timestamp4
jade -D /usr/lib/sgml -d table.dsl -t sgml \
-V %no-make-index% table.sgml > /dev/null && \
touch .timestamp4

View File

@@ -2,6 +2,7 @@
<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
<!entity libgtopConf.sh SYSTEM "../libgtopConf.sh" >
<!entity home-of-linux "http://www.home-of-linux.org/">
]>
<book>
<bookinfo>
@@ -51,6 +52,8 @@
</legalnotice>
<abstract>
<para>
<literal>$Id$</literal>
<para>
This is a short introduction in how to use
@@ -59,6 +62,24 @@
takes and the information stored in the automatically generated
<filename>libgtopConf.sh</filename> configuration script.
<note>
<para>
This document is currently out of date.
</note>
<note>
<para>
Documentation about the new <function>table ()</function>
function can be found here:
<itemizedlist>
<listitem><para>
<ulink url="&home-of-linux;kernel/table/">
&home-of-linux;kernel/table/
</ulink>
</itemizedlist>
</note>
</abstract>
</bookinfo>
@@ -391,3 +412,10 @@
</book>
<!--
Local Variables:
mode: sgml
sgml-indent-data: t
End:
-->

161
doc/table.announce.txt Normal file
View File

@@ -0,0 +1,161 @@
Path: news.uni-stuttgart.de!fu-berlin.de!taurus.uni-trier.DE!baulig
From: Martin Baulig <baulig@merkur.uni-trier.de>
Newsgroups: comp.os.linux.development.system
Subject: RFC: New system call for /proc information ?
Date: 07 Jun 1998 20:22:47 +0200
Lines: 143
Sender: baulig@Taurus.uni-trier.de
Message-ID: <of7zpfprs08.fsf@Taurus.uni-trier.de>
NNTP-Posting-Host: taurus.uni-trier.de (136.199.14.201)
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
NNTP-Posting-User: baulig
X-Access: 16 1542 1543
X-Trace: fu-berlin.de 897243777 29527 baulig 136.199.14.201
X-Newsreader: Gnus v5.6.11/XEmacs 20.3 - "Vatican City"
Xref: news.uni-stuttgart.de comp.os.linux.development.system:73539
[Posted to the Gnome Mailing List and to comp.os.linux.development.system]
Request for Comments:
====================
Should we have a new system call under Linux which fetches information
from the /proc filesytem similar to the table() function of DEC OSF/1 ?
The whole story:
===============
I am currently working on libgtop, a library that fetches information
from the proc filesystem for user processes. This library uses a suid
server on system where this is required. On Linux, the information are
fetched directly from the proc filesystem.
Now, I made some profilings (fetches 50000 times cpu, memory, swap,
uptime and loadavg):
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ns/call ns/call name
91.86 348.03 348.03 read
3.07 359.67 11.64 open
0.67 362.22 2.55 close
0.16 363.55 0.62 memset
0.16 364.14 0.59 __ipc
0.03 368.84 0.12 vsscanf (iovsscanf.c:31)
0.01 374.49 0.05 sscanf (sscanf.c:28)
0.00 378.71 0.01 semctl (semctl.c:32)
0.00 378.73 0.01 shmctl (shmctl.c:30)
granularity: each sample hit covers 4 byte(s) for 0.00% of 378.88 seconds
index % time self children called name
[1] 91.9 348.03 0.00 read [1]
-----------------------------------------------
[2] 3.1 11.64 0.00 open [2]
-----------------------------------------------
[3] 0.7 2.55 0.00 close [3]
-----------------------------------------------
[5] 0.2 0.62 0.00 memset [5]
-----------------------------------------------
[6] 0.2 0.59 0.00 __ipc [6]
-----------------------------------------------
[35] 0.0 0.12 0.00 vsscanf (iovsscanf.c:31) [35]
-----------------------------------------------
[96] 0.0 0.05 0.00 sscanf (sscanf.c:28) [96]
-----------------------------------------------
You see, it spends a lot of time in read() which is only used to read the
data from the files in /proc. Well, basically one can say that these
timings are not so bad, normally a process periodically fetches those
information say 10 times a seconds which makes 36000 invocations per
hour.
This will make a total of about 250 seconds per hour or on even say:
``a program fetching those information at a frequency of 10 will take
about 7 % of each hour just for reading files from /proc''.
Now look at timings of __ipc, they're about 350 times better 'cause this
is done using system calls.
So far so good, now look at how this is done on the DEC OSF/1 port of the
library (the following code is part of libgtop - GPL/LGPL):
CPU usage:
{
struct tbl_sysinfo sysinfo;
int ret;
ret = table (TBL_SYSINFO, 0, (char *) &sysinfo, 1,
sizeof (struct tbl_sysinfo));
buf->user = sysinfo.si_user;
buf->nice = sysinfo.si_nice;
buf->sys = sysinfo.si_sys;
buf->idle = sysinfo.si_idle;
}
Well, the table() command of DEC OSF/1 has may disadvantages, too - such
as requiring to be root to fetch any information about processes (well, for
each process that is not the current one).
But this works using system calls rather that reading and parsing files
and should be about as fast as getting the IPC information on Linux.
Under Linux, the current trend seems to be to move anything into the /proc
filesystem, but if you look at the timings, wouldn't it be better to also
implement a system call interface ?
Don't understand me wrong:
=========================
I *do not want* to *replace* the /proc filesystem - it's an excellent
idea to be able to fetch all information on the command line without
any program just a simple 'cat' - I want to *add* a *new* system call
to allow programmers to fetch those information faster that reading
from /proc.
To come to the point:
=====================
Is there any public interest in having a new system call under Linux
which can be used to fetch all information that are currently in the
/proc filesystem.
Basically, this system would be defined like this:
asmlinkage int
sys_table (int command, struct sysinfo_table *buf)
and be invoked like this:
#include <sys/table.h>
{
struct sysinfo_cpu cpu;
struct sysinfo_mem mem;
ret = table (TABLE_CPU, &cpu);
if (ret == -1) return; /* or invoke any error handler */
ret = table (TABLE_MEM, &mem);
if (ret == -1) return;
}
What do you think, folks. Should we have such a system call under Linux ?
I can do the implementation of this system call, but I want to have some
feedback first.
Martin
--
-----------------------------------------------------------------
Martin Baulig - Angewandte Mathematik - Universitaet Trier
baulig@castor.uni-trier.de, http://www.home-of-linux.com/
Key: 1024-bit key with ID C8178435 created 1997/01/24
ID: 67 C1 84 A0 47 F5 11 C5 5F 68 4C 84 99 05 C3 92
Finger me for public key or fetch finger.txt from the url above
------------------------------------------------------------------

12
doc/table.dsl Normal file
View File

@@ -0,0 +1,12 @@
<!doctype style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
<!ENTITY dbtohtml.dsl SYSTEM "dbtohtml.dsl" CDATA DSSSL >
]>
<style-specification id="tabledbotohtml" use="dbtohtml">
(define %output-basename% "table")
(define %output-directory% "table")
</style-specification>
<external-specification id="dbtohtml" document="dbtohtml.dsl">

193
doc/table.sgml Normal file
View File

@@ -0,0 +1,193 @@
<!-- $Id$ -->
<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
<!entity libgtopConf.sh SYSTEM "../libgtopConf.sh" >
<!entity home-of-linux "http://www.home-of-linux.org/">
<!entity table-announce-first "&home-of-linux;kernel/table/ANNOUNCE.FIRST">
<!entity table20-tgz "&home-of-linux;kernel/table/table20.tgz">
<!entity table21-tgz "&home-of-linux;kernel/table/table21.tgz">
<!entity news-c-o-l-d-s "comp.os.linux.development.system">
<!entity libgtop "<productname>libgtop</productname>">
<!entity table "<function>table ()</function>">
]>
<book>
<bookinfo>
<title>The &table; system call under Linux</title>
<authorgroup>
<author>
<firstname>Martin</firstname>
<surname>Baulig</surname>
<affiliation>
<address>
<email>martin@home-of-linux.org</email>
</address>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>1998</year>
<holder>Martin Baulig</holder>
</copyright>
<legalnotice>
<para>
This documentation is free software; you can redistribute
it and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later
version.
<para>
This 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 General Public License for more
details.
<para>
You should have received a copy of the GNU General Public
License along with this program; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
<para>
For more details see the file COPYING in the source
distribution of LibGTop.</para>
</legalnotice>
<abstract>
<para>
<literal>$Id$</literal>
<para>
Under <productname>Linux</productname>, reading from
<filename>/proc</filename> is somehow slow because the data
needs to be converted into a stringified representation from
the kernel and to be parsed from the application program to
get the original data back.
While doing the <productname>DEC OSF/1</productname> port of
&libgtop; I got the idea to add something similar to the &table;
function there to the Linux kernel.
This is what this document is about.
</abstract>
</bookinfo>
<toc></toc>
<chapter id="why-not-sysctl">
<title>Why not <function>sysctl</function>?</title>
<para>
Some weeks ago, I posted the initial proposal of the project to
<ulink url="news:&news-c-o-l-d-s;">&news-c-o-l-d-s;</ulink> with
Message-ID <literal>&lt;of7zpfprs08.fsf@Taurus.uni-trier.de&gt;</literal>.
<para>
You can also read this article at my site:
<itemizedlist>
<listitem><para>
<ulink url="&table-announce-first;">&table-announce-first;</ulink>
</itemizedlist>
<para>
Some people told me to include all the stuff into
<function>sysctl</function> instead of inventing a new system call.
<para>
Basically this is a good idea, but the main problem with
<function>sysctl</function> is that this should be applied to standard
kernels and not just as a short patch. Well, AFAIK something similar
is on the "wish list" for 2.2er kernels - but of cause it'll need some
time until we have a real replacement of the <filename>/proc</filename>
filesystem in <function>sysctl</function>.
<para>
If someone thinks that this absolutely should be included in
<function>sysctl</function>: think about some kind of interface,
discuss it with the kernel developers, ...
<chapter id="about-table">
<title>About the &table; function</title>
<para>
Using the &table; function will not affect any existing kernel
structures and can be done independent from kernel development.
<para>
So it can easily be used in &libgtop; until we have something
simliar in standard kernels.
<para>
If you want to use the &table; function in your own programs, be
aware that it is just intended to be some kind of quick solution
for &libgtop; until there's something better in standard kernels.
<chapter id="how-to-use">
<title>How to use the &table; function in &libgtop;</title>
<para>
The source code of the &table; function is distributed together with
&libgtop;. It can be found in the <filename>kernel/table20</filename>
directory for 2.0.xx kernels and in the <filename>kernel/table21</filename>
directory for 2.1.xx kernels.
<para>
You can also download it from my site:
<itemizedlist>
<listitem><para>
<ulink url="&table20-tgz;">&table20-tgz</ulink>
(for kernel 2.0.xx)
<listitem><para>
<ulink url="&table21-tgz;">&table21-tgz</ulink>
(for kernel 2.1.xx)
</itemizedlist>
<para>
Copy the contents of the appropriate directory to
<filename>/usr/src/linux/table</filename>, apply the
patch to the kernel and re-configure &libgtop;.
<para>
After that, you can unmount <filename>/proc</filename> and
&libgtop; will still work !
<note>
<para>
Maybe one could consider this as a bug, but currently there
isn't a configuration option to disable the &table; function
once you applied the patch ...
</note>
<note>
<para>
Currently I'm working on the 2.1.x version to implement some
features newer kernels have - so the 2.0.x version may not
have all features the 2.1.x one has.
</note>
<note>
<para>
The 2.1.x version of the &table; function is implemented
as a kernel module. You have to do a
<command>insmod table/module.o</command> manually to use it.
<para>
This has the advantage that you don't need to reboot if you
want to play around with the code a little bit.
</note>
</book>
<!--
Local Variables:
mode: sgml
sgml-indent-data: t
End:
-->

View File

@@ -1,3 +1,7 @@
1998-07-22 Martin Baulig <martin@home-of-linux.org>
* mountlist.c: New file.
1998-06-12 Martin Baulig <martin@home-of-linux.org>
* test.scm: New file.

View File

@@ -2,15 +2,12 @@
LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@
INCLUDES = -I$(top_builddir) -I$(top_srcdir) @machine_incs@ \
-I$(top_srcdir)/include -I$(top_srcdir)/intl @GUILE_INCS@ \
-DGTOPLOCALEDIR=\"$(datadir)/locale\" -D_GNU_SOURCE
CFLAGS = -Wall -W @CFLAGS@ -O0
DEFS = @DEFS@
bin_PROGRAMS = first first_static second second_static \
mountlist mountlist_static \
@guile_examples@
EXTRA_PROGRAMS = third third_static
@@ -35,10 +32,8 @@ second_static_SOURCES = $(second_SOURCES)
second_static_LDADD = $(second_LDADD)
second_static_LDFLAGS = -static
if GLIBTOP_NAMES
third_guile_names_LIBS = $(top_builddir)/sysdeps/guile/names/libgtop_guile_names.la
third_names_LIBS = $(top_builddir)/sysdeps/names/libgtop_names.la
endif
third_SOURCES = third.c
third_LDADD = $(top_builddir)/sysdeps/guile/libgtop_guile.la \
@@ -51,3 +46,14 @@ third_LDADD = $(top_builddir)/sysdeps/guile/libgtop_guile.la \
third_static_SOURCES = $(third_SOURCES)
third_static_LDADD = $(third_LDADD)
third_static_LDFLAGS = -static
mountlist_SOURCES = mountlist.c
mountlist_LDADD = $(top_builddir)/lib/libgtop.la \
$(top_builddir)/sysdeps/common/libgtop_common.la \
$(top_builddir)/sysdeps/@sysdeps_dir@/libgtop_sysdeps.la \
@INTLLIBS@ @LIBSUPPORT@ @libs_xauth@
mountlist_static_SOURCES= $(mountlist_SOURCES)
mountlist_static_LDADD = $(mountlist_LDADD)
mountlist_static_LDFLAGS= -static

View File

@@ -68,62 +68,63 @@ main (int argc, char *argv [])
printf ("Host = '%s' - %u\n\n", buffer, port);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_cpu (&data.cpu);
printf ("CPU (0x%08lx): %lu, %lu, %lu, %lu, %lu, %lu\n",
printf ("CPU (0x%08Lx): %Lu, %Lu, %Lu, %Lu, %Lu, %Lu\n",
data.cpu.flags, data.cpu.total, data.cpu.user, data.cpu.nice,
data.cpu.sys, data.cpu.idle, data.cpu.frequency);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_mem (&data.mem);
printf ("Memory (0x%08lx): %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu\n",
printf ("Memory (0x%08Lx): %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu\n",
data.mem.flags, data.mem.total, data.mem.used, data.mem.free,
data.mem.shared, data.mem.buffer, data.mem.cached,
data.mem.user, data.mem.locked);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_swap (&data.swap);
printf ("Swap (0x%08lx): %lu, %lu, %lu\n", data.swap.flags,
data.swap.total, data.swap.used, data.swap.free);
printf ("Swap (0x%08Lx): %Lu, %Lu, %Lu, %Lu, %Lu\n",
data.swap.flags, data.swap.total, data.swap.used,
data.swap.free, data.swap.pagein, data.swap.pageout);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_uptime (&data.uptime);
printf ("Uptime (0x%08lx): %f, %f\n", data.uptime.flags,
printf ("Uptime (0x%08Lx): %f, %f\n", data.uptime.flags,
data.uptime.uptime, data.uptime.idletime);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_loadavg (&data.loadavg);
printf ("Loadavg (0x%08lx): %f, %f, %f\n", data.loadavg.flags,
printf ("Loadavg (0x%08Lx): %f, %f, %f\n", data.loadavg.flags,
data.loadavg.loadavg [0], data.loadavg.loadavg [1],
data.loadavg.loadavg [2]);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_shm_limits (&data.shm_limits);
printf ("Shm Limits (0x%08lx): %ld, %ld, %ld, %ld, %ld\n",
printf ("Shm Limits (0x%08Lx): %Lu, %Lu, %Lu, %Lu, %Lu\n",
data.shm_limits.flags, data.shm_limits.shmmax,
data.shm_limits.shmmin, data.shm_limits.shmmni,
data.shm_limits.shmseg, data.shm_limits.shmall);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_msg_limits (&data.msg_limits);
printf ("Msg Limits (0x%08lx): %ld, %ld, %ld, %ld, %ld, %ld, %ld\n",
printf ("Msg Limits (0x%08Lx): %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu\n",
data.msg_limits.flags, data.msg_limits.msgpool,
data.msg_limits.msgmap, data.msg_limits.msgmax,
data.msg_limits.msgmnb, data.msg_limits.msgmni,
data.msg_limits.msgssz, data.msg_limits.msgtql);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_sem_limits (&data.sem_limits);
printf ("Sem Limits (0x%08lx): "
"%ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld\n",
printf ("Sem Limits (0x%08Lx): "
"%Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu\n",
data.sem_limits.flags, data.sem_limits.semmap,
data.sem_limits.semmni, data.sem_limits.semmns,
data.sem_limits.semmnu, data.sem_limits.semmsl,
@@ -135,8 +136,8 @@ main (int argc, char *argv [])
glibtop_get_sysdeps (&sysdeps);
printf ("Sysdeps (0x%08lx): %lu, %lu, %lu, %lu, %lu, "
"%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu\n",
printf ("Sysdeps (0x%08Lx): %Lu, %Lu, %Lu, %Lu, %Lu, "
"%Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu\n",
sysdeps.flags, sysdeps.cpu, sysdeps.mem, sysdeps.swap,
sysdeps.uptime, sysdeps.loadavg, sysdeps.shm_limits,
sysdeps.msg_limits, sysdeps.sem_limits,
@@ -149,7 +150,7 @@ main (int argc, char *argv [])
ptr = glibtop_get_proclist (&data.proclist);
printf ("Proclist (0x%08lx): %ld, %ld, %ld\n",
printf ("Proclist (0x%08Lx): %Lu, %Lu, %Lu\n",
data.proclist.flags, data.proclist.number,
data.proclist.size, data.proclist.total);
@@ -167,18 +168,18 @@ main (int argc, char *argv [])
printf ("\n");
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_state (&data.proc_state, pid);
printf ("Proc_State PID %5u (0x%08lx): '%s', %c, %u, %u\n",
printf ("Proc_State PID %5u (0x%08Lx): '%s', %c, %u, %u\n",
pid, data.proc_state.flags, data.proc_state.cmd,
data.proc_state.state, data.proc_state.uid,
data.proc_state.gid);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_uid (&data.proc_uid, pid);
printf ("Proc_Uid PID %5u (0x%08lx): "
printf ("Proc_Uid PID %5u (0x%08Lx): "
"%d %d %d %d %d %d %d %d %d %d %d %d\n",
pid, data.proc_uid.flags, data.proc_uid.uid,
data.proc_uid.euid, data.proc_uid.gid,
@@ -188,49 +189,49 @@ main (int argc, char *argv [])
data.proc_uid.tpgid, data.proc_uid.priority,
data.proc_uid.nice);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_mem (&data.proc_mem, pid);
printf ("Proc_Mem PID %5u (0x%08lx): "
"%ld %ld %ld %ld %ld %ld\n", pid, data.proc_mem.flags,
printf ("Proc_Mem PID %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu %Lu %Lu\n", pid, data.proc_mem.flags,
data.proc_mem.size, data.proc_mem.vsize,
data.proc_mem.resident, data.proc_mem.share,
data.proc_mem.rss, data.proc_mem.rss_rlim);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_time (&data.proc_time, pid);
printf ("Proc_Time PID %5u (0x%08lx): "
"%ld %ld %ld %ld %ld %ld %ld\n", pid, data.proc_time.flags,
printf ("Proc_Time PID %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu %Lu %Lu %Lu\n", pid, data.proc_time.flags,
data.proc_time.start_time, data.proc_time.utime,
data.proc_time.stime, data.proc_time.cutime,
data.proc_time.cstime, data.proc_time.timeout,
data.proc_time.it_real_value);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_signal (&data.proc_signal, pid);
printf ("Proc_Signal PID %5u (0x%08lx): "
"%d %d %d %d\n", pid, data.proc_signal.flags,
printf ("Proc_Signal PID %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu\n", pid, data.proc_signal.flags,
data.proc_signal.signal, data.proc_signal.blocked,
data.proc_signal.sigignore, data.proc_signal.sigcatch);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_kernel (&data.proc_kernel, pid);
printf ("Proc_Kernel PID %5u (0x%08lx): "
"%lu %lu %lu %lu %lu %lu %lu %lu\n", pid,
printf ("Proc_Kernel PID %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu\n", pid,
data.proc_kernel.flags, data.proc_kernel.k_flags,
data.proc_kernel.min_flt, data.proc_kernel.maj_flt,
data.proc_kernel.cmin_flt, data.proc_kernel.cmaj_flt,
data.proc_kernel.kstk_esp, data.proc_kernel.kstk_eip,
data.proc_kernel.wchan);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_segment (&data.proc_segment, pid);
printf ("Proc_Segment PID %5u (0x%08lx): "
"%ld %ld %ld %ld %lu %lu %lu\n", pid, data.proc_segment.flags,
printf ("Proc_Segment PID %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu %Lu %Lu %Lu\n", pid, data.proc_segment.flags,
data.proc_segment.trs, data.proc_segment.lrs,
data.proc_segment.drs, data.proc_segment.dt,
data.proc_segment.start_code, data.proc_segment.end_code,
@@ -238,18 +239,18 @@ main (int argc, char *argv [])
printf ("\n");
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_state (&data.proc_state, ppid);
printf ("Proc_State PPID %5u (0x%08lx): '%s', %c, %u, %u\n",
printf ("Proc_State PPID %5u (0x%08Lx): '%s', %c, %u, %u\n",
ppid, data.proc_state.flags, data.proc_state.cmd,
data.proc_state.state, data.proc_state.uid,
data.proc_state.gid);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_uid (&data.proc_uid, ppid);
printf ("Proc_Uid PPID %5u (0x%08lx): "
printf ("Proc_Uid PPID %5u (0x%08Lx): "
"%d %d %d %d %d %d %d %d %d %d %d %d\n",
ppid, data.proc_uid.flags, data.proc_uid.uid,
data.proc_uid.euid, data.proc_uid.gid,
@@ -259,49 +260,49 @@ main (int argc, char *argv [])
data.proc_uid.tpgid, data.proc_uid.priority,
data.proc_uid.nice);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_mem (&data.proc_mem, ppid);
printf ("Proc_Mem PPID %5u (0x%08lx): "
"%ld %ld %ld %ld %ld %ld\n", ppid, data.proc_mem.flags,
printf ("Proc_Mem PPID %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu %Lu %Lu\n", ppid, data.proc_mem.flags,
data.proc_mem.size, data.proc_mem.vsize,
data.proc_mem.resident, data.proc_mem.share,
data.proc_mem.rss, data.proc_mem.rss_rlim);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_time (&data.proc_time, ppid);
printf ("Proc_Time PPID %5u (0x%08lx): "
"%ld %ld %ld %ld %ld %ld %ld\n", ppid, data.proc_time.flags,
printf ("Proc_Time PPID %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu %Lu %Lu %Lu\n", ppid, data.proc_time.flags,
data.proc_time.start_time, data.proc_time.utime,
data.proc_time.stime, data.proc_time.cutime,
data.proc_time.cstime, data.proc_time.timeout,
data.proc_time.it_real_value);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_signal (&data.proc_signal, ppid);
printf ("Proc_Signal PPID %5u (0x%08lx): "
"%d %d %d %d\n", ppid, data.proc_signal.flags,
printf ("Proc_Signal PPID %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu\n", ppid, data.proc_signal.flags,
data.proc_signal.signal, data.proc_signal.blocked,
data.proc_signal.sigignore, data.proc_signal.sigcatch);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_kernel (&data.proc_kernel, ppid);
printf ("Proc_Kernel PPID %5u (0x%08lx): "
"%lu %lu %lu %lu %lu %lu %lu %lu\n", ppid,
printf ("Proc_Kernel PPID %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu\n", ppid,
data.proc_kernel.flags, data.proc_kernel.k_flags,
data.proc_kernel.min_flt, data.proc_kernel.maj_flt,
data.proc_kernel.cmin_flt, data.proc_kernel.cmaj_flt,
data.proc_kernel.kstk_esp, data.proc_kernel.kstk_eip,
data.proc_kernel.wchan);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_segment (&data.proc_segment, ppid);
printf ("Proc_Segment PPID %5u (0x%08lx): "
"%ld %ld %ld %ld %lu %lu %lu\n", ppid, data.proc_segment.flags,
printf ("Proc_Segment PPID %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu %Lu %Lu %Lu\n", ppid, data.proc_segment.flags,
data.proc_segment.trs, data.proc_segment.lrs,
data.proc_segment.drs, data.proc_segment.dt,
data.proc_segment.start_code, data.proc_segment.end_code,
@@ -309,18 +310,18 @@ main (int argc, char *argv [])
printf ("\n");
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_state (&data.proc_state, 1);
printf ("Proc_State INIT %5u (0x%08lx): '%s', %c, %u, %u\n",
printf ("Proc_State INIT %5u (0x%08Lx): '%s', %c, %u, %u\n",
1, data.proc_state.flags, data.proc_state.cmd,
data.proc_state.state, data.proc_state.uid,
data.proc_state.gid);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_uid (&data.proc_uid, 1);
printf ("Proc_Uid INIT %5u (0x%08lx): "
printf ("Proc_Uid INIT %5u (0x%08Lx): "
"%d %d %d %d %d %d %d %d %d %d %d %d\n",
1, data.proc_uid.flags, data.proc_uid.uid,
data.proc_uid.euid, data.proc_uid.gid,
@@ -330,53 +331,55 @@ main (int argc, char *argv [])
data.proc_uid.tpgid, data.proc_uid.priority,
data.proc_uid.nice);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_mem (&data.proc_mem, 1);
printf ("Proc_Mem INIT %5u (0x%08lx): "
"%ld %ld %ld %ld %ld %ld\n", 1, data.proc_mem.flags,
printf ("Proc_Mem INIT %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu %Lu %Lu\n", 1, data.proc_mem.flags,
data.proc_mem.size, data.proc_mem.vsize,
data.proc_mem.resident, data.proc_mem.share,
data.proc_mem.rss, data.proc_mem.rss_rlim);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_time (&data.proc_time, 1);
printf ("Proc_Time INIT %5u (0x%08lx): "
"%ld %ld %ld %ld %ld %ld %ld\n", 1, data.proc_time.flags,
printf ("Proc_Time INIT %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu %Lu %Lu %Lu\n", 1, data.proc_time.flags,
data.proc_time.start_time, data.proc_time.utime,
data.proc_time.stime, data.proc_time.cutime,
data.proc_time.cstime, data.proc_time.timeout,
data.proc_time.it_real_value);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_signal (&data.proc_signal, 1);
printf ("Proc_Signal INIT %5u (0x%08lx): "
"%d %d %d %d\n", 1, data.proc_signal.flags,
printf ("Proc_Signal INIT %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu\n", 1, data.proc_signal.flags,
data.proc_signal.signal, data.proc_signal.blocked,
data.proc_signal.sigignore, data.proc_signal.sigcatch);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_kernel (&data.proc_kernel, 1);
printf ("Proc_Kernel INIT %5u (0x%08lx): "
"%lu %lu %lu %lu %lu %lu %lu %lu\n", 1,
printf ("Proc_Kernel INIT %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu\n", 1,
data.proc_kernel.flags, data.proc_kernel.k_flags,
data.proc_kernel.min_flt, data.proc_kernel.maj_flt,
data.proc_kernel.cmin_flt, data.proc_kernel.cmaj_flt,
data.proc_kernel.kstk_esp, data.proc_kernel.kstk_eip,
data.proc_kernel.wchan);
for (c = 0; c < count; c++)
for (c = 0; c < PROFILE_COUNT; c++)
glibtop_get_proc_segment (&data.proc_segment, 1);
printf ("Proc_Segment INIT %5u (0x%08lx): "
"%ld %ld %ld %ld %lu %lu %lu\n", 1, data.proc_segment.flags,
printf ("Proc_Segment INIT %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu %Lu %Lu %Lu\n", 1, data.proc_segment.flags,
data.proc_segment.trs, data.proc_segment.lrs,
data.proc_segment.drs, data.proc_segment.dt,
data.proc_segment.start_code, data.proc_segment.end_code,
data.proc_segment.start_stack);
glibtop_close ();
exit (0);
}

111
examples/mountlist.c Normal file
View File

@@ -0,0 +1,111 @@
/* $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. */
#include <locale.h>
#include <glibtop.h>
#include <glibtop/open.h>
#include <glibtop/close.h>
#include <glibtop/xmalloc.h>
#include <glibtop/parameter.h>
#include <glibtop/mountlist.h>
#include <glibtop/fsusage.h>
#ifndef PROFILE_COUNT
#define PROFILE_COUNT 1000
#endif
int
main (int argc, char *argv [])
{
glibtop_fsusage fsusage;
glibtop_mountlist mount_list;
glibtop_mountentry *mount_entries;
unsigned c, index, method, count, port;
char buffer [BUFSIZ];
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, GTOPLOCALEDIR);
textdomain (PACKAGE);
glibtop_init_r (&glibtop_global_server, 0, GLIBTOP_INIT_NO_OPEN);
glibtop_get_parameter (GLIBTOP_PARAM_METHOD, &method, sizeof (method));
printf ("Method = %d\n", method);
count = glibtop_get_parameter (GLIBTOP_PARAM_COMMAND, buffer, BUFSIZ);
buffer [count] = 0;
printf ("Command = '%s'\n", buffer);
count = glibtop_get_parameter (GLIBTOP_PARAM_HOST, buffer, BUFSIZ);
buffer [count] = 0;
glibtop_get_parameter (GLIBTOP_PARAM_PORT, &port, sizeof (port));
printf ("Host = '%s' - %u\n\n", buffer, port);
printf ("sbrk (0) = %p\n\n", sbrk (0));
for (c = 0; c < PROFILE_COUNT; c++) {
mount_entries = glibtop_get_mountlist (&mount_list, 1);
glibtop_free (mount_entries);
}
printf ("sbrk (0) = %p\n\n", sbrk (0));
mount_entries = glibtop_get_mountlist (&mount_list, 1);
if (mount_entries == NULL)
_exit (1);
for (index = 0; index < mount_list.number; index++)
printf ("Mount_Entry: %-30s %-10s %-20s\n",
mount_entries [index].mountdir,
mount_entries [index].type,
mount_entries [index].devname);
printf ("\n\n%-23s %9s %9s %9s %9s %9s\n\n",
"", "Blocks", "Free", "Avail", "Files", "Free");
for (index = 0; index < mount_list.number; index++) {
glibtop_get_fsusage (&fsusage,
mount_entries [index].mountdir);
printf ("Usage: %-16s %9Lu %9Lu %9Lu %9Lu %9Lu\n",
mount_entries [index].mountdir,
fsusage.blocks, fsusage.bfree,
fsusage.bavail, fsusage.files,
fsusage.ffree);
}
glibtop_free (mount_entries);
printf ("\nsbrk (0) = %p\n\n", sbrk (0));
glibtop_close ();
exit (0);
}

View File

@@ -45,8 +45,8 @@ main (int argc, char *argv [])
glibtop_get_sysdeps (&sysdeps);
fprintf (stderr, "Sysdeps (0x%08lx): %lu, %lu, %lu, %lu, %lu, "
"%lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu, %lu\n",
fprintf (stderr, "Sysdeps (0x%08Lx): %Lu, %Lu, %Lu, %Lu, %Lu, "
"%Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu, %Lu\n",
sysdeps.flags, sysdeps.cpu, sysdeps.mem, sysdeps.swap,
sysdeps.uptime, sysdeps.loadavg, sysdeps.shm_limits,
sysdeps.msg_limits, sysdeps.sem_limits,
@@ -59,7 +59,7 @@ main (int argc, char *argv [])
ptr = glibtop_get_proclist (&proclist);
fprintf (stderr, "Proclist (0x%08lx): %ld, %ld, %ld\n",
fprintf (stderr, "Proclist (0x%08Lx): %Ld, %Ld, %Ld\n",
proclist.flags, proclist.number, proclist.size,
proclist.total);
@@ -73,14 +73,14 @@ main (int argc, char *argv [])
glibtop_get_proc_state (&data.proc_state, pid);
fprintf (stderr, "Proc_State PID %5u (0x%08lx): "
fprintf (stderr, "Proc_State PID %5u (0x%08Lx): "
"'%s', %c, %u, %u\n", pid, data.proc_state.flags,
data.proc_state.cmd, data.proc_state.state,
data.proc_state.uid, data.proc_state.gid);
glibtop_get_proc_uid (&data.proc_uid, pid);
fprintf (stderr, "Proc_Uid PID %5u (0x%08lx): "
fprintf (stderr, "Proc_Uid PID %5u (0x%08Lx): "
"%d %d %d %d %d %d %d %d %d %d %d %d\n",
pid, data.proc_uid.flags, data.proc_uid.uid,
data.proc_uid.euid, data.proc_uid.gid,
@@ -92,16 +92,16 @@ main (int argc, char *argv [])
glibtop_get_proc_mem (&data.proc_mem, pid);
fprintf (stderr, "Proc_Mem PID %5u (0x%08lx): "
"%ld %ld %ld %ld %ld %ld\n", pid, data.proc_mem.flags,
fprintf (stderr, "Proc_Mem PID %5u (0x%08Lx): "
"%Ld %Ld %Ld %Ld %Ld %Ld\n", pid, data.proc_mem.flags,
data.proc_mem.size, data.proc_mem.vsize,
data.proc_mem.resident, data.proc_mem.share,
data.proc_mem.rss, data.proc_mem.rss_rlim);
glibtop_get_proc_time (&data.proc_time, pid);
fprintf (stderr, "Proc_Time PID %5u (0x%08lx): "
"%ld %ld %ld %ld %ld %ld %ld\n", pid, data.proc_time.flags,
fprintf (stderr, "Proc_Time PID %5u (0x%08Lx): "
"%Ld %Ld %Ld %Ld %Ld %Ld %Ld\n", pid, data.proc_time.flags,
data.proc_time.start_time, data.proc_time.utime,
data.proc_time.stime, data.proc_time.cutime,
data.proc_time.cstime, data.proc_time.timeout,
@@ -109,15 +109,15 @@ main (int argc, char *argv [])
glibtop_get_proc_signal (&data.proc_signal, pid);
fprintf (stderr, "Proc_Signal PID %5u (0x%08lx): "
"%d %d %d %d\n", pid, data.proc_signal.flags,
fprintf (stderr, "Proc_Signal PID %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu\n", pid, data.proc_signal.flags,
data.proc_signal.signal, data.proc_signal.blocked,
data.proc_signal.sigignore, data.proc_signal.sigcatch);
glibtop_get_proc_kernel (&data.proc_kernel, pid);
fprintf (stderr, "Proc_Kernel PID %5u (0x%08lx): "
"%lu %lu %lu %lu %lu %lu %lu %lu\n", pid,
fprintf (stderr, "Proc_Kernel PID %5u (0x%08Lx): "
"%Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu\n", pid,
data.proc_kernel.flags, data.proc_kernel.k_flags,
data.proc_kernel.min_flt, data.proc_kernel.maj_flt,
data.proc_kernel.cmin_flt, data.proc_kernel.cmaj_flt,
@@ -126,8 +126,8 @@ main (int argc, char *argv [])
glibtop_get_proc_segment (&data.proc_segment, pid);
fprintf (stderr, "Proc_Segment PID %5u (0x%08lx): "
"%ld %ld %ld %ld %lu %lu %lu\n", pid, data.proc_segment.flags,
fprintf (stderr, "Proc_Segment PID %5u (0x%08Lx): "
"%Ld %Ld %Ld %Ld %Lu %Lu %Lu\n", pid, data.proc_segment.flags,
data.proc_segment.trs, data.proc_segment.lrs,
data.proc_segment.drs, data.proc_segment.dt,
data.proc_segment.start_code, data.proc_segment.end_code,

View File

@@ -1,16 +1,18 @@
cpu ulong(total,user,nice,sys,idle,frequency)
mem ulong(total,used,free,shared,buffer,cached,user,locked)
swap ulong(total,used,free)
uptime double(uptime,idletime)
loadavg double(loadavg[0],loadavg[1],loadavg[2])
shm_limits ulong(shmmax,shmmin,shmmni,shmseg,shmall)
msg_limits ulong(msgpool,msgmap,msgmax,msgmnb,msgmni,msgssz,msgtql)
sem_limits ulong(semmap,semmni,semmns,semmnu,semmsl,semopm,semume,semusz,semvmx,semaem)
proclist ulong(number,size,total)
proc_state str(cmd):char(state):ulong(uid,gid)
proc_uid long(uid,euid,gid,egid,pid,ppid,pgrp,session,tty,tpgid,priority,nice)
proc_mem long(size,vsize,resident,share,rss,rss_rlim)
proc_time long(start_time,utime,stime,cutime,cstime,timeout,it_real_value)
proc_signal long(signal,blocked,sigignore,sigcatch)
proc_kernel ulong(k_flags,min_flt,maj_flt,cmin_flt,cmaj_flt,kstk_esp,kstk_eip,wchan)
proc_segment long(trs,lrs,drs,dt):ulong(start_code,end_code,start_stack)
void|cpu|ulong(total,user,nice,sys,idle,frequency)
void|mem|ulong(total,used,free,shared,buffer,cached,user,locked)
void|swap|ulong(total,used,free,pagein,pageout)
void|uptime|double(uptime,idletime)
void|loadavg|double(loadavg[0],loadavg[1],loadavg[2])
void|shm_limits|ulong(shmmax,shmmin,shmmni,shmseg,shmall)
void|msg_limits|ulong(msgpool,msgmap,msgmax,msgmnb,msgmni,msgssz,msgtql)
void|sem_limits|ulong(semmap,semmni,semmns,semmnu,semmsl,semopm,semume,semusz,semvmx,semaem)
unsigned *|proclist|ulong(number,size,total)
void|proc_state|str(cmd):char(state):ulong(uid,gid)|pid_t|pid
void|proc_uid|long(uid,euid,gid,egid,pid,ppid,pgrp,session,tty,tpgid,priority,nice)|pid_t|pid
void|proc_mem|long(size,vsize,resident,share,rss,rss_rlim)|pid_t|pid
void|proc_time|long(start_time,utime,stime,cutime,cstime,timeout,it_real_value)|pid_t|pid
void|proc_signal|ulong(signal,blocked,sigignore,sigcatch)|pid_t|pid
void|proc_kernel|ulong(k_flags,min_flt,maj_flt,cmin_flt,cmaj_flt,kstk_esp,kstk_eip,wchan)|pid_t|pid
void|proc_segment|long(trs,lrs,drs,dt):ulong(start_code,end_code,start_stack)|pid_t|pid
glibtop_mountentry *|@mountlist|ulong(number,size,total)|int|all_fs
void|@fsusage|ulong(blocks,bfree,bavail,files,ffree)|const char *|mount_dir|strlen (mount_dir) + 1

View File

@@ -60,11 +60,12 @@ extern const unsigned long glibtop_server_features;
#define glibtop_init() glibtop_init_r(&glibtop_global_server, 0, 0);
#define glibtop_close() glibtop_close_r(&glibtop_global_server);
#define glibtop_close() glibtop_close_r(glibtop_global_server);
extern glibtop *glibtop_init_r __P((glibtop **, const unsigned long, const unsigned));
extern glibtop *glibtop_init_s __P((glibtop **, const unsigned long, const unsigned));
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -1 +1,3 @@
reference.sgml
Makefile.in
Makefile

9
guile/ChangeLog Normal file
View File

@@ -0,0 +1,9 @@
1998-07-29 Martin Baulig <martin@home-of-linux.org>
* dynamic.c, dynamic_names.c: New files.
* Makefile.am: New file. Creates `libgtop.so' and
`libnames.so' which will be installed in
`$(datadir)/guile/libgtop'; just do a
`(use-modules (libgtop libgtop) (libgtop names))' in
guile to use them.

51
guile/Makefile.am Normal file
View File

@@ -0,0 +1,51 @@
LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@
CFLAGS = -Wall -W @CFLAGS@
sitedir = $(datadir)/guile/site
libgtopmoduledir = $(datadir)/guile/libgtop
libgtopmodule_LTLIBRARIES = libgtop.la libnames.la
libgtop_la_SOURCES = dynamic.c
libnames_la_SOURCES = dynamic_names.c
libgtop_la_LIBADD = ../sysdeps/guile/guile.lo \
../lib/init.lo \
../lib/open.lo \
../lib/close.lo \
../lib/command.lo \
../lib/read.lo \
../lib/read_data.lo \
../lib/write.lo \
../lib/lib.lo \
../lib/parameter.lo \
../lib/sysdeps.lo \
../sysdeps/common/error.lo \
../sysdeps/common/fsusage.lo \
../sysdeps/common/gnuslib.lo \
../sysdeps/common/mountlist.lo \
../sysdeps/common/xmalloc.lo \
../sysdeps/@sysdeps_dir@/close.lo \
../sysdeps/@sysdeps_dir@/proclist.lo \
../sysdeps/@sysdeps_dir@/sem_limits.lo \
../sysdeps/@sysdeps_dir@/cpu.lo \
../sysdeps/@sysdeps_dir@/procmem.lo \
../sysdeps/@sysdeps_dir@/shm_limits.lo \
../sysdeps/@sysdeps_dir@/loadavg.lo \
../sysdeps/@sysdeps_dir@/procsegment.lo \
../sysdeps/@sysdeps_dir@/siglist.lo \
../sysdeps/@sysdeps_dir@/mem.lo \
../sysdeps/@sysdeps_dir@/procsignal.lo \
../sysdeps/@sysdeps_dir@/swap.lo \
../sysdeps/@sysdeps_dir@/msg_limits.lo \
../sysdeps/@sysdeps_dir@/procstate.lo \
../sysdeps/@sysdeps_dir@/uptime.lo \
../sysdeps/@sysdeps_dir@/open.lo \
../sysdeps/@sysdeps_dir@/proctime.lo \
../sysdeps/@sysdeps_dir@/prockernel.lo \
../sysdeps/@sysdeps_dir@/procuid.lo
libnames_la_LIBADD = ../sysdeps/guile/names/guile-names.lo

View File

@@ -19,13 +19,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <glibtop/output.h>
#include <glibtop.h>
#include <libguile/dynl.h>
void
glibtop_output (size_t size, const void *buf)
scm_init_libgtop_libgtop_module (void)
{
if (write (1, &size, sizeof (size_t)) < 0)
_exit (2);
if (write (1, buf, size) < 0)
_exit (2);
scm_register_module_xxx ("libgtop libgtop", glibtop_boot_guile);
}

View File

@@ -19,13 +19,11 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <glibtop/version.h>
#include <glibtop.h>
#include <libguile/dynl.h>
void
glibtop_version (void)
scm_init_libgtop_names_module (void)
{
char buffer [BUFSIZ];
sprintf (buffer, "%s server %s ready.\n", PACKAGE, VERSION);
glibtop_output (strlen (buffer), buffer);
scm_register_module_xxx ("libgtop names", glibtop_boot_guile_names);
}

View File

@@ -6,4 +6,4 @@ glibtop_HEADERS = close.h loadavg.h prockernel.h procstate.h \
procmem.h procuid.h swap.h write.h error.h open.h \
procsegment.h read.h sysdeps.h xmalloc.h global.h \
output.h procsignal.h read_data.h union.h types.h \
parameter.h
parameter.h mountlist.h fsusage.h

View File

@@ -28,6 +28,9 @@ __BEGIN_DECLS
extern void glibtop_close_r __P((glibtop *));
extern void glibtop_close_s __P((glibtop *));
extern void glibtop_close_p __P((glibtop *));
__END_DECLS
#endif

View File

@@ -48,18 +48,22 @@ __BEGIN_DECLS
#define GLIBTOP_CMND_PROC_KERNEL 16
#define GLIBTOP_CMND_PROC_SEGMENT 17
#define GLIBTOP_MAX_CMND 18
#define GLIBTOP_CMND_MOUNTLIST 18
#define GLIBTOP_CMND_FSUSAGE 19
#define GLIBTOP_MAX_CMND 20
#define _GLIBTOP_PARAM_SIZE 16
typedef struct _glibtop_command glibtop_command;
typedef struct _glibtop_response glibtop_response;
typedef union _glibtop_response_union glibtop_response_union;
struct _glibtop_command
{
glibtop server;
unsigned command;
size_t size, data_size;
u_int64_t command;
u_int64_t size, data_size;
char parameter [_GLIBTOP_PARAM_SIZE];
};
@@ -71,9 +75,9 @@ union _glibtop_response_union
struct _glibtop_response
{
off_t offset;
size_t size, data_size;
union _glibtop_response_union u;
int64_t offset;
u_int64_t size, data_size;
glibtop_response_union u;
};
#define glibtop_call(p1, p2, p3, p4) glibtop_call_r(glibtop_global_server, p1, p2, p3, p4)

View File

@@ -40,7 +40,7 @@ typedef struct _glibtop_cpu glibtop_cpu;
struct _glibtop_cpu
{
unsigned long flags,
u_int64_t flags,
total, /* GLIBTOP_CPU_TOTAL */
user, /* GLIBTOP_CPU_USER */
nice, /* GLIBTOP_CPU_NICE */
@@ -65,7 +65,7 @@ extern void glibtop_get_cpu_p __P((glibtop *, glibtop_cpu *));
extern void glibtop_get_cpu_s __P((glibtop *, glibtop_cpu *));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

90
include/glibtop/fsusage.h Normal file
View File

@@ -0,0 +1,90 @@
/* $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_FSUSAGE_H__
#define __GLIBTOP_FSUSAGE_H__
#include <glibtop.h>
#include <glibtop/global.h>
__BEGIN_DECLS
#define GLIBTOP_FSUSAGE_BLOCKS 0
#define GLIBTOP_FSUSAGE_BFREE 1
#define GLIBTOP_FSUSAGE_BAVAIL 2
#define GLIBTOP_FSUSAGE_FILES 3
#define GLIBTOP_FSUSAGE_FFREE 4
#define GLIBTOP_MAX_FSUSAGE 5
typedef struct _glibtop_fsusage glibtop_fsusage;
struct _glibtop_fsusage
{
u_int64_t flags,
blocks, /* Total blocks. */
bfree, /* Free blocks available to superuser. */
bavail, /* Free blocks available to non-superuser. */
files, /* Total file nodes. */
ffree; /* Free file nodes. */
};
#define glibtop_get_fsusage(fsusage,disk) glibtop_get_fsusage_l(glibtop_global_server, fsusage, disk)
#define glibtop_get_fsusage_r glibtop_get_fsusage_s
extern void glibtop_get_fsusage_l __P((glibtop *, glibtop_fsusage *, const char *));
extern void glibtop_get_fsusage_s __P((glibtop *, glibtop_fsusage *, const char *));
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */
extern SCM glibtop_guile_get_fsusage __P((SCM));
#endif
#ifdef GLIBTOP_GUILE_NAMES
/* You need to link with -lgtop_guile_names to get this stuff here. */
extern SCM glibtop_guile_names_fsusage __P((void));
extern SCM glibtop_guile_types_fsusage __P((void));
extern SCM glibtop_guile_labels_fsusage __P((void));
extern SCM glibtop_guile_descriptions_fsusage __P((void));
#endif
#ifdef GLIBTOP_NAMES
/* You need to link with -lgtop_names to get this stuff here. */
extern const char *glibtop_names_fsusage [];
extern const unsigned glibtop_types_fsusage [];
extern const char *glibtop_labels_fsusage [];
extern const char *glibtop_descriptions_fsusage [];
#endif
__END_DECLS
#endif

View File

@@ -63,11 +63,11 @@
#endif
#ifdef WITHOUT_GUILE
#undef HAVE_GUILE
#undef GLIBTOP_GUILE
#undef GLIBTOP_GUILE_NAMES
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
#include <guile/gh.h>
#endif

View File

@@ -54,10 +54,8 @@ static char header_rcsid [] = "!Header: gnuserv.h,v 2.4 95/02/16 11:58:11 arup a
* sockets with sysv ipc
*/
#define INTERNET_DOMAIN_SOCKETS
// #define UNIX_DOMAIN_SOCKETS
// #define SYSV_IPC
#define UNIX_DOMAIN_SOCKETS
/*
* Define additional authentication protocols to be used. These methods will
@@ -91,15 +89,13 @@ static char header_rcsid [] = "!Header: gnuserv.h,v 2.4 95/02/16 11:58:11 arup a
* Pick a default communication scheme, if none was specified.
*/
#if !defined(SYSV_IPC) && !defined(UNIX_DOMAIN_SOCKETS) && !defined(INTERNET_DOMAIN_SOCKETS)
#if !defined(UNIX_DOMAIN_SOCKETS) && !defined(INTERNET_DOMAIN_SOCKETS)
#ifdef HAVE_SYSVIPC
#define SYSV_IPC /* SYSV systems use SYSV IPC by default */
#endif /* HAVE_SYSVIPC */
/* BSD systems use Unix Domain sockets by default */
#ifdef BSD
#define UNIX_DOMAIN_SOCKETS /* BSD systems use Unix Domain sockets by default */
#endif /* BSD */
#define UNIX_DOMAIN_SOCKETS
#endif
#endif /* No communication method pre-defined */
@@ -111,24 +107,6 @@ static char header_rcsid [] = "!Header: gnuserv.h,v 2.4 95/02/16 11:58:11 arup a
* what you want.
*/
# define GSERV_BUFSZ BUFSIZ
#ifdef SYSV_IPC
#include <sys/ipc.h>
#include <sys/msg.h>
#define send_string(s,str) \
if (strlen(msgp->mtext) + strlen(str) < GSERV_BUFSZ) \
strcat(msgp->mtext,str); \
else \
{ \
fprintf(stderr,"%s: not enough message buffer space\n",progname); \
exit(1); \
} \
#endif /* SYSV_IPC */
#if defined(INTERNET_DOMAIN_SOCKETS) || defined(UNIX_DOMAIN_SOCKETS)
#include <sys/socket.h>
#endif /* INTERNET_DOMAIN_SOCKETS || UNIX_DOMAIN_SOCKETS */
@@ -155,9 +133,6 @@ static char header_rcsid [] = "!Header: gnuserv.h,v 2.4 95/02/16 11:58:11 arup a
#undef TRUE
#define TRUE 1
// extern char *optarg;
// extern int optind;
/* The casts shut Sun's compiler up and are safe in the context these
are actually used. */
#define max2(x,y) (((int) (x) > (int) (y)) ? (x) : (y))
@@ -178,16 +153,6 @@ static char header_rcsid [] = "!Header: gnuserv.h,v 2.4 95/02/16 11:58:11 arup a
/* function declarations */
extern int glibtop_make_connection __P((const char *, int, int *));
#ifdef SYSV_IPC
void disconnect_from_ipc_server();
#endif
#if defined(INTERNET_DOMAIN_SOCKETS) || defined(UNIX_DOMAIN_SOCKETS)
// void send_string (int s, const char *msg);
// void disconnect_from_server (int s, int echo);
// int read_line (int s, char *dest);
#endif
#ifdef INTERNET_DOMAIN_SOCKETS
extern long glibtop_internet_addr __P((const char *));
#endif

View File

@@ -35,7 +35,7 @@ typedef struct _glibtop_loadavg glibtop_loadavg;
struct _glibtop_loadavg
{
unsigned long flags;
u_int64_t flags;
double loadavg [3]; /* GLIBTOP_LOADAVG_LOADAVG */
};
@@ -55,7 +55,7 @@ extern void glibtop_get_loadavg_p __P((glibtop *, glibtop_loadavg *));
extern void glibtop_get_loadavg_s __P((glibtop *, glibtop_loadavg *));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -42,7 +42,7 @@ typedef struct _glibtop_mem glibtop_mem;
struct _glibtop_mem
{
unsigned long flags,
u_int64_t flags,
total, /* GLIBTOP_MEM_TOTAL */
used, /* GLIBTOP_MEM_USED */
free, /* GLIBTOP_MEM_FREE */
@@ -69,7 +69,7 @@ extern void glibtop_get_mem_p __P((glibtop *, glibtop_mem *));
extern void glibtop_get_mem_s __P((glibtop *, glibtop_mem *));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -0,0 +1,98 @@
/* $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_MOUNTLIST_H__
#define __GLIBTOP_MOUNTLIST_H__
#include <glibtop.h>
#include <glibtop/global.h>
__BEGIN_DECLS
#define GLIBTOP_MOUNTLIST_NUMBER 0
#define GLIBTOP_MOUNTLIST_TOTAL 1
#define GLIBTOP_MOUNTLIST_SIZE 2
#define GLIBTOP_MAX_MOUNTLIST 3
#define GLIBTOP_MOUNTENTRY_LEN 79
typedef struct _glibtop_mountentry glibtop_mountentry;
typedef struct _glibtop_mountlist glibtop_mountlist;
struct _glibtop_mountentry
{
u_int64_t dev;
char devname [GLIBTOP_MOUNTENTRY_LEN+1];
char mountdir [GLIBTOP_MOUNTENTRY_LEN+1];
char type [GLIBTOP_MOUNTENTRY_LEN+1];
};
struct _glibtop_mountlist
{
u_int64_t flags,
number, /* GLIBTOP_MOUNTLIST_NUMBER */
total, /* GLIBTOP_MOUNTLIST_TOTAL */
size; /* GLIBTOP_MOUNTLIST_SIZE */
};
#define glibtop_get_mountlist(mountlist,all_fs) glibtop_get_mountlist_l(glibtop_global_server, mountlist, all_fs)
#define glibtop_get_mountlist_r glibtop_get_mountlist_s
extern glibtop_mountentry *glibtop_get_mountlist_l __P((glibtop *, glibtop_mountlist *, int));
extern glibtop_mountentry *glibtop_get_mountlist_s __P((glibtop *, glibtop_mountlist *, int));
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */
extern SCM glibtop_guile_get_mountlist __P((SCM));
#endif
#ifdef GLIBTOP_GUILE_NAMES
/* You need to link with -lgtop_guile_names to get this stuff here. */
extern SCM glibtop_guile_names_mountlist __P((void));
extern SCM glibtop_guile_types_mountlist __P((void));
extern SCM glibtop_guile_labels_mountlist __P((void));
extern SCM glibtop_guile_descriptions_mountlist __P((void));
#endif
#ifdef GLIBTOP_NAMES
/* You need to link with -lgtop_names to get this stuff here. */
extern const char *glibtop_names_mountlist [];
extern const unsigned glibtop_types_mountlist [];
extern const char *glibtop_labels_mountlist [];
extern const char *glibtop_descriptions_mountlist [];
#endif
__END_DECLS
#endif

View File

@@ -41,7 +41,7 @@ typedef struct _glibtop_msg_limits glibtop_msg_limits;
struct _glibtop_msg_limits
{
unsigned long flags,
u_int64_t flags,
msgpool, /* GLIBTOP_IPC_MSGPOOL */
msgmap, /* GLIBTOP_IPC_MSGMAP */
msgmax, /* GLIBTOP_IPC_MSGMAX */
@@ -67,7 +67,7 @@ extern void glibtop_get_msg_limits_p __P((glibtop *, glibtop_msg_limits *));
extern void glibtop_get_msg_limits_s __P((glibtop *, glibtop_msg_limits *));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -33,15 +33,18 @@ __BEGIN_DECLS
#define GLIBTOP_INIT_NO_OPEN 1
#define GLIBTOP_INIT_NO_INIT 2
#define GLIBTOP_OPEN_NO_OVERRIDE 1
#define GLIBTOP_FEATURES_NO_SERVER 4
#define GLIBTOP_FEATURES_EXCEPT 8
#define GLIBTOP_METHOD_DIRECT 1
#define GLIBTOP_METHOD_PIPE 2
#define GLIBTOP_METHOD_INET 3
#define GLIBTOP_METHOD_UNIX 4
extern void glibtop_open_l __P((glibtop *, const char *, const unsigned long, const unsigned));
extern void glibtop_open_r __P((glibtop *, const char *, const unsigned long, const unsigned));
extern void glibtop_open_p __P((glibtop *, const char *, const unsigned long, const unsigned));
extern void glibtop_open_s __P((glibtop *, const char *, const unsigned long, const unsigned));
__END_DECLS

View File

@@ -44,8 +44,8 @@ typedef struct _glibtop_proc_kernel glibtop_proc_kernel;
struct _glibtop_proc_kernel
{
unsigned long flags;
unsigned long k_flags, /* kernel flags for the process */
u_int64_t flags;
u_int64_t k_flags, /* kernel flags for the process */
min_flt, /* number of minor page faults since
* process start */
maj_flt, /* number of major page faults since
@@ -76,7 +76,7 @@ extern void glibtop_get_proc_kernel_p __P((glibtop *, glibtop_proc_kernel *, pid
extern void glibtop_get_proc_kernel_s __P((glibtop *, glibtop_proc_kernel *, pid_t));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -37,7 +37,7 @@ typedef struct _glibtop_proclist glibtop_proclist;
struct _glibtop_proclist
{
unsigned long flags,
u_int64_t flags,
number, /* GLIBTOP_PROCLIST_NUMBER */
total, /* GLIBTOP_PROCLIST_TOTAL */
size; /* GLIBTOP_PROCLIST_SIZE */
@@ -59,7 +59,7 @@ extern unsigned *glibtop_get_proclist_p __P((glibtop *, glibtop_proclist *));
extern unsigned *glibtop_get_proclist_s __P((glibtop *, glibtop_proclist *));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -42,8 +42,8 @@ typedef struct _glibtop_proc_mem glibtop_proc_mem;
struct _glibtop_proc_mem
{
unsigned long flags;
long size, /* total # of pages of memory */
u_int64_t flags,
size, /* total # of pages of memory */
vsize, /* number of pages of virtual memory ... */
resident, /* number of resident set
* (non-swapped) pages (4k) */
@@ -69,7 +69,7 @@ extern void glibtop_get_proc_mem_p __P((glibtop *, glibtop_proc_mem *, pid_t));
extern void glibtop_get_proc_mem_s __P((glibtop *, glibtop_proc_mem *, pid_t));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -43,12 +43,12 @@ typedef struct _glibtop_proc_segment glibtop_proc_segment;
struct _glibtop_proc_segment
{
unsigned long flags;
long trs, /* text resident set size */
u_int64_t flags,
trs, /* text resident set size */
lrs, /* shared-lib resident set size */
drs, /* data resident set size */
dt; /* dirty pages */
unsigned long start_code,
dt, /* dirty pages */
start_code,
/* address of beginning of code segment */
end_code, /* address of end of code segment */
start_stack; /* address of the bottom of stack segment */
@@ -70,7 +70,7 @@ extern void glibtop_get_proc_segment_p __P((glibtop *, glibtop_proc_segment *, p
extern void glibtop_get_proc_segment_s __P((glibtop *, glibtop_proc_segment *, pid_t));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -40,11 +40,11 @@ typedef struct _glibtop_proc_signal glibtop_proc_signal;
struct _glibtop_proc_signal
{
unsigned long flags;
int signal, /* mask of pending signals */
blocked, /* mask of blocked signals */
sigignore, /* mask of ignored signals */
sigcatch; /* mask of caught signals */
u_int64_t flags,
signal, /* mask of pending signals */
blocked, /* mask of blocked signals */
sigignore, /* mask of ignored signals */
sigcatch; /* mask of caught signals */
};
#define glibtop_get_proc_signal(p1, p2) glibtop_get_proc_signal_l(glibtop_global_server, p1, p2)
@@ -63,7 +63,7 @@ extern void glibtop_get_proc_signal_p __P((glibtop *, glibtop_proc_signal *, pid
extern void glibtop_get_proc_signal_s __P((glibtop *, glibtop_proc_signal *, pid_t));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -40,7 +40,7 @@ typedef struct _glibtop_proc_state glibtop_proc_state;
struct _glibtop_proc_state
{
unsigned long flags;
u_int64_t flags;
char cmd[40], /* basename of executable file in
* call to exec(2) */
state; /* single-char code for process state
@@ -70,7 +70,7 @@ extern void glibtop_get_proc_state_p __P((glibtop *, glibtop_proc_state *, pid_t
extern void glibtop_get_proc_state_s __P((glibtop *, glibtop_proc_state *, pid_t));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -43,8 +43,8 @@ typedef struct _glibtop_proc_time glibtop_proc_time;
struct _glibtop_proc_time
{
unsigned long flags;
long start_time, /* start time of process --
u_int64_t flags,
start_time, /* start time of process --
* seconds since 1-1-70 */
utime, /* user-mode CPU time accumulated by process */
stime, /* kernel-mode CPU time accumulated by process */
@@ -75,7 +75,7 @@ extern void glibtop_get_proc_time_p __P((glibtop *, glibtop_proc_time *, pid_t))
extern void glibtop_get_proc_time_s __P((glibtop *, glibtop_proc_time *, pid_t));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -48,7 +48,7 @@ typedef struct _glibtop_proc_uid glibtop_proc_uid;
struct _glibtop_proc_uid
{
unsigned long flags;
u_int64_t flags;
int uid, /* user id */
euid, /* effective user id */
gid, /* group id */
@@ -79,7 +79,7 @@ extern void glibtop_get_proc_uid_p __P((glibtop *, glibtop_proc_uid *, pid_t));
extern void glibtop_get_proc_uid_s __P((glibtop *, glibtop_proc_uid *, pid_t));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -44,7 +44,7 @@ typedef struct _glibtop_sem_limits glibtop_sem_limits;
struct _glibtop_sem_limits
{
unsigned long flags,
u_int64_t flags,
semmap, /* GLIBTOP_IPC_SEMMAP */
semmni, /* GLIBTOP_IPC_SEMMNI */
semmns, /* GLIBTOP_IPC_SEMMNS */
@@ -73,7 +73,7 @@ extern void glibtop_get_sem_limits_p __P((glibtop *, glibtop_sem_limits *));
extern void glibtop_get_sem_limits_s __P((glibtop *, glibtop_sem_limits *));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -39,7 +39,7 @@ typedef struct _glibtop_shm_limits glibtop_shm_limits;
struct _glibtop_shm_limits
{
unsigned long flags,
u_int64_t flags,
shmmax, /* GLIBTOP_IPC_SHMMAX */
shmmin, /* GLIBTOP_IPC_SHMMIN */
shmmni, /* GLIBTOP_IPC_SHMMNI */
@@ -63,7 +63,7 @@ extern void glibtop_get_shm_limits_p __P((glibtop *, glibtop_shm_limits *));
extern void glibtop_get_shm_limits_s __P((glibtop *, glibtop_shm_limits *));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

45
include/glibtop/signal.h Normal file
View File

@@ -0,0 +1,45 @@
/* $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_SIGNAL_H__
#define __GLIBTOP_SIGNAL_H__
#include <glibtop.h>
#ifdef HAVE_SYS_SIGNAL_H
#include <sys/signal.h>
#endif
__BEGIN_DECLS
typedef struct _glibtop_signame glibtop_signame;
struct _glibtop_signame
{
const int number;
const char *name, *label;
};
extern const glibtop_signame glibtop_sys_siglist [];
__END_DECLS
#endif

View File

@@ -30,17 +30,21 @@ __BEGIN_DECLS
#define GLIBTOP_SWAP_TOTAL 0
#define GLIBTOP_SWAP_USED 1
#define GLIBTOP_SWAP_FREE 2
#define GLIBTOP_SWAP_PAGEIN 3
#define GLIBTOP_SWAP_PAGEOUT 4
#define GLIBTOP_MAX_SWAP 3
#define GLIBTOP_MAX_SWAP 5
typedef struct _glibtop_swap glibtop_swap;
struct _glibtop_swap
{
unsigned long flags,
u_int64_t flags,
total, /* GLIBTOP_SWAP_TOTAL */
used, /* GLIBTOP_SWAP_USED */
free; /* GLIBTOP_SWAP_FREE */
free, /* GLIBTOP_SWAP_FREE */
pagein, /* GLIBTOP_SWAP_PAGEIN */
pageout; /* GLIBTOP_SWAP_PAGEOUT */
};
#define glibtop_get_swap(swap) glibtop_get_swap_l(glibtop_global_server, swap)
@@ -59,7 +63,7 @@ extern void glibtop_get_swap_p __P((glibtop *, glibtop_swap *));
extern void glibtop_get_swap_s __P((glibtop *, glibtop_swap *));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -44,8 +44,10 @@ __BEGIN_DECLS
#define GLIBTOP_SYSDEPS_PROC_SIGNAL 14
#define GLIBTOP_SYSDEPS_PROC_KERNEL 15
#define GLIBTOP_SYSDEPS_PROC_SEGMENT 16
#define GLIBTOP_SYSDEPS_MOUNTLIST 17
#define GLIBTOP_SYSDEPS_FSUSAGE 18
#define GLIBTOP_MAX_SYSDEPS 17
#define GLIBTOP_MAX_SYSDEPS 19
#define GLIBTOP_SYSDEPS_ALL ((1 << GLIBTOP_MAX_SYSDEPS) - 1)
@@ -53,7 +55,7 @@ typedef struct _glibtop_sysdeps glibtop_sysdeps;
struct _glibtop_sysdeps
{
unsigned long flags,
u_int64_t flags,
features, /* server features */
cpu, /* glibtop_cpu */
mem, /* glibtop_mem */
@@ -70,14 +72,16 @@ struct _glibtop_sysdeps
proc_time, /* glibtop_proc_time */
proc_signal, /* glibtop_proc_signal */
proc_kernel, /* glibtop_proc_kernel */
proc_segment; /* glibtop_proc_segment */
proc_segment, /* glibtop_proc_segment */
mountlist, /* glibtop_mountlist */
fsusage; /* glibtop_fsusage */
};
#define glibtop_get_sysdeps(sysdeps) glibtop_get_sysdeps_r(glibtop_global_server,sysdeps)
extern void glibtop_get_sysdeps_r __P((glibtop *, glibtop_sysdeps *));
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -40,6 +40,9 @@
#include <glibtop/prockernel.h>
#include <glibtop/procsegment.h>
#include <glibtop/mountlist.h>
#include <glibtop/fsusage.h>
__BEGIN_DECLS
typedef union _glibtop_union glibtop_union;
@@ -62,6 +65,8 @@ union _glibtop_union
glibtop_proc_signal proc_signal;
glibtop_proc_kernel proc_kernel;
glibtop_proc_segment proc_segment;
glibtop_mountlist mountlist;
glibtop_fsusage fsusage;
};
__END_DECLS

View File

@@ -36,7 +36,7 @@ typedef struct _glibtop_uptime glibtop_uptime;
struct _glibtop_uptime
{
unsigned long flags;
u_int64_t flags;
double uptime, /* GLIBTOP_UPTIME_UPTIME */
idletime; /* GLIBTOP_UPTIME_IDLETIME */
};
@@ -57,7 +57,7 @@ extern void glibtop_get_uptime_p __P((glibtop *, glibtop_uptime *));
extern void glibtop_get_uptime_s __P((glibtop *, glibtop_uptime *));
#endif
#ifdef HAVE_GUILE
#ifdef GLIBTOP_GUILE
/* You need to link with -lgtop_guile to get this stuff here. */

View File

@@ -1,3 +1,11 @@
1998-07-21 Martin Baulig <martin@home-of-linux.org>
* table20: New directory for 2.0.xx kernels.
* table21: New directory for 2.1.xx kernels.
* *: Moved into `table20' and `table21'.
1998-06-14 Martin Baulig <baulig@taurus.uni-trier.de>
* README: Added README.

View File

@@ -3,6 +3,8 @@
#ifdef _KERNEL
#include <linux/types.h>
#else
#define NR_TASKS 512
#endif
#define TABLE_VERSION 0
@@ -11,13 +13,14 @@
#define TABLE_SWAP 3
#define TABLE_LOADAVG 4
#define TABLE_UPTIME 5
#define TABLE_PROC_UID 6
#define TABLE_PROC_MEM 7
#define TABLE_PROC_SEGMENT 8
#define TABLE_PROC_TIME 9
#define TABLE_PROC_STATE 10
#define TABLE_PROC_SIGNAL 11
#define TABLE_PROC_KERNEL 12
#define TABLE_PROCLIST 6
#define TABLE_PROC_UID 7
#define TABLE_PROC_MEM 8
#define TABLE_PROC_SEGMENT 9
#define TABLE_PROC_TIME 10
#define TABLE_PROC_STATE 11
#define TABLE_PROC_SIGNAL 12
#define TABLE_PROC_KERNEL 13
/* CPU Usage (in jiffies = 1/100th seconds) */
@@ -50,6 +53,8 @@ struct table_swap
unsigned long total; /* Total swap space */
unsigned long used; /* Used swap space */
unsigned long free; /* Free swap space */
unsigned long pagein; /* Total # of pages swapped in */
unsigned long pageout; /* Total # of pages swapped out */
};
/* Load average */
@@ -70,6 +75,14 @@ struct table_uptime
unsigned long idle;
};
/* Process list. */
struct table_proclist
{
int nr_running, nr_tasks, last_pid;
unsigned pids [NR_TASKS];
};
/* Information about processes. */
struct table_proc_state
@@ -118,10 +131,10 @@ struct table_proc_time
struct table_proc_signal
{
unsigned long signal;
unsigned long blocked; /* bitmap of masked signals */
unsigned long ignored; /* mask of ignored signals */
unsigned long caught; /* mask of caught signals */
unsigned long long signal,
blocked, /* bitmap of masked signals */
ignored, /* mask of ignored signals */
caught; /* mask of caught signals */
};
struct table_proc_kernel
@@ -140,6 +153,7 @@ union table
struct table_swap swap;
struct table_loadavg loadavg;
struct table_uptime uptime;
struct table_proclist proclist;
struct table_proc_uid proc_uid;
struct table_proc_mem proc_mem;
struct table_proc_segment proc_segment;

View File

@@ -28,14 +28,16 @@ diff -ur linux-2.0.32/Makefile linux-hacked/Makefile
diff -ur linux-2.0.32/arch/i386/kernel/entry.S linux-hacked/arch/i386/kernel/entry.S
--- linux-2.0.32/arch/i386/kernel/entry.S Tue Sep 16 23:42:45 1997
+++ linux-hacked/arch/i386/kernel/entry.S Thu Jun 11 21:37:20 1998
@@ -699,4 +699,6 @@
@@ -699,4 +699,8 @@
.long SYMBOL_NAME(sys_mremap)
.long 0,0
.long SYMBOL_NAME(sys_vm86)
- .space (NR_syscalls-166)*4
+ .long 0
+ .long 0,0,0,0 /* 170 */
+ .long 0,0,0,0,0,0,0,0,0,0 /* 180 */
+ .long 0,0,0,0,0,0,0
+ .long SYMBOL_NAME(sys_table)
+ .space (NR_syscalls-168)*4
+ .space (NR_syscalls-188)*4
diff -ur linux-2.0.32/include/asm-i386/unistd.h linux-hacked/include/asm-i386/unistd.h
--- linux-2.0.32/include/asm-i386/unistd.h Fri Mar 22 07:34:02 1996
+++ linux-hacked/include/asm-i386/unistd.h Thu Jun 11 21:37:03 1998
@@ -43,7 +45,7 @@ diff -ur linux-2.0.32/include/asm-i386/unistd.h linux-hacked/include/asm-i386/un
#define __NR_sched_rr_get_interval 161
#define __NR_nanosleep 162
#define __NR_mremap 163
+#define __NR_table 168
+#define __NR_table 188
/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
#define _syscall0(type,name) \

View File

@@ -189,8 +189,8 @@ sys_table (int type, union table *buf, const void *param)
union table tbl;
struct sysinfo i;
struct task_struct *tsk = NULL;
int index, err;
pid_t pid;
int err;
if (type == TABLE_VERSION)
return _TABLE_VERSION;
@@ -224,12 +224,23 @@ sys_table (int type, union table *buf, const void *param)
/* Main function dispatcher */
switch (type) {
case TABLE_PROCLIST:
tsk = task [0];
for (index = 0; index < nr_tasks; index++) {
tbl.proclist.pids [index] = tsk->pid;
tsk = tsk->next_task;
}
tbl.proclist.nr_running = nr_running;
tbl.proclist.nr_tasks = nr_tasks;
tbl.proclist.last_pid = last_pid;
break;
case TABLE_CPU:
tbl.cpu.total = jiffies;
tbl.cpu.user = kstat.cpu_user;
tbl.cpu.nice = kstat.cpu_nice;
tbl.cpu.sys = kstat.cpu_system;
tbl.cpu.idle = tbl.cpu.total - (tbl.cpu.user + tbl.cpu.nice + tbl.cpu.sys);
tbl.cpu.idle = tbl.cpu.total -
(tbl.cpu.user + tbl.cpu.nice + tbl.cpu.sys);
tbl.cpu.frequency = HZ;
break;
case TABLE_MEM:
@@ -246,6 +257,8 @@ sys_table (int type, union table *buf, const void *param)
tbl.swap.total = i.totalswap;
tbl.swap.used = i.totalswap - i.freeswap;
tbl.swap.free = i.freeswap;
tbl.swap.pagein = kstat.pswpin;
tbl.swap.pageout = kstat.pswpout;
break;
case TABLE_LOADAVG:
tbl.loadavg.loadavg [0] = (double) avenrun [0] / (1 << FSHIFT);
@@ -262,7 +275,8 @@ sys_table (int type, union table *buf, const void *param)
case TABLE_PROC_STATE:
tbl.proc_state.state = tsk->state;
tbl.proc_state.flags = tsk->flags;
memcpy (tbl.proc_state.comm, tsk->comm, sizeof (tbl.proc_state.comm));
memcpy (tbl.proc_state.comm, tsk->comm,
sizeof (tbl.proc_state.comm));
break;
case TABLE_PROC_UID:
tbl.proc_uid.uid = tsk->uid;
@@ -280,7 +294,8 @@ sys_table (int type, union table *buf, const void *param)
tbl.proc_uid.ppid = tsk->p_pptr->pid;
tbl.proc_uid.session = tsk->session;
tbl.proc_uid.tty = tsk->tty ? kdev_t_to_nr (tsk->tty->device) : 0;
tbl.proc_uid.tty = tsk->tty ?
kdev_t_to_nr (tsk->tty->device) : 0;
tbl.proc_uid.tpgid = tsk->tty ? tsk->tty->pgrp : -1;
tbl.proc_uid.priority = tsk->priority;
@@ -337,7 +352,8 @@ sys_table (int type, union table *buf, const void *param)
tbl.proc_mem.total_vm = tsk->mm->total_vm;
tbl.proc_mem.locked_vm = tsk->mm->locked_vm;
}
tbl.proc_mem.rlim = tsk->rlim ? tsk->rlim[RLIMIT_RSS].rlim_cur : 0;
tbl.proc_mem.rlim = tsk->rlim ?
tsk->rlim[RLIMIT_RSS].rlim_cur : 0;
break;
case TABLE_PROC_SEGMENT:
if (tsk->mm && tsk->mm != &init_mm) {

16
kernel/table21/Makefile Normal file
View File

@@ -0,0 +1,16 @@
#
# Makefile for the linux system information tables.
#
# Note! Dependencies are done automagically by 'make dep', which also
# removes any old dependencies. DON'T put your own dependencies here
# unless it's something special (ie not a .c file).
#
# Note 2! The CFLAGS definition is now in the main makefile...
O_TARGET := table.o
OX_OBJS := main.o
M_TARGET := module.o
MX_OBJS := module.o
include $(TOPDIR)/Rules.make

21
kernel/table21/README Normal file
View File

@@ -0,0 +1,21 @@
This is a new system call `table ()' for the Linux table. It is faster
than reading from /proc and can be used to fetch all information required
for libgtop until whe have some other function (extended sysctl, ...) in
standard kernels.
I didn't want to change sysctl or some other function myself cause this may
cause other applications relying upon those function to fail. This is
something for the ``real'' kernel gurus ...
To use this new system call for libgtop, do the following:
* Copy this directory to /usr/src/linux/table
* Make /usr/src/linux/include/linux/table.h symlink to /usr/src/linux/table/table.h
* Apply the patch `kernel.patch' to the kernel, compile, install and reboot
* Recompile libgtop (remove `config.cache' and run the `autogen.sh' again).
If you want to change and/or add something - feel free to do so !
Have fun,
Martin

61
kernel/table21/main.c Normal file
View File

@@ -0,0 +1,61 @@
/*
* linux/table/table_impl.c
* Copyright (C) 1998 Martin Baulig
*/
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/tty.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/string.h>
#include <linux/mman.h>
#include <linux/proc_fs.h>
#include <linux/ioport.h>
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/io.h>
#include <linux/module.h>
#include <linux/table.h>
#include "version.h"
extern void scheduling_functions_start_here(void);
extern void scheduling_functions_end_here(void);
int (*table_function_ptr) (int, union table *, const void *) = 0;
EXPORT_SYMBOL(table_function_ptr);
EXPORT_SYMBOL(nr_running);
EXPORT_SYMBOL(pidhash);
EXPORT_SYMBOL(task);
EXPORT_SYMBOL(si_swapinfo);
EXPORT_SYMBOL(scheduling_functions_start_here);
EXPORT_SYMBOL(scheduling_functions_end_here);
EXPORT_SYMBOL(avenrun);
EXPORT_SYMBOL(nr_tasks);
EXPORT_SYMBOL(last_pid);
EXPORT_SYMBOL(page_cache_size);
EXPORT_SYMBOL(init_mm);
asmlinkage int
sys_table (int type, union table *buf, const void *param)
{
if (table_function_ptr == 0)
return -ENOSYS;
return (*table_function_ptr) (type, buf, param);
}

551
kernel/table21/module.c Normal file
View File

@@ -0,0 +1,551 @@
/*
* linux/table/table_impl.c
* Copyright (C) 1998 Martin Baulig
*/
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/tty.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/string.h>
#include <linux/mman.h>
#include <linux/proc_fs.h>
#include <linux/ioport.h>
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/signal.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/io.h>
#include <linux/module.h>
#include <linux/table.h>
#include "version.h"
extern int (*table_function_ptr) (int, union table *, const void *);
int table_fkt (int, union table *, const void *);
EXPORT_NO_SYMBOLS;
int
init_module(void)
{
printk ("init_module () = %p - %d, %d\n",
table_fkt, sizeof (union table), sizeof (sigset_t));
table_function_ptr = table_fkt;
return 0;
}
void
cleanup_module(void)
{
table_function_ptr = 0;
}
#define LOAD_INT(x) ((x) >> FSHIFT)
#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
#ifdef CONFIG_DEBUG_MALLOC
int get_malloc(char * buffer);
#endif
static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
sigset_t *catch)
{
struct k_sigaction *k;
int i;
sigemptyset(ign);
sigemptyset(catch);
#if 0
printk ("collect_sigign_sigcatch: %p - %p\n",
p, p->sig);
#endif
if (p->sig) {
k = p->sig->action;
for (i = 1; i <= _NSIG; ++i, ++k) {
#if 0
printk ("signal: %d - %p (%p, %p)\n",
i, k->sa.sa_handler, SIG_IGN, SIG_DFL);
#endif
if (k->sa.sa_handler == SIG_IGN)
sigaddset(ign, i);
else if (k->sa.sa_handler != SIG_DFL)
sigaddset(catch, i);
}
}
}
/*
* These bracket the sleeping functions..
*/
extern void scheduling_functions_start_here(void);
extern void scheduling_functions_end_here(void);
#define first_sched ((unsigned long) scheduling_functions_start_here)
#define last_sched ((unsigned long) scheduling_functions_end_here)
static unsigned long get_wchan(struct task_struct *p)
{
if (!p || p == current || p->state == TASK_RUNNING)
return 0;
#if defined(__i386__)
{
unsigned long ebp, eip;
unsigned long stack_page;
int count = 0;
stack_page = 4096 + (unsigned long)p;
if (!stack_page)
return 0;
ebp = p->tss.ebp;
do {
if (ebp < stack_page || ebp >= 4092+stack_page)
return 0;
eip = *(unsigned long *) (ebp+4);
if (eip < first_sched || eip >= last_sched)
return eip;
ebp = *(unsigned long *) ebp;
} while (count++ < 16);
}
#elif defined(__alpha__)
/*
* This one depends on the frame size of schedule(). Do a
* "disass schedule" in gdb to find the frame size. Also, the
* code assumes that sleep_on() follows immediately after
* interruptible_sleep_on() and that add_timer() follows
* immediately after interruptible_sleep(). Ugly, isn't it?
* Maybe adding a wchan field to task_struct would be better,
* after all...
*/
{
unsigned long schedule_frame;
unsigned long pc;
pc = thread_saved_pc(&p->tss);
if (pc >= first_sched && pc < last_sched) {
schedule_frame = ((unsigned long *)p->tss.ksp)[6];
return ((unsigned long *)schedule_frame)[12];
}
return pc;
}
#elif defined(__mc68000__)
{
unsigned long fp, pc;
unsigned long stack_page;
int count = 0;
extern int sys_pause (void);
stack_page = p->kernel_stack_page;
if (!stack_page)
return 0;
fp = ((struct switch_stack *)p->tss.ksp)->a6;
do {
if (fp < stack_page || fp >= 4088+stack_page)
return 0;
pc = ((unsigned long *)fp)[1];
/* FIXME: This depends on the order of these functions. */
if (pc < first_sched || pc >= last_sched)
return pc;
fp = *(unsigned long *) fp;
} while (count++ < 16);
}
#elif defined(__powerpc__)
return (p->tss.wchan);
#elif defined (CONFIG_ARM)
{
unsigned long fp, lr;
unsigned long stack_page;
int count = 0;
stack_page = 4096 + (unsigned long)p;
fp = get_css_fp (&p->tss);
do {
if (fp < stack_page || fp > 4092+stack_page)
return 0;
lr = pc_pointer (((unsigned long *)fp)[-1]);
if (lr < first_sched || lr > last_sched)
return lr;
fp = *(unsigned long *) (fp - 12);
} while (count ++ < 16);
}
#endif
return 0;
}
#if defined(__i386__)
# define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019])
# define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
#elif defined(__alpha__)
/*
* See arch/alpha/kernel/ptrace.c for details.
*/
# define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \
+ (long)&((struct pt_regs *)0)->reg)
# define KSTK_EIP(tsk) \
(*(unsigned long *)(PT_REG(pc) + PAGE_SIZE + (unsigned long)(tsk)))
# define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp)
#elif defined(CONFIG_ARM)
# define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
# define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020])
#elif defined(__mc68000__)
#define KSTK_EIP(tsk) \
({ \
unsigned long eip = 0; \
if ((tsk)->tss.esp0 > PAGE_SIZE && \
MAP_NR((tsk)->tss.esp0) < max_mapnr) \
eip = ((struct pt_regs *) (tsk)->tss.esp0)->pc; \
eip; })
#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp)
#elif defined(__powerpc__)
#define KSTK_EIP(tsk) ((tsk)->tss.regs->nip)
#define KSTK_ESP(tsk) ((tsk)->tss.regs->gpr[1])
#elif defined (__sparc_v9__)
# define KSTK_EIP(tsk) ((tsk)->tss.kregs->tpc)
# define KSTK_ESP(tsk) ((tsk)->tss.kregs->u_regs[UREG_FP])
#elif defined(__sparc__)
# define KSTK_EIP(tsk) ((tsk)->tss.kregs->pc)
# define KSTK_ESP(tsk) ((tsk)->tss.kregs->u_regs[UREG_FP])
#endif
/* Gcc optimizes away "strlen(x)" for constant x */
#define ADDBUF(buffer, string) \
do { memcpy(buffer, string, strlen(string)); \
buffer += strlen(string); } while (0)
static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned long size,
int * pages, int * shared, int * dirty, int * total)
{
pte_t * pte;
unsigned long end;
if (pmd_none(*pmd))
return;
if (pmd_bad(*pmd)) {
printk("statm_pte_range: bad pmd (%08lx)\n", pmd_val(*pmd));
pmd_clear(pmd);
return;
}
pte = pte_offset(pmd, address);
address &= ~PMD_MASK;
end = address + size;
if (end > PMD_SIZE)
end = PMD_SIZE;
do {
pte_t page = *pte;
address += PAGE_SIZE;
pte++;
if (pte_none(page))
continue;
++*total;
if (!pte_present(page))
continue;
++*pages;
if (pte_dirty(page))
++*dirty;
if (MAP_NR(pte_page(page)) >= max_mapnr)
continue;
if (atomic_read(&mem_map[MAP_NR(pte_page(page))].count) > 1)
++*shared;
} while (address < end);
}
static inline void statm_pmd_range(pgd_t * pgd, unsigned long address, unsigned long size,
int * pages, int * shared, int * dirty, int * total)
{
pmd_t * pmd;
unsigned long end;
if (pgd_none(*pgd))
return;
if (pgd_bad(*pgd)) {
printk("statm_pmd_range: bad pgd (%08lx)\n", pgd_val(*pgd));
pgd_clear(pgd);
return;
}
pmd = pmd_offset(pgd, address);
address &= ~PGDIR_MASK;
end = address + size;
if (end > PGDIR_SIZE)
end = PGDIR_SIZE;
do {
statm_pte_range(pmd, address, end - address, pages, shared, dirty, total);
address = (address + PMD_SIZE) & PMD_MASK;
pmd++;
} while (address < end);
}
static void statm_pgd_range(pgd_t * pgd, unsigned long address, unsigned long end,
int * pages, int * shared, int * dirty, int * total)
{
while (address < end) {
statm_pmd_range(pgd, address, end - address, pages, shared, dirty, total);
address = (address + PGDIR_SIZE) & PGDIR_MASK;
pgd++;
}
}
int
table_fkt (int type, union table *buf, const void *param)
{
union table tbl;
struct sysinfo i;
struct task_struct *tsk = NULL;
sigset_t sigign, sigcatch;
int index, err;
pid_t pid;
if (type == TABLE_VERSION)
return _TABLE_VERSION;
if (!buf)
return -EFAULT;
memset (&tbl, 0, sizeof (union table));
/* For TABLE_PROC_*, read pid and get task_struct */
switch (type) {
case TABLE_PROC_UID:
case TABLE_PROC_MEM:
case TABLE_PROC_SEGMENT:
case TABLE_PROC_TIME:
case TABLE_PROC_STATE:
case TABLE_PROC_SIGNAL:
case TABLE_PROC_KERNEL:
err = verify_area (VERIFY_READ, param, sizeof (pid_t));
if (err)
return err;
copy_from_user (&pid, param, sizeof (pid_t));
read_lock (&tasklist_lock);
tsk = find_task_by_pid (pid);
/* FIXME!! This should be done after the last use */
read_unlock(&tasklist_lock);
if (tsk == NULL)
return -ESRCH;
break;
}
/* Main function dispatcher */
switch (type) {
case TABLE_PROCLIST:
tsk = task [0];
for (index = 0; index < nr_tasks; index++) {
tbl.proclist.pids [index] = tsk->pid;
tsk = tsk->next_task;
}
tbl.proclist.nr_running = nr_running;
tbl.proclist.nr_tasks = nr_tasks;
tbl.proclist.last_pid = last_pid;
break;
case TABLE_CPU:
tbl.cpu.total = jiffies;
tbl.cpu.user = kstat.cpu_user;
tbl.cpu.nice = kstat.cpu_nice;
tbl.cpu.sys = kstat.cpu_system;
tbl.cpu.idle = tbl.cpu.total -
(tbl.cpu.user + tbl.cpu.nice + tbl.cpu.sys);
tbl.cpu.frequency = HZ;
break;
case TABLE_MEM:
si_meminfo (&i);
tbl.mem.total = i.totalram;
tbl.mem.used = i.totalram - i.freeram;
tbl.mem.free = i.freeram;
tbl.mem.shared = i.sharedram;
tbl.mem.buffer = i.bufferram;
tbl.mem.cached = page_cache_size << PAGE_SHIFT;
break;
case TABLE_SWAP:
si_swapinfo (&i);
tbl.swap.total = i.totalswap;
tbl.swap.used = i.totalswap - i.freeswap;
tbl.swap.free = i.freeswap;
break;
case TABLE_LOADAVG:
tbl.loadavg.loadavg [0] = (double) avenrun [0] / (1 << FSHIFT);
tbl.loadavg.loadavg [1] = (double) avenrun [1] / (1 << FSHIFT);
tbl.loadavg.loadavg [2] = (double) avenrun [2] / (1 << FSHIFT);
tbl.loadavg.nr_running = nr_running;
tbl.loadavg.nr_tasks = nr_tasks;
tbl.loadavg.last_pid = last_pid;
break;
case TABLE_UPTIME:
tbl.uptime.uptime = jiffies;
tbl.uptime.idle = task[0]->times.tms_utime +
task[0]->times.tms_stime;
break;
case TABLE_PROC_STATE:
tbl.proc_state.state = tsk->state;
tbl.proc_state.flags = tsk->flags;
memcpy (tbl.proc_state.comm, tsk->comm,
sizeof (tbl.proc_state.comm));
break;
case TABLE_PROC_UID:
tbl.proc_uid.uid = tsk->uid;
tbl.proc_uid.euid = tsk->euid;
tbl.proc_uid.suid = tsk->suid;
tbl.proc_uid.fsuid = tsk->fsuid;
tbl.proc_uid.gid = tsk->gid;
tbl.proc_uid.egid = tsk->egid;
tbl.proc_uid.sgid = tsk->sgid;
tbl.proc_uid.fsgid = tsk->fsgid;
tbl.proc_uid.pid = tsk->pid;
tbl.proc_uid.pgrp = tsk->pgrp;
tbl.proc_uid.ppid = tsk->p_pptr->pid;
tbl.proc_uid.session = tsk->session;
tbl.proc_uid.tty = tsk->tty ?
kdev_t_to_nr (tsk->tty->device) : 0;
tbl.proc_uid.tpgid = tsk->tty ? tsk->tty->pgrp : -1;
tbl.proc_uid.priority = tsk->priority;
tbl.proc_uid.counter = tsk->counter;
tbl.proc_uid.def_priority = DEF_PRIORITY;
break;
case TABLE_PROC_SIGNAL:
memcpy (&tbl.proc_signal.signal, &tsk->signal,
sizeof (tbl.proc_signal.signal));
memcpy (&tbl.proc_signal.blocked, &tsk->blocked,
sizeof (tbl.proc_signal.blocked));
collect_sigign_sigcatch (tsk, &sigign, &sigcatch);
memcpy (&tbl.proc_signal.ignored, &sigign,
sizeof (tbl.proc_signal.ignored));
memcpy (&tbl.proc_signal.caught, &sigcatch,
sizeof (tbl.proc_signal.caught));
#if 0
printk ("PROC_SIGNAL: (%lu, %lu) - (%lu, %lu)\n",
tbl.proc_signal.ignored.sig [0],
tbl.proc_signal.ignored.sig [1],
tbl.proc_signal.caught.sig [0],
tbl.proc_signal.caught.sig [1]);
#endif
break;
case TABLE_PROC_MEM:
if (tsk->mm && tsk->mm != &init_mm) {
tbl.proc_mem.context = tsk->mm->context;
tbl.proc_mem.start_code = tsk->mm->start_code;
tbl.proc_mem.end_code = tsk->mm->end_code;
tbl.proc_mem.start_data = tsk->mm-> start_data;
tbl.proc_mem.end_data = tsk->mm->end_data;
tbl.proc_mem.start_brk = tsk->mm->start_brk;
tbl.proc_mem.brk = tsk->mm->brk;
tbl.proc_mem.start_stack = tsk->mm->start_stack;
tbl.proc_mem.start_mmap = tsk->mm->mmap ?
tsk->mm->mmap->vm_start : 0;
tbl.proc_mem.arg_start = tsk->mm->arg_start;
tbl.proc_mem.arg_end = tsk->mm->arg_end;
tbl.proc_mem.env_start = tsk->mm->env_start;
tbl.proc_mem.env_end = tsk->mm->env_end;
tbl.proc_mem.rss = tsk->mm->rss;
tbl.proc_mem.total_vm = tsk->mm->total_vm;
tbl.proc_mem.locked_vm = tsk->mm->locked_vm;
}
tbl.proc_mem.rlim = tsk->rlim ? tsk->rlim[RLIMIT_RSS].rlim_cur : 0;
break;
case TABLE_PROC_SEGMENT:
if (tsk->mm && tsk->mm != &init_mm) {
unsigned long vsize = 0;
int size = 0, resident = 0, share = 0;
int trs = 0, lrs = 0, drs = 0, dt = 0;
struct vm_area_struct * vma = tsk->mm->mmap;
while (vma) {
pgd_t *pgd = pgd_offset(tsk->mm, vma->vm_start);
int pages = 0, shared = 0, dirty = 0, total = 0;
vsize += vma->vm_end - vma->vm_start;
statm_pgd_range (pgd, vma->vm_start, vma->vm_end,
&pages, &shared, &dirty, &total);
resident += pages;
share += shared;
dt += dirty;
size += total;
if (vma->vm_flags & VM_EXECUTABLE)
trs += pages; /* text */
else if (vma->vm_flags & VM_GROWSDOWN)
drs += pages; /* stack */
else if (vma->vm_end > 0x60000000)
lrs += pages; /* library */
else
drs += pages;
vma = vma->vm_next;
}
tbl.proc_segment.vsize = vsize;
tbl.proc_segment.size = size;
tbl.proc_segment.resident = resident;
tbl.proc_segment.shared = share;
tbl.proc_segment.trs = trs;
tbl.proc_segment.lrs = lrs;
tbl.proc_segment.dt = dt;
}
break;
case TABLE_PROC_TIME:
tbl.proc_time.utime = tsk->times.tms_utime;
tbl.proc_time.stime = tsk->times.tms_stime;
tbl.proc_time.cutime = tsk->times.tms_cutime;
tbl.proc_time.cstime = tsk->times.tms_cstime;
tbl.proc_time.start_time = tsk->start_time;
tbl.proc_time.timeout = tsk->timeout;
tbl.proc_time.policy = tsk->policy;
tbl.proc_time.rt_priority = tsk->rt_priority;
tbl.proc_time.it_real_value = tsk->it_real_value;
tbl.proc_time.it_prof_value = tsk->it_prof_value;
tbl.proc_time.it_virt_value = tsk->it_virt_value;
tbl.proc_time.it_real_incr = tsk->it_real_incr;
tbl.proc_time.it_prof_incr = tsk->it_prof_incr;
tbl.proc_time.it_virt_incr = tsk->it_virt_incr;
break;
case TABLE_PROC_KERNEL:
tbl.proc_kernel.min_flt = tsk->min_flt;
tbl.proc_kernel.cmin_flt = tsk->cmin_flt;
tbl.proc_kernel.maj_flt = tsk->maj_flt;
tbl.proc_kernel.cmaj_flt = tsk->cmaj_flt;
tbl.proc_kernel.kesp = KSTK_EIP(tsk);
tbl.proc_kernel.keip = KSTK_ESP(tsk);
tbl.proc_kernel.nswap = tsk->nswap;
tbl.proc_kernel.cnswap = tsk->cnswap;
tbl.proc_kernel.wchan = get_wchan (tsk);
break;
default:
return -EINVAL;
}
err = verify_area (VERIFY_WRITE, buf, sizeof (struct table));
if (err)
return err;
copy_to_user (buf, &tbl, sizeof (union table));
return 0;
}

1
kernel/table21/version.h Normal file
View File

@@ -0,0 +1 @@
#define _TABLE_VERSION 1

View File

@@ -1,85 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/unistd.h>
#include <linux/table.h>
#include <syscall.h>
static inline _syscall3 (int, table, int, type, union table *, tbl, const void *, param);
int
main (void)
{
union table tbl;
unsigned count;
int ret;
ret = table (TABLE_VERSION, NULL, NULL);
if (ret == -1) {
fprintf (stderr, "table(%u): %s\n", TABLE_VERSION, sys_errlist [errno]);
exit (-errno);
}
fprintf (stderr, "Table (%u) = %u\n", TABLE_VERSION, ret);
for (count = 0; count < 5; count++) {
ret = table (TABLE_CPU, &tbl, NULL);
if (ret == -1) {
fprintf (stderr, "table(%u): %s\n", TABLE_CPU, sys_errlist [errno]);
exit (-errno);
}
fprintf (stderr, "Table (%u) = %lu, %lu, %lu, %lu, %lu, %lu\n",
TABLE_CPU, tbl.cpu.total, tbl.cpu.user, tbl.cpu.nice,
tbl.cpu.sys, tbl.cpu.idle, tbl.cpu.frequency);
}
ret = table (TABLE_MEM, &tbl, NULL);
if (ret == -1) {
fprintf (stderr, "table(%u): %s\n", TABLE_MEM, sys_errlist [errno]);
exit (-errno);
}
fprintf (stderr, "Table (%u) = %lu, %lu, %lu, %lu, %lu, %lu\n",
TABLE_MEM, tbl.mem.total, tbl.mem.used, tbl.mem.free,
tbl.mem.shared, tbl.mem.buffer, tbl.mem.cached);
ret = table (TABLE_SWAP, &tbl, NULL);
if (ret == -1) {
fprintf (stderr, "table(%u): %s\n", TABLE_SWAP, sys_errlist [errno]);
exit (-errno);
}
fprintf (stderr, "Table (%u) = %lu, %lu, %lu\n",
TABLE_SWAP, tbl.swap.total, tbl.swap.used, tbl.swap.free);
ret = table (TABLE_LOADAVG, &tbl, NULL);
if (ret == -1) {
fprintf (stderr, "table(%u): %s\n", TABLE_LOADAVG, sys_errlist [errno]);
exit (-errno);
}
fprintf (stderr, "Table (%u) = (%lu, %lu, %lu) - %u, %u, %u\n",
TABLE_LOADAVG, tbl.loadavg.loadavg [0], tbl.loadavg.loadavg [1],
tbl.loadavg.loadavg [2], tbl.loadavg.nr_running,
tbl.loadavg.nr_tasks, tbl.loadavg.last_pid);
ret = table (TABLE_UPTIME, &tbl, NULL);
if (ret == -1) {
fprintf (stderr, "table(%u): %s\n", TABLE_UPTIME, sys_errlist [errno]);
exit (-errno);
}
fprintf (stderr, "Table (%u) = %lu, %lu\n",
TABLE_UPTIME, tbl.uptime.uptime, tbl.uptime.idle);
exit (0);
}

View File

@@ -1,20 +1,17 @@
LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@
INCLUDES = -I$(top_builddir) -I$(top_srcdir) @machine_incs@ \
-I$(top_srcdir)/include -I$(top_srcdir)/intl @GUILE_INCS@ \
-DGTOPLOCALEDIR=\"$(datadir)/locale\" -D_GNU_SOURCE
CFLAGS = -Wall -W @CFLAGS@ -DGTOP_SERVER=\""@LIBGTOP_SERVER@"\" -DDEBUG
CFLAGS = -Wall -W @CFLAGS@
lib_LTLIBRARIES = libgtop.la
libgtop_la_SOURCES = init.c open.c close.c command.c read.c read_data.c \
write.c lib.c parameter.c
libgtop_la_SOURCES = init.c open.c close.c command.c read.c \
read_data.c write.c lib.c parameter.c \
sysdeps.c
BUILT_SOURCES = lib.c
lib.c: lib.awk $(top_builddir)/config.h $(top_builddir)/features.def
$(AWK) -f $(srcdir)/lib.awk < $(top_builddir)/features.def > lib-t
lib.c: lib.awk $(top_builddir)/config.h $(top_srcdir)/features.def
$(AWK) -f $(srcdir)/lib.awk < $(top_srcdir)/features.def > lib-t
mv lib-t lib.c
EXTRA_DIST = lib.awk

View File

@@ -19,14 +19,30 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <glibtop.h>
#include <glibtop/open.h>
#include <glibtop/close.h>
#include <glibtop/command.h>
/* Closes pipe to gtop server. */
/* Closes server. */
void
glibtop_close_r (glibtop *server)
{
kill (server->pid, SIGKILL);
close (server->input [0]);
close (server->output [1]);
switch (server->method) {
case GLIBTOP_METHOD_UNIX:
case GLIBTOP_METHOD_INET:
glibtop_call_l (server, GLIBTOP_CMND_QUIT,
0, NULL, 0, NULL);
if (close (server->socket))
glibtop_warn_io ("close");
break;
case GLIBTOP_METHOD_PIPE:
kill (server->pid, SIGKILL);
close (server->input [0]);
close (server->output [1]);
break;
}
}

View File

@@ -27,8 +27,8 @@
#include <glibtop/xmalloc.h>
void *
glibtop_call_l (glibtop *server, unsigned command, size_t send_size, void *send_buf,
size_t recv_size, void *recv_buf)
glibtop_call_l (glibtop *server, unsigned command, size_t send_size,
void *send_buf, size_t recv_size, void *recv_buf)
{
glibtop_command cmnd;
glibtop_response response;
@@ -37,19 +37,12 @@ glibtop_call_l (glibtop *server, unsigned command, size_t send_size, void *send_
memset (&cmnd, 0, sizeof (glibtop_command));
memcpy (&cmnd.server, server, sizeof (glibtop));
cmnd.command = command;
/* If send_size is less than _GLIBTOP_PARAM_SIZE (normally 16 Bytes), we
* send it together with command, so we only need one system call instead
* of two. */
#ifdef DEBUG
// fprintf (stderr, "COMMAND: send_size = %d; command = %d; sizeof (cmnd) = %d\n",
// send_size, command, sizeof (glibtop_command));
#endif
if (send_size <= _GLIBTOP_PARAM_SIZE) {
memcpy (cmnd.parameter, send_buf, send_size);
cmnd.size = send_size;
@@ -58,14 +51,17 @@ glibtop_call_l (glibtop *server, unsigned command, size_t send_size, void *send_
}
glibtop_write_l (server, sizeof (glibtop_command), &cmnd);
// glibtop_write_l (server, cmnd.data_size, send_buf);
glibtop_read_l (server, sizeof (glibtop_response), &response);
fprintf (stderr, "RESPONSE: %d - %d\n", response.offset, response.data_size);
#ifdef DEBUG
fprintf (stderr, "RESPONSE: %lu - %d\n",
response.offset, response.data_size);
#endif
if (recv_buf)
memcpy (recv_buf, ((char *) &response) + response.offset, recv_size);
memcpy (recv_buf, ((char *) &response) + response.offset,
recv_size);
if (response.data_size) {
void *ptr = glibtop_malloc_r (server, response.data_size);

View File

@@ -41,7 +41,7 @@ _init_server (glibtop *server, const unsigned features)
if (server->server_command == NULL) {
const char *temp = getenv ("LIBGTOP_SERVER") ?
getenv ("LIBGTOP_SERVER") : GTOP_SERVER;
getenv ("LIBGTOP_SERVER") : LIBGTOP_SERVER;
server->server_command = glibtop_strdup_r (server, temp);
}
@@ -63,16 +63,11 @@ _init_server (glibtop *server, const unsigned features)
if (server->server_command [0] != ':') {
if (features & glibtop_server_features) {
/* We really need the server. */
server->method = GLIBTOP_METHOD_PIPE;
} else {
/* Fine. No server is needed, so we call the
* sysdeps functions directly. */
server->method = GLIBTOP_METHOD_DIRECT;
}
@@ -92,21 +87,19 @@ _init_server (glibtop *server, const unsigned features)
/* Dispatch method. */
if (!strcmp (command, "direct")) {
/* Use sysdeps dir instead of connecting to server
* even if using the server would be required on
* the current system. */
/* Use sysdeps dir instead of connecting to server
* even if using the server would be required on
* the current system. */
server->method = GLIBTOP_METHOD_DIRECT;
} else if (!strcmp (command, "inet")) {
server->method = GLIBTOP_METHOD_INET;
/* Connect to internet server. */
/* Connect to internet server. */
if (temp == NULL) {
/* If no value was set, we use 'localhost'. */
/* If no value was set, we use 'localhost'. */
if (server->server_host == NULL)
server->server_host = glibtop_strdup_r
(server, "localhost");
@@ -114,7 +107,7 @@ _init_server (glibtop *server, const unsigned features)
char *temp2 = strstr (temp+1, ":");
if (temp2) *temp2 = 0;
/* Override default. */
/* Override default. */
if (server->server_host)
glibtop_free_r (server, (char *) server->server_host);
@@ -125,7 +118,7 @@ _init_server (glibtop *server, const unsigned features)
}
if (temp == NULL) {
/* If no value was set, we use DEFAULT_PORT. */
/* If no value was set, we use DEFAULT_PORT. */
if (server->server_port == 0)
server->server_port = DEFAULT_PORT;
} else {
@@ -137,9 +130,22 @@ _init_server (glibtop *server, const unsigned features)
temp = temp2 ? temp2 + 1 : temp2;
}
} else if (!strcmp (command, "unix")) {
/* Connect to unix domain socket. */
server->method = GLIBTOP_METHOD_UNIX;
} else if (!strcmp (command, "pipe")) {
/* Open pipe to server. */
server->method = GLIBTOP_METHOD_PIPE;
} else {
glibtop_error_r (server, "Unknown server method '%s'",
server->server_command+1);
}
glibtop_free_r (server, command);
@@ -185,3 +191,21 @@ glibtop_init_r (glibtop **server_ptr, const unsigned long features,
return server;
}
glibtop *
glibtop_init_s (glibtop **server, const unsigned long features,
const unsigned flags)
{
if (*server != NULL)
return *server;
fprintf (stderr, "DEBUG: %s (%d)\n", __FILE__, __LINE__);
if (glibtop_global_server == NULL) {
glibtop_global_server = &_glibtop_global_server;
glibtop_open_s (glibtop_global_server, "glibtop",
features, flags);
}
return *server = glibtop_global_server;
}

View File

@@ -2,54 +2,96 @@ BEGIN {
print "/* lib.c */";
print "/* This is a generated file. Please modify `lib.awk' */";
print "";
print "#include <glibtop.h>";
print "#include <glibtop/open.h>";
print "#include <glibtop/sysdeps.h>";
print "#include <glibtop/command.h>";
print "";
}
function output(feature) {
if (feature ~ /^proclist$/) {
print "unsigned *";
function output(line) {
split (line, line_fields, /\|/);
retval = line_fields[1];
feature = line_fields[2];
param_typ = line_fields[4];
param = line_fields[5];
param_size = line_fields[6];
if (param_typ == "") {
param_size = "0";
param_ptr = "NULL";
} else {
if (param_size == "")
param_size = "sizeof ("param_typ")";
if (param_typ ~ /*/)
param_ptr = param;
else
param_ptr = "&"param;
}
orig = feature; sub(/^@/,"",feature);
space = feature; gsub(/./," ",space);
print retval;
if (retval !~ /^void$/) {
prefix = "return ";
prefix_space = " ";
} else {
prefix = "";
print "void";
}
if (feature ~ /^proc_/) {
param = ", pid_t pid";
} else {
param = "";
prefix_space = "";
}
if (param_typ != "") {
print "glibtop_get_"feature"_l (glibtop *server, glibtop_"feature" *buf,";
print " "space" "param_typ" "param")";
} else {
print "glibtop_get_"feature"_l (glibtop *server, glibtop_"feature" *buf)";
}
print "glibtop_get_"feature"_l (glibtop *server, glibtop_"feature" *buf"param")";
print "{";
print "\tglibtop_init_r (&server, GLIBTOP_SYSDEPS_"toupper(feature)", 0);";
print "\tglibtop_init_r (&server, (1 << GLIBTOP_SYSDEPS_"toupper(feature)"), 0);";
print "";
print "\tif ((server->flags & _GLIBTOP_INIT_STATE_SERVER) &&";
print "\t (server->features & GLIBTOP_SYSDEPS_"toupper(feature)"))";
print "\t (server->features & (1 << GLIBTOP_SYSDEPS_"toupper(feature)")))";
print "\t{";
if (feature ~ /^proc_/) {
print "\t\t"prefix"glibtop_call_l (server, GLIBTOP_CMND_"toupper(feature)", sizeof (pid_t),";
print "\t\t\t\t&pid, sizeof (glibtop_"feature"), buf);";
print "\t} else {";
print "\t\t"prefix"glibtop_get_"feature"_r (server, buf, pid);";
} else {
if (param == "")
print "\t\t"prefix"glibtop_call_l (server, GLIBTOP_CMND_"toupper(feature)", 0, NULL,";
print "\t\t\t sizeof (glibtop_"feature"), buf);";
print "\t} else {";
print "\t\t"prefix"glibtop_get_"feature"_r (server, buf);";
else
print "\t\t"prefix"glibtop_call_l (server, GLIBTOP_CMND_"toupper(feature)",";
if (param == "") {
print "\t\t\t\t"prefix_space"sizeof (glibtop_"feature"), buf);";
} else {
print "\t\t\t\t"prefix_space""param_size", "param_ptr",";
print "\t\t\t\t"prefix_space"sizeof (glibtop_"feature"),";
print "\t\t\t\t"prefix_space"buf);";
}
print "\t} else {";
if (orig !~ /^@/)
print "#if (!GLIBTOP_SUID_"toupper(feature)")";
if (param == "")
print "\t\t"prefix"glibtop_get_"feature"_r (server, buf);";
else
print "\t\t"prefix"glibtop_get_"feature"_r (server, buf, "param");";
if (orig !~ /^@/) {
print "#else";
print "\t\terrno = ENOSYS;";
print "\t\tglibtop_error_io_r (server, \"glibtop_get_"feature"\");";
print "#endif";
}
print "\t}";
print "}";
print "";
}
/^(\w+)/ { output($1) }
/^[^#]/ { output($0) }

View File

@@ -33,6 +33,10 @@ void
glibtop_open_l (glibtop *server, const char *program_name,
const unsigned long features, const unsigned flags)
{
char version [BUFSIZ], buffer [BUFSIZ];
int connect_type;
unsigned nbytes;
server->name = program_name;
/* It is important to set _GLIBTOP_INIT_STATE_OPEN here when we
@@ -40,19 +44,112 @@ glibtop_open_l (glibtop *server, const char *program_name,
server->flags |= _GLIBTOP_INIT_STATE_OPEN;
if (server->method == GLIBTOP_METHOD_INET) {
int connect_type;
if (flags & GLIBTOP_FEATURES_EXCEPT)
features = ~features & GLIBTOP_SYSDEPS_ALL;
fprintf (stderr, "Connecting to '%s' port %d.\n",
if (features == 0)
features = GLIBTOP_SYSDEPS_ALL;
if (flags & GLIBTOP_FEATURES_NO_SERVER) {
server->method = GLIBTOP_METHOD_DIRECT;
features = 0;
}
server->features = features;
#ifdef DEBUG
fprintf (stderr, "SIZEOF: %u - %u - %u - %u - %u - %u\n",
sizeof (glibtop_command), sizeof (glibtop_response),
sizeof (glibtop_mountentry), sizeof (glibtop_union),
sizeof (glibtop_sysdeps), sizeof (glibtop_response_union));
#endif
switch (server->method) {
case GLIBTOP_METHOD_PIPE:
case GLIBTOP_METHOD_UNIX:
if (glibtop_server_features & features)
break;
fprintf (stderr, "Using the server is not required.\n");
server->method = GLIBTOP_METHOD_DIRECT;
break;
}
switch (server->method) {
case GLIBTOP_METHOD_DIRECT:
server->features = 0;
break;
case GLIBTOP_METHOD_INET:
fprintf (stderr, "Connecting to '%s' port %ld.\n",
server->server_host, server->server_port);
connect_type = glibtop_make_connection
(server->server_host, server->server_port,
&server->socket);
fprintf (stderr, "Connect Type is %d.\n", connect_type);
server->flags |= _GLIBTOP_INIT_STATE_SERVER;
server->features = -1;
break;
case GLIBTOP_METHOD_UNIX:
fprintf (stderr, "Connecting to Unix Domain Socket.\n");
return;
connect_type = glibtop_make_connection
("unix", 0, &server->socket);
fprintf (stderr, "Connect Type is %d.\n", connect_type);
server->flags |= _GLIBTOP_INIT_STATE_SERVER;
server->features = -1;
break;
case GLIBTOP_METHOD_PIPE:
fprintf (stderr, "Opening pipe to server (%s).\n",
LIBGTOP_SERVER);
if (pipe (server->input) || pipe (server->output))
glibtop_error_io_r (server, "cannot make a pipe");
server->pid = fork ();
if (server->pid < 0) {
glibtop_error_io_r (server, "fork failed");
} else if (server->pid == 0) {
close (0); close (1);
close (server->input [0]); close (server->output [1]);
dup2 (server->input [1], 1);
dup2 (server->output [0], 0);
execl (LIBGTOP_SERVER, NULL);
glibtop_error_io_r (server, "execl (%s)",
LIBGTOP_SERVER);
_exit (2);
}
close (server->input [1]);
close (server->output [0]);
sprintf (version, "libgtop server %s ready.\n",
LIBGTOP_VERSION);
glibtop_read_l (server, sizeof (nbytes), &nbytes);
if (nbytes != strlen (version))
glibtop_error_r (server, "Requested %u bytes but got %u",
strlen (version), nbytes);
glibtop_read_l (server, nbytes, buffer);
if (memcmp (version, buffer, strlen (version)))
glibtop_error_r (server, "server version is not %s",
LIBGTOP_VERSION);
server->flags |= _GLIBTOP_INIT_STATE_SERVER;
server->features = -1;
break;
}
/* If the server has been started, ask it for its features. */
@@ -64,5 +161,15 @@ glibtop_open_l (glibtop *server, const char *program_name,
sizeof (glibtop_sysdeps), &sysdeps);
server->features = sysdeps.features;
fprintf (stderr, "Server features are %lu.\n",
server->features);
}
/* In any case, we call the open functions of our own sysdeps
* directory. */
fprintf (stderr, "Calling sysdeps open function.\n");
glibtop_open_s (server, program_name, features, flags);
}

View File

@@ -28,6 +28,14 @@
memcpy (data_ptr, ptr, size); \
return size;
#define _check_data(size) \
if ((data_ptr == NULL) || (data_size != size)) { \
glibtop_error_r (server, "glibtop_set_parameter (%d): " \
"Expected %lu bytes but got %lu.", \
parameter, size, data_size); \
return; \
}
#define _strlen(ptr) (ptr ? strlen (ptr) : 0)
size_t
@@ -59,4 +67,14 @@ void
glibtop_set_parameter_l (glibtop *server, const unsigned parameter,
const void *data_ptr, size_t data_size)
{
switch (parameter) {
case GLIBTOP_PARAM_METHOD:
_check_data (sizeof (server->method));
memcpy (&server->method, data_ptr, data_size);
break;
case GLIBTOP_PARAM_FEATURES:
_check_data (sizeof (server->features));
memcpy (&server->features, data_ptr, data_size);
break;
}
}

View File

@@ -53,48 +53,48 @@ glibtop_get_sysdeps_r (glibtop *server, glibtop_sysdeps *buf)
/* Call all system dependent functions to check which values
* they return. */
glibtop_get_cpu_r (server, &data.cpu);
glibtop_get_cpu_l (server, &data.cpu);
buf->cpu = data.cpu.flags;
glibtop_get_mem_r (server, &data.mem);
glibtop_get_mem_l (server, &data.mem);
buf->mem = data.mem.flags;
glibtop_get_swap_r (server, &data.swap);
glibtop_get_swap_l (server, &data.swap);
buf->swap = data.swap.flags;
glibtop_get_uptime_r (server, &data.uptime);
glibtop_get_uptime_l (server, &data.uptime);
buf->uptime = data.uptime.flags;
glibtop_get_loadavg_r (server, &data.loadavg);
glibtop_get_loadavg_l (server, &data.loadavg);
buf->loadavg = data.loadavg.flags;
glibtop_get_shm_limits_r (server, &data.shm_limits);
glibtop_get_shm_limits_l (server, &data.shm_limits);
buf->shm_limits = data.shm_limits.flags;
glibtop_get_msg_limits_r (server, &data.msg_limits);
glibtop_get_msg_limits_l (server, &data.msg_limits);
buf->msg_limits = data.msg_limits.flags;
glibtop_get_sem_limits_r (server, &data.sem_limits);
glibtop_get_sem_limits_l (server, &data.sem_limits);
buf->sem_limits = data.sem_limits.flags;
glibtop_get_proclist_r (server, &data.proclist);
glibtop_get_proclist_l (server, &data.proclist);
buf->proclist = data.proclist.flags;
glibtop_get_proc_state_r (server, &data.proc_state, 0);
glibtop_get_proc_state_l (server, &data.proc_state, 0);
buf->proc_state = data.proc_state.flags;
glibtop_get_proc_uid_r (server, &data.proc_uid, 0);
glibtop_get_proc_uid_l (server, &data.proc_uid, 0);
buf->proc_uid = data.proc_uid.flags;
glibtop_get_proc_mem_r (server, &data.proc_mem, 0);
glibtop_get_proc_mem_l (server, &data.proc_mem, 0);
buf->proc_mem = data.proc_mem.flags;
glibtop_get_proc_time_r (server, &data.proc_time, 0);
glibtop_get_proc_time_l (server, &data.proc_time, 0);
buf->proc_time = data.proc_time.flags;
glibtop_get_proc_kernel_r (server, &data.proc_kernel, 0);
glibtop_get_proc_kernel_l (server, &data.proc_kernel, 0);
buf->proc_kernel = data.proc_kernel.flags;
glibtop_get_proc_segment_r (server, &data.proc_segment, 0);
glibtop_get_proc_segment_l (server, &data.proc_segment, 0);
buf->proc_segment = data.proc_segment.flags;
}

View File

@@ -8,18 +8,26 @@ LIBGTOP_INCLUDEDIR="@LIBGTOP_INCLUDEDIR@"
LIBGTOP_LIBS="@LIBGTOP_LIBS@"
LIBGTOP_INCS="@LIBGTOP_INCS@"
LIBGTOP_NAMES_LIBS="@LIBGTOP_NAMES_LIBS@"
LIBGTOP_NAMES_INCS="@LIBGTOP_NAMES_INCS@"
LIBGTOP_GUILE_LIBS="@LIBGTOP_GUILE_LIBS@"
LIBGTOP_GUILE_INCS="@LIBGTOP_GUILE_INCS@"
LIBGTOP_GUILE_NAMES_LIBS="@LIBGTOP_GUILE_NAMES_LIBS@"
LIBGTOP_GUILE_NAMES_INCS="@LIBGTOP_GUILE_NAMES_INCS@"
LIBGTOP_BINDIR="@LIBGTOP_BINDIR@"
LIBGTOP_SERVER="@LIBGTOP_SERVER@"
LIBGTOP_MAJOR_VERSION="@LIBGTOP_MAJOR_VERSION@"
LIBGTOP_MINOR_VERSION="@LIBGTOP_MINOR_VERSION@"
LIBGTOP_VERSION="@LIBGTOP_VERSION@"
libgtop_sysdeps_dir="@libgtop_sysdeps_dir@"
libgtop_need_server="@libgtop_need_server@"
libgtop_use_machine_h="@libgtop_use_machine_h@"
libgtop_guile_found="@libgtop_guile_found@"
libgtop_want_names="@libgtop_want_names@"
libgtop_want_guile_names="@libgtop_want_guile_names@"
libgtop_want_examples="@libgtop_want_examples@"

111
libproc/Makefile Normal file
View File

@@ -0,0 +1,111 @@
# Auto-adaptive C library Makefile adapted for libproc, Chuck Blake.
# Assumptions are basically that all the .c files in the CWD are modules
# for the library and that all .h files are the interface to the library.
# PROJECT SPECIFIC MACROS
NAME = proc
# INSTALLATION OPTIONS
TOPDIR = /usr
HDRDIR = $(TOPDIR)/include/$(NAME)# where to put .h files
LIBDIR = $(TOPDIR)/lib# where to put library files
SHLIBDIR = /lib# where to put shared library files
HDROWN = -o root -g root # owner of header files
LIBOWN = -o root -g root # owner of library files
INSTALL = install
# COMPILATION OPTIONS
CC = gcc -O2 -D_GNU_SOURCE #-ggdb # easy to command-line override
CFLAGS = -I.. -Wall
# ----------------------------------------------------------------#
# The rest is the auto-magic section -- highly GNU make dependent #
# You should never need to edit this. #
# ----------------------------------------------------------------#
VC_SUF = ,v
VC_PFX = RCS/
RCSFILES = $(patsubst $(VC_PFX)%$(VC_SUF),%,$(wildcard $(VC_PFX)*$(VC_SUF)))
# We take the union of RCS files and other files in CWD so that new files do
# not need to alter this makefile. 'sort' removes duplicates. This allows the
# convenience of compiling and testing new files before the initial check-in.
SRC = $(sort $(wildcard *.c) $(filter %.c,$(RCSFILES)))
HDR = $(sort $(wildcard *.h) $(filter %.h,$(RCSFILES)))
OBJ = $(SRC:.c=.o)
SONAME = lib$(NAME).so.$(LIBVERSION)
ifeq ($(SHARED),1)
CFLAGS += -fpic
all: lib$(NAME).a $(SONAME)
else
all: lib$(NAME).a
endif
lib$(NAME).a: $(OBJ)
$(AR) rcs $@ $^
$(SONAME): $(OBJ)
gcc -Wl,-shared -Wl,-soname,$(SONAME) -o $@ $^ -lc
ln -sf $(SONAME) lib$(NAME).so
# AUTOMATIC DEPENDENCY GENERATION -- GCC AND GNUMAKE DEPENDENT
.depend:
$(strip $(CC) $(CFLAGS) -MM -MG $(SRC) > .depend)
include .depend
# INSTALLATION
install: all
if ! [ -d $(HDRDIR) ] ; then mkdir $(HDRDIR) ; fi
$(INSTALL) $(HDROWN) $(HDR) $(TOPDIR)/include/$(NAME)
$(INSTALL) $(LIBOWN) lib$(NAME).a $(LIBDIR)
ifeq ($(SHARED),1)
$(INSTALL) $(LIBOWN) $(SONAME) $(SHLIBDIR)
ln -sf $(SHLIBDIR)/$(SONAME) $(SHLIBDIR)/lib$(NAME).so
ldconfig
endif
# VARIOUS SHORT CUT TARGETS
.PHONY: all install dep clean distclean checkout checkclean
dep: .depend
clean:
$(RM) lib$(NAME).* *.o
distclean: clean
$(RM) .depend signames.h
checkout:
$(CO) $(RCSFILES)
checkclean:
$(RM) $(RCSFILES)
# CUSTOM c -> o rule so that command-line has minimal whitespace
%.o : %.c
$(strip $(CC) $(CFLAGS) -c $<)
# PROJECT SPECIFIC DEPENDENCIES/BUILD RULES
version.o: version.c version.h
ifdef MINORVERSION
$(strip $(CC) $(CFLAGS) -DVERSION=\"$(VERSION)\" -DSUBVERSION=\"$(SUBVERSION)\" -DMINORVERSION=\"$(MINORVERSION)\" -c version.c)
else
$(strip $(CC) $(CFLAGS) -DVERSION=\"$(VERSION)\" -DSUBVERSION=\"$(SUBVERSION)\" -c version.c)
endif
signals.o : signames.h
signames.h ../proc/signames.h : /usr/include/signal.h
/lib/cpp -dM </usr/include/signal.h | \
tr -s '\t ' ' ' | sort -n +2 | sed \
's:#define SIG\([A-Z]\+[0-9]*\) \([0-9]\+\) *\(\|/\*.*\)$$:{\
\2,"\1" },:p;d' > signames.h

49
libproc/alloc.c Normal file
View File

@@ -0,0 +1,49 @@
/***********************************************************************\
* Copyright (C) 1992 by Michael K. Johnson, johnsonm@sunsite.unc.edu *
* *
* This file is placed under the conditions of the GNU public *
* license, version 2, or any later version. See file COPYING *
* for information on distribution conditions. *
\***********************************************************************/
#include <stdlib.h>
#include <stdio.h>
void *xcalloc(void *pointer, int size) {
void * ret;
if (pointer)
free(pointer);
if (!(ret = calloc(1, size))) {
fprintf(stderr, "xcalloc: allocation error, size = %d\n", size);
exit(1);
} else {
return ret;
}
}
void *xmalloc(unsigned int size) {
void *p;
if (size == 0)
++size;
p = malloc(size);
if (!p) {
fprintf(stderr, "xmalloc: malloc(%d) failed", size);
perror(NULL);
exit(1);
}
return(p);
}
void *xrealloc(void *oldp, unsigned int size) {
void *p;
if (size == 0)
++size;
p = realloc(oldp, size);
if (!p) {
fprintf(stderr, "xrealloc: realloc(%d) failed", size);
perror(NULL);
exit(1);
}
return(p);
}

307
libproc/compare.c Normal file
View File

@@ -0,0 +1,307 @@
/*
*
* Copyright 1994 Charles Blake and Michael K. Johnson
* This file is a part of procps, which is distributable
* under the conditions of the GNU Public License. See the
* file COPYING for details.
*
*/
#include <string.h> /* for strcmp */
#include <stdio.h> /* for parse error output */
#include "readproc.h" /* for proc_t */
#include "tree.h" /* for struct tree_node */
/*
This module was written by Charles Blake for procps.
mult_lvl_cmp:
slick general purpose multi-level compare function I invented.
sort_depth:
the number of levels of functions *to use*. This means many more levels
can be defined than mult_lvl_cmp tres out. If this is 1 then mult_lvl_cmp
is just a trivial wrapper around (*sort_function[0]).
sort_direction:
multiplicative factor for the output of cmp_whatever.
1 ==> default order, -1 ==> reverse order, 0 ==> forced equality
The 0 bit is the neat part. Since a value of zero is the code for equality
multiplying the output of cmp_foo(a,b) forces a==b to be true. This is a
convenient way to turn sorting off in middle levels of a multi-level sort.
If time is a problem, reforming the whole sort_function array to not include
these unsorted middle levels will be faster since then cmp_foo won't even
be called. It might simplify some code depending upon how you organize it.
sort_function[]:
array of function pointers that points to our family of comparison functions
(I have named them cmp_* but mult_lvl_cmp doesn't care what they're named).
This may be declared and initialized like so:
int (*sort_function[])(void* a, void* b)={&cmp_foo, &cmp_bar, &cmp_hiho};
You could also use my command line '-O' parser below.
Note that we only descend levels until the order is determined. If we descend
all levels, that means that the items are equal at all levels, so we return 0.
Otherwise we return whatever the level's cmp_foo function would have returned.
This allows whatever default behavior you want for cmp_foo. sort_direction[]
reverses this default behavior, but mult_lvl_cmp doesn't decide that ascending
or descending is the default. That is the job of your cmp_foo's.
*/
/* the only reason these are global is because qsort(3) likes it that way.
It's also a little more efficient if mult_lvl_cmp() is called many times.
*/
typedef int (*cmp_t)(void*,void*); /* for function pointer casts */
int sort_depth = 0;
int sort_direction[10]; /* storage for 10 levels, but 4 would be plenty!*/
int (*sort_function[10])(void* a, void* b);
int mult_lvl_cmp(void* a, void* b) {
int i, cmp_val;
for(i = 0; i < sort_depth; i++) {
cmp_val = sort_direction[i] * (*sort_function[i])(a,b);
if (cmp_val != 0)
return cmp_val;
}
return 0;
}
int node_mult_lvl_cmp(void* a, void* b) {
int i, cmp_val;
for(i = 0; i < sort_depth; i++) {
cmp_val = sort_direction[i] * (*sort_function[i])(&(((struct tree_node *)a)->proc),&(((struct tree_node *)b)->proc));
if (cmp_val != 0)
return cmp_val;
}
return 0;
}
/* qsort(3) compliant comparison functions for all members of the ps_proc
structure (in the same order in which they appear in the proc_t declaration)
return is {-1,0,1} as {a<b, a==b, a>b}
default ordering is ascending for all members. (flip 1,-1 to reverse)
*/
/* pre-processor macros to cut down on source size (and typing!)
Note the use of the string concatenation operator ##
*/
#define CMP_STR(NAME) \
int cmp_ ## NAME(proc_t** P, proc_t** Q) { \
return strcmp((*P)-> ## NAME, (*Q)-> ## NAME); \
}
#define CMP_INT(NAME) \
int cmp_ ## NAME (proc_t** P, proc_t** Q) { \
if ((*P)-> ## NAME < (*Q)-> ## NAME) return -1; \
if ((*P)-> ## NAME > (*Q)-> ## NAME) return 1; \
return 0; \
}
/* Define the (46!) cmp_ functions with the above macros for every element
of proc_t. If the binary gets too big, we could nuke inessentials.
*/
/* CMP_STR(cmdline) */
CMP_STR(user)
CMP_STR(cmd)
/* CMP_INT(state) */
/* CMP_STR(ttyc) */
CMP_INT(uid)
CMP_INT(pid)
CMP_INT(ppid)
CMP_INT(pgrp)
CMP_INT(session)
CMP_INT(tty)
CMP_INT(tpgid)
CMP_INT(utime)
CMP_INT(stime)
CMP_INT(cutime)
CMP_INT(cstime)
/* CMP_INT(priority) */
CMP_INT(nice)
CMP_INT(start_time)
/* CMP_INT(signal) */
/* CMP_INT(blocked) */
/* CMP_INT(sigignore) */
/* CMP_INT(sigcatch) */
CMP_INT(flags)
CMP_INT(min_flt)
CMP_INT(cmin_flt)
CMP_INT(maj_flt)
CMP_INT(cmaj_flt)
/* CMP_INT(timeout) */
CMP_INT(vsize)
CMP_INT(rss)
/* CMP_INT(rss_rlim) */
/* CMP_INT(start_code) */
/* CMP_INT(end_code) */
/* CMP_INT(start_stack) */
/* CMP_INT(kstk_esp) */
/* CMP_INT(kstk_eip) */
/* CMP_INT(wchan) */
CMP_INT(pcpu)
CMP_INT(size)
CMP_INT(resident)
CMP_INT(share)
/* CMP_INT(trs) */
/* CMP_INT(lrs) */
/* CMP_INT(drs) */
/* CMP_INT(dt) */
/* define user interface to sort keys. Fairly self-explanatory. */
struct cmp_fun_struct {
char letter; /* single option-letter for key */
char name[15]; /* long option name for key */
int (*fun)(proc_t**, proc_t**); /* pointer to cmp_key */
} cmp[] = {
/* { '?', "cmdline", &cmp_cmdline }, */
{ 'u', "user", &cmp_user },
{ 'c', "cmd", &cmp_cmd },
/* { '?', "state", &cmp_state }, */
/* { '?', "ttyc", &cmp_ttyc }, */
{ 'U', "uid", &cmp_uid },
{ 'p', "pid", &cmp_pid },
{ 'P', "ppid", &cmp_ppid },
{ 'g', "pgrp", &cmp_pgrp },
{ 'o', "session", &cmp_session },
{ 't', "tty", &cmp_tty },
{ 'G', "tpgid", &cmp_tpgid },
{ 'k', "utime", &cmp_utime },
{ 'K', "stime", &cmp_stime },
{ 'j', "cutime", &cmp_cutime },
{ 'J', "cstime", &cmp_cstime },
/* { '?', "counter", &cmp_counter }, */
{ 'y', "priority", &cmp_nice },
{ 'T', "start_time", &cmp_start_time },
/* { '?', "signal", &cmp_signal }, */
/* { '?', "blocked", &cmp_blocked }, */
/* { '?', "sigignore", &cmp_sigignore }, */
/* { '?', "sigcatch", &cmp_sigcatch }, */
{ 'f', "flags", &cmp_flags },
{ 'm', "min_flt", &cmp_min_flt },
{ 'n', "cmin_flt", &cmp_cmin_flt },
{ 'M', "maj_flt", &cmp_maj_flt },
{ 'N', "cmaj_flt", &cmp_cmaj_flt },
/* { 'C', "timeout", &cmp_timeout }, */
{ 'v', "vsize", &cmp_vsize },
{ 'r', "rss", &cmp_rss },
/* { '?', "rss_rlim", &cmp_rss_rlim }, */
/* { '?', "start_code", &cmp_start_code }, */
/* { '?', "end_code", &cmp_end_code }, */
/* { '?', "start_stack", &cmp_start_stack }, */
/* { '?', "kstk_esp", &cmp_kstk_esp }, */
/* { '?', "kstk_eip", &cmp_kstk_eip }, */
/* { '?', "wchan", &cmp_wchan }, */
{ 'C', "pcpu", &cmp_pcpu },
{ 's', "size", &cmp_size },
{ 'R', "resident", &cmp_resident },
{ 'S', "share", &cmp_share },
/* { '?', "trs", &cmp_trs }, */
/* { '?', "lrs", &cmp_lrs }, */
/* { '?', "drs", &cmp_drs }, */
/* { '?', "dt", &cmp_dt }, */
{ '\0',"terminator", NULL }
};
void dump_keys(void) {
int i;
for(i=0; cmp[i].letter; i++)
fprintf(stderr, "%s-O%c , --sort:%-15.15s%s",
i%2?"":" ",
cmp[i].letter, cmp[i].name,
i%2?"\n":"");
if (i%2)
fprintf(stderr, "\n");
}
/* command line option parsing. Assign sort_{depth,direction[],function[]}
based upon a string of the form:
[+-]a[+-]b[+-]c...
with a,b,c,... being letter flags corresponding to a particular sort
key and the optional '-' specifying a reverse sort on that key. + doesn't
mean anything, but it keeps things looking balanced...
*/
int parse_sort_opt(char* opt) {
int i, next_dir=1;
for(; *opt ; ++opt) {
if (*opt == '-' || *opt == '+') {
if (*opt == '-')
next_dir = -1;
opt++;
continue;
}
for (i = 0; cmp[i].letter; i++)
if (*opt == cmp[i].letter)
break;
if (!cmp[i].letter) {
fprintf(stderr,
"ps: no such sort key -- %c. Possibilities are:\n", *opt);
dump_keys();
return -1;
} else {
#ifdef DEBUG
fprintf(stderr,
"sort level %d: key %s, direction % d\n",
sort_depth, cmp[i].name, next_dir);
#endif
sort_function[sort_depth] = (cmp_t)cmp[i].fun;
sort_direction[sort_depth++] = next_dir;
next_dir = 1;
}
}
return 0;
}
int parse_long_sort(char* opt) {
char* comma;
int i, more_keys, next_dir=1;
do {
if (*opt == '-' || *opt == '+') {
if (*opt == '-')
next_dir = -1;
more_keys = 1;
opt++;
continue;
}
more_keys = ((comma=index(opt,',')) != NULL);
/* keys are ',' delimited */
if (more_keys)
*comma='\0'; /* terminate for strcmp() */
for(i = 0; cmp[i].letter; ++i)
if (strcmp(opt, cmp[i].name) == 0)
break;
if (!cmp[i].letter) {
fprintf(stderr,
"ps: no such sort key -- %s. Possibilities are:\n", opt);
dump_keys();
return -1;
} else {
#ifdef DEBUG
fprintf(stderr,
"sort level %d: key %s, direction % d\n",
sort_depth, cmp[i].name, next_dir);
#endif
sort_function[sort_depth] = (cmp_t)cmp[i].fun;
sort_direction[sort_depth++] = next_dir;
next_dir = 1;
}
opt = comma + 1; /* do next loop on next key, if more keys, else done*/
} while (more_keys);
return 0;
}
void reset_sort_options (void)
{
int i;
sort_depth=0;
for (i=0;i<10;i++){
sort_direction[i]=0;
sort_function[i]=(cmp_t)NULL;
}
}
void register_sort_function (int dir, cmp_t func)
{
sort_function[sort_depth] = func;
sort_direction[sort_depth++] = dir;
}

269
libproc/devname.c Normal file
View File

@@ -0,0 +1,269 @@
/* device name <-> number map system optimized for rapid, constant time lookup.
Copyright Charles Blake, 1996, see COPYING for details.
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#define __KERNEL__
#include <linux/kdev_t.h>
#undef __KERNEL__
#define DEVDIR "/dev"
#define DEVTAB "psdevtab"
static char *devtab_paths[] = {
"/etc/" DEVTAB,
"%s/." DEVTAB,
NULL
};
#define DEVINITIALMODE 0664
#define DEV_MAX_PATH (5+256)
#define DEV_NAME_MAX 8
static dev_t major[] = { 2, 3, 4, 5, 19, 20, 22, 23, 24, 25, 32, 33,
46, 47, 48, 49 };
#define Nminor 256
#define Nmajor (sizeof(major)/sizeof(dev_t))
#define Ndev (Nmajor*Nminor)
#define Ndevtab (Ndev*DEV_NAME_MAX)
static char* devtab; /* the memory buffer holding all the name strings */
/* This macro evaluates to the address into the table of the string of
DEV_NAME_MAX chars for the device with major m, minor n. */
#define TAB(m,n) (devtab + (m)*(Nminor*DEV_NAME_MAX) + (n)*DEV_NAME_MAX)
static int devtab_initialized = 0;
static char* name_to_path(char* name); /* forward declarations */
static int init_devtab (void);
/* Device Name -> Number Map
many-to-one: -1 on failed match.
*/
dev_t name_to_dev(char* name) {
static struct stat sbuf;
return (stat(name_to_path(name), &sbuf) < 0) ? -1 : sbuf.st_rdev;
}
/* find m in a[] assuming a is sorted into ascending order */
/* in-line linear search placeholder until more majors warrant binary search */
static __inline__ int lookup(dev_t m, dev_t* a, int n) {
int k;
for(k=0; k < n && a[k] != m; k++)
;
return (k < n) ? k : -1;
}
/* Device Number -> Name Map
one-to-many: first directory order match in DEVDIR, "" on failed match.
*/
char* dev_to_name(dev_t num) {
static char rval[DEV_NAME_MAX+1];
dev_t m = MAJOR(num), n = MINOR(num), tmp;
if (!devtab_initialized && !init_devtab())
return "";
if ((tmp = lookup(m, major, Nmajor)) == (dev_t)-1)
return "";
strncpy(rval, TAB(tmp,n), DEV_NAME_MAX);
rval[DEV_NAME_MAX] = '\0';
return rval;
}
static int dev_to_devtab(int);
static int init_devtab(void) {
static struct stat sbuf, lbuf;
static int fd;
char **fmt, path[64], *HOME = getenv("HOME") ? getenv("HOME") : "";
for (fmt = devtab_paths; *fmt; fmt++) {
snprintf(path, sizeof path, *fmt, HOME);
lbuf.st_ino = 0; /* initialize for test later */
if (lstat(path, &lbuf) >= 0 && S_ISLNK(lbuf.st_mode))
/* don't follow symlinks */
continue;
if ( (fd = open(path, O_RDONLY)) < 0 /* open DEVTAB file */
|| fstat(fd, &sbuf) < 0 /* fstat it */
|| (lbuf.st_ino && (sbuf.st_ino != lbuf.st_ino)) /* race */
|| sbuf.st_nlink > 1 /* hardlink attack */
|| sbuf.st_size != Ndevtab /* make sure it's the right size */
|| (devtab = mmap(0, Ndevtab, PROT_READ, MAP_SHARED, fd, 0)) == (caddr_t) -1
|| close(fd) == -1)
{ /* could not open for read, attempt to fix/create */
int oumsk = umask(0);
if (devtab)
munmap(devtab, Ndevtab);
if (((fd = open(path, O_RDWR|O_TRUNC|O_CREAT, DEVINITIALMODE)) == -1 &&
(unlink(path), fd = open(path, O_RDWR|O_TRUNC|O_CREAT, DEVINITIALMODE)) == -1)
|| !dev_to_devtab(fd)) {
close(fd); /* either both opens failed or the constructor failed */
unlink(path); /* in case we created but could not fill a file */
umask(oumsk);
continue;
} else {
devtab_initialized = 1;
close(fd);
umask(oumsk);
return 1;
}
}
else
return devtab_initialized = 1;
}
return devtab_initialized;
}
/* stat every file in DEVDIR saving its basename in devtab[] if it has
a MAJOR(st_rdev) in our list of majors. return 0 on error otherwise 1. */
static int dev_to_devtab(int fd) {
static struct stat sbuf;
int i;
dev_t m;
struct dirent* ent;
DIR* dev;
if (!(dev = opendir(DEVDIR))) {
fprintf(stderr, "%s: %s\nCannot generate device number -> name mapping.\n",
DEVDIR, sys_errlist[errno]);
return 0;
}
if (!(devtab = malloc(Ndevtab))) {
fprintf(stderr, "%s: could not allocate memory\n", sys_errlist[errno]);
return 0;
}
memset((void*)devtab, 0, Ndevtab);
while ((ent = readdir(dev))) { /* loop over all dirents in DEVDIR */
if (lstat(name_to_path(ent->d_name), &sbuf) < 0
|| !S_ISCHR(sbuf.st_mode)) /* only look for char special devs */
continue; /* due to overloading of majors */
m = MAJOR(sbuf.st_rdev); /* copy name to appropriate spot */
if ((i = lookup(m, major, Nmajor)) != -1)
strncpy(TAB(i,MINOR(sbuf.st_rdev)), ent->d_name, DEV_NAME_MAX);
}
closedir(dev);
if (write(fd, devtab, Ndevtab) != Ndevtab) /* probably no disk space */
return 0;
return 1;
}
static char path[DEV_MAX_PATH];
static char* name_to_path(char* name) {
static char* Path;
if (!Path) {
strcpy(path, DEVDIR); /* copy DEVDIR */
path[sizeof(DEVDIR) - 1] = '/'; /* change NUL to '/' */
Path = path + sizeof(DEVDIR); /* put Path at start of basename */
}
strncpy(Path, name, DEV_MAX_PATH - sizeof(DEVDIR));
return path;
}
#ifdef TEST_DEVNAME
int main(int argc, char** argv) { /* usage: cmd [<major> <minor>|<name>] */
dev_t tmp;
if (argc < 2) {
printf("%s: [ maj min... | name ... ]\n", argv[0]);
return 0;
}
if (argv[1][0] >= '0' && argv[1][0] <= '9')
for(argv++ ; argv[0] && argv[1] ; argv+=2)
printf("%s\n", dev_to_name(MKDEV( atoi(argv[0]), atoi(argv[1]) )));
else
for(argv++ ; *argv ; argv++) {
tmp = name_to_dev(*argv);
printf("%d, %d\n", MAJOR(tmp), MINOR(tmp));
}
return 0;
}
#endif
/*
Using this program on over 700 files in /dev to perform number->name resolution
took well under 300 microsecs per device number pair on a Pentium 90. It is
somewhat tough to time because once the 3 pages have been mapped in, the time is
almost zero. For things like top, this method may even be faster in the long
run. Those interested can gprof it for me. This system has the virtue of being
nearly perfectly adaptable to individual systems, self updating when /dev
changes and pretty darn fast when it hasn't. It will be slow for users without
perms to change the psdevtab file, though. So this is what I decided was
reasonable. If the process does not have perms to create or update
/etc/psdevtab and it is out of date, we try /tmp/psdevtab. If /tmp/psdevtab is
either out of date or unreadable (malicious user creates it and chmods it),
$HOME/.psdevtab is used. This secondarily allows for per-user naming of ttys,
but is really so that at most one user sees only a single delay per /dev
modification.
To do the timings I did something like this with zsh:
a=(`ls -l *(%^@/) | awk '{print $5 $6}' | sed 's/,/ /'`);
time ./test $a
Finally, for lack of a better file for these to be in, I have collected the
old algorithmic device number <-> device name mappings.
Let m = major device number and n = minor device number satisfy:
devno = m<<8 + n , m = devno>>8 , n = devno && 0x00FF, and let
char L[32]="pqrstuvwxyzABCDEFGHIJKLMNOPQRSTU", H[16]="01234567890abcdef";
DEVICE NUMBERS SPECIAL FILE NAMES
OLD SYSTEM (64 pseudoterminal devices):
m=4:
n=0..63: tty + itoa_dec(n+1)
n=128..191: pty + L[(n-128)/16] + H[(n-128)%16]
n=192..255: tty + L[(n-192)/16] + H[(n-192)%16]
NEW SYSTEM (256/512 pseudoterminal devices):
m=2, n: pty + L[n/16] + H[n%16]
m=3, n: tty + L[n/16] + H[n%16]
m=4, n: tty + itoa_dec(n+1)
m=49, n: pty + L[16+n/16] + H[n%16]
m=50, n: tty + L[16+n/16] + H[n%16]
(THE SAME IN EITHER SYSTEM)
CALL-UNIX AND CONTROLLING TERMINAL DEVICES
m=5:
n=0: tty
n=64..128: cua + {'0' + (n-64)}
CYCLADES MULTIPORT:
m=19, n: ttyC + itoa_hex(n)
m=20, n: cub + itoa_hex(n) */
/* Re-implementation of old interface with the new generic functions. */
/* This does exactly the same thing as name_to_dev only now a full "ttyXX"
specification will work as well.
*/
int tty_to_dev(char *tty) {
static char pref_name_1[32] = "tty", *pnam1 = pref_name_1 + 3,
pref_name_2[32] = "cu", *pnam2 = pref_name_2 + 2;
dev_t num;
if ((num = name_to_dev(tty)) != (dev_t) -1) /* try tty straight up */
return num;
strncpy(pnam1, tty, 32 - 3); /* try with "tty" prepended */
if ((num = name_to_dev(pref_name_1)) != (dev_t) -1)
return num;
strncpy(pnam2, tty, 32 - 2); /* try with "cu" prepended */
if ((num = name_to_dev(pref_name_2)) != (dev_t) -1)
return num;
return -1; /* no match */
}
/* new abstraction that can maybe be generalized a little better. */
char* abbrev_of_tty(char *tty) {
static char temp[32]; /* return buf: good only until next call */
char *pos = strpbrk(tty, "yu"); /* end of (presumed) prefices: tty*, cu* */
temp[0] = 0;
if (tty && tty[0] && pos && pos[0] && pos[1])
sprintf(temp, "%*.*s", 3, 3, pos + 1);
else
strncpy(temp, " ? ", 31);
return temp;
}
/* Do in-place modification of the 4-buffer `tty' based upon `dev' */
void dev_to_tty(char *tty, int dev) {
char* new = abbrev_of_tty(dev_to_name(dev));
strncpy(tty, new, 4);
}

10
libproc/devname.h Normal file
View File

@@ -0,0 +1,10 @@
#include <sys/types.h>
dev_t name_to_dev(char* name);
char* dev_to_name(dev_t num);
dev_t tty_to_dev(char *tty);
void dev_to_tty(char *tty, int dev);
char* abbrev_of_tty(char *tty);

252
libproc/ksym.c Normal file
View File

@@ -0,0 +1,252 @@
/* kernel address -> symbol with next lower address. Charles Blake, 1996.
* Written to obviate the need for psdatabase initialization based upon kernel
* binary formats, etc.
*
* The basic algorithm is an approximate (intervals split vaguely 50-50) binary
* search taking advantage of the fact the System.map is already sorted in
* ascending order by the kernel makefile. It needs to assume an average symbol
* record length to avoid scanning the entire symbol table, but in practice the
* search time does not seem to be especially sensitive to this choice.
*
* The search could be an exact binary search if the lines of System.map were
* padded with blanks to the right. awk '{printf "%8s%2s %-21.21s\n",$1,$2,$3}'
* would do the trick for this but either makes the file large or truncates
* symbols. The approximate method seems to be plenty fast enough, costing
* only about as much as one extra fstat() or so per process.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/utsname.h>
#include "psdata.h"
#include "ps.h"
#include "version.h"
#define MAX_ADDR_SZ 32
static char *sysmap, *sysmap_last, sysmap_fmt[10];
static int sysmap_len, sysmap_mean = 32, sysmap_addrsz;
/* scan backward in a string no further than address beg looking for c */
static char *strchrrev(char *a, char *beg, char c) {
if (a)
while (--a > beg && *a != c) ;
return a;
}
/* return ptr to the beg of approximately the i-th record */
static char *addr_str(int i) {
char *guess = sysmap + sysmap_mean * i;
if (!i) return sysmap;
if (guess - sysmap > sysmap_len - 2) guess = sysmap + sysmap_len - 2;
for ( ; *guess != '\n' && guess > sysmap; guess--)
;
return guess + 1;
}
/* return ptr to symbol string (\n terminated) given beg of record ptr */
static char *sym_put(char *buf, int len, char *addrptr) {
char *s;
while (*addrptr++ != ' ') ;
while (*addrptr++ != ' ') ;
strncpy(buf, addrptr, len);
for (s = buf; s < buf + len; s++)
if (*s == '\n')
*s = '\0';
buf[len - 1] = '\0';
return buf;
}
/* Try to open and mmap a single symbol table file and initialize globals */
int sysmap_mmap(char *path) {
int fd;
struct stat sbuf;
char *p;
if (sysmap) /* do nothing if already mapped */
return 1;
if ((fd = open(path, O_RDONLY)) < 0
|| fstat(fd, &sbuf) < 0
|| (sysmap = mmap(0, sbuf.st_size,
PROT_READ, MAP_SHARED,
fd, 0)) == (caddr_t) -1)
{
close(fd);
sysmap = NULL;
return 0;
}
sysmap_len = sbuf.st_size;
sysmap_last = strchrrev(sysmap + sysmap_len - 2, sysmap, '\n') + 1;
/* Now check first line of sysmap for hex numbers in first column. Note:
0x/0X prefixes are disallowed, but easily addable. Capitalization is
irrelevant because strncasecmp(3) is used below instead of strncmp. */
for (p = sysmap; *p != ' '
&& ((*p >= '0' && *p <= '9') ||
(*p >= 'A' && *p <= 'F') ||
(*p >= 'a' && *p <= 'f'))
&& p < sysmap + MAX_ADDR_SZ;
p++) /* no-op */ ;
if (*p != ' ') { /* uh-oh: cannot understand format */
fprintf(stderr, "warning: %s not parseable as a System.map.\n", path);
munmap(sysmap, sysmap_len);
sysmap = NULL;
close(fd);
return 0;
}
sysmap_addrsz = p - sysmap;
snprintf(sysmap_fmt, sizeof sysmap_fmt, "%%0%dlx", sysmap_addrsz);
close(fd);
return 1;
}
/* kernel address -> name resolver.
returned value is only good until the next call to the function.
*/
char *sysmap_symbol(unsigned long address) {
static char rval[128], *pc, addr[MAX_ADDR_SZ];
int i, p, n = sysmap_len / (double)sysmap_mean;
sprintf(addr, sysmap_fmt, address);
p = 0; pc = sysmap;
while (n) {
i = p + (n >> 1);
if (strncasecmp(addr, pc = addr_str(i), sysmap_addrsz) > 0)
p = i + 1;
n >>= 1;
}
if (pc == sysmap_last) /* scan forward but not past end */
return sym_put(rval, sizeof rval, pc);
while (strncasecmp(addr, pc, sysmap_addrsz) > 0)
pc = strchr(pc, '\n') + 1;
if (pc == sysmap) /* scan backward but not past beg */
return sym_put(rval, sizeof rval, pc);
while (strncasecmp(addr, pc, sysmap_addrsz) < 0)
pc = strchrrev(pc - 1, sysmap, '\n') + 1;
return sym_put(rval, sizeof rval, pc);
}
/* extern struct nlist *namelist; */
struct tbl_s vars, fncs;
struct psdb_hdr db_hdr;
int psdb = -1;
int open_psdb(void) {
static char *sysmap_paths[] = {
"/boot/System.map-%s",
"/boot/System.map",
"/lib/modules/%s/System.map",
NULL
};
static char *psdb_paths[] = {
"/etc/psdatabase",
"/boot/psdatabase-%s",
"/boot/psdatabase",
"/lib/modules/%s/psdatabase",
NULL
};
char **fmt, *env, path[64];
struct utsname uts;
uname(&uts);
if ((env = getenv("PS_SYSMAP")) && sysmap_mmap(env))
return 0;
for (fmt = sysmap_paths; *fmt; fmt++) {
snprintf(path, sizeof path, *fmt, uts.release);
if (sysmap_mmap(path))
return 0;
}
for (fmt = psdb_paths; *fmt; fmt++) {
snprintf(path, sizeof path, *fmt, uts.release);
if ((psdb = open(path, O_RDONLY)) != -1 &&
read(psdb, (char*)&db_hdr, sizeof db_hdr) == sizeof db_hdr &&
strncmp(db_hdr.magic, procps_version, sizeof(db_hdr.magic)) == 0)
/* && version_cmp(kernel,psdatabase) */
return 0;
if (psdb != -1)
fprintf(stderr,
"psdatabase has magic no. %*s instead of %*s\n",
(int) sizeof db_hdr.magic, db_hdr.magic,
(int) sizeof db_hdr.magic, procps_version);
close(psdb);
}
return -1;
}
void close_psdb(void) {
if (sysmap)
munmap(sysmap, sysmap_len);
else if (psdb != -1)
close(psdb);
psdb = -1;
sysmap = NULL;
}
int read_tbl(struct dbtbl_s *dbtbl, struct tbl_s *tbl) {
lseek(psdb, dbtbl->off, SEEK_SET);
tbl->tbl = (struct sym_s *) xmalloc(dbtbl->size);
if (read(psdb, (char *) tbl->tbl, dbtbl->size) != dbtbl->size) {
perror(PSDATABASE);
exit(1);
}
tbl->nsym = dbtbl->nsym;
tbl->strings = (char *) (tbl->tbl + tbl->nsym);
return 0;
}
char * find_func(unsigned long address) {
int n;
struct sym_s *p;
char *s;
if (sysmap)
return sysmap_symbol(address);
if (psdb == -1)
return "(no psdb)";
if (fncs.tbl == NULL)
read_tbl(&db_hdr.fncs, &fncs);
p = fncs.tbl;
n = fncs.nsym;
while (n) {
int i = n / 2;
if (p[i].addr < address) {
p = &p[i+1];
if (p->addr > address) {
--p;
break;
}
--n;
}
n /= 2;
}
s = p->name + fncs.strings;
return *s=='_' ? s+1 : s;
}
char * wchan(unsigned long address) {
static char zero = 0;
char *p;
if (address) {
p = find_func(address);
if (strncmp(p, "sys_", 4) == 0)
p += 4;
while (*p == '_' && *p)
++p;
} else /* 0 address means not in kernel space */
p = &zero;
return p;
}
#ifdef SYSMAP_TEST
int main(int ac, char** av) {
if (ac < 3) {printf("%s System.map lines hexaddr ...\n",av[0]); return 1;}
if (!sysmap_mmap(av[1])) return 1;
if ((sysmap_mean = atoi(av[2])) <= 0) return 1;
for (av += 3; *av; av++)
printf("%s %s\n", *av, sysmap_symbol(strtoul(*av, NULL, 16)));
return 0;
}
#endif

52
libproc/output.c Normal file
View File

@@ -0,0 +1,52 @@
/*
Some output conversion routines for libproc
Copyright (C) 1996, Charles Blake. See COPYING for details.
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
/* output a string, converting unprintables to octal as we go, and stopping after
processing max chars of output (accounting for expansion due to octal rep).
*/
unsigned print_str(FILE* file, char *s, unsigned max) {
int i;
for (i=0; s[i] && i < max; i++)
if (isprint(s[i]) || s[i] == ' ')
fputc(s[i], file);
else {
if (max - i > 3) {
fprintf(file, "\\%03o", s[i]);
i += 3; /* 4 printed, but i counts one */
} else
return max - i;
}
return max - i;
}
/* output an argv style NULL-terminated string list, converting unprintables
to octal as we go, separating items of the list by 'sep' and stopping after
processing max chars of output (accounting for expansion due to octal rep).
*/
unsigned print_strlist(FILE* file, char **strs, char* sep, unsigned max) {
int i, n, seplen = strlen(sep);
for (n=0; *strs && n < max; strs++) {
for (i=0; strs[0][i] && n+i < max; i++)
if (isprint(strs[0][i]) || strs[0][i] == ' ')
fputc(strs[0][i], file);
else {
if (max-(n+i) > 3) {
fprintf(file, "\\%03o", strs[0][i]);
n += 3; /* 4 printed, but i counts one */
} else
return max - n;
}
n += i;
if (n + seplen < max) {
fputs(sep, file);
n += seplen;
} else
return max - n;
}
return max - n;
}

30
libproc/ps.h Normal file
View File

@@ -0,0 +1,30 @@
/* The shadow of the original with only common prototypes now. */
#include <stdio.h>
#include <sys/types.h>
/* get definition of HZ */
#include <asm/param.h>
/* get page info */
#include <asm/page.h>
char *wchan(unsigned long);
char *find_func(unsigned long address);
void *xcalloc(void *pointer, int size);
void *xmalloc(unsigned int size);
void *xrealloc(void *oldp, unsigned int size);
int mult_lvl_cmp(void* a, void* b);
int node_mult_lvl_cmp(void* a, void* b);
void dump_keys(void);
char *user_from_uid(int uid);
int open_sysmap(void);
int open_psdb(void);
void close_psdb(void);
void make_fnctbl(void);
unsigned print_str (FILE* file, char *s, unsigned max);
unsigned print_strlist(FILE* file, char **strs, char* sep, unsigned max);
unsigned snprint_strlist(char *buf, int max, char **strs, char *sep);

103
libproc/psdata.h Normal file
View File

@@ -0,0 +1,103 @@
/*
* psdata.h
*
* Jeffrey A. Uphoff <juphoff@nrao.edu>, 1995, 1996.
* Michael K. Johnson.
* Bruno Lankester.
* (And others I'm sure...)
*
*/
/*
* Capabilities are for reading system images and producing maps for
* WCHAN output.
*
* AOUT_CAPABLE and ELF_CAPABLE may have 32-bit word size limitations
* and have only been tested by the maintainer on Intel systems. They
* are retained in the source tree in case they are useful; they are
* intended to be generally deprecated.
*
* BFD_CAPABLE should work on any system with BFD.
*
* Set the capabilities in the top-level Makefile.
*/
#if defined(ELF_CAPABLE)
# define ELF_OBJECT 1
# define ELF_FUNC 2
#endif
#include <sys/types.h>
#include <linux/utsname.h>
#define PSDATABASE "/etc/psdatabase"
struct dbtbl_s {
off_t off; /* offset in psdatabase */
int nsym; /* # symbols */
int size; /* size of array + strings */
};
/*
* header of psdatabase
*/
struct psdb_hdr {
/* Current procps package version goes here. kmemps doesn't like this. */
char magic[32];
/*
* These are not functional--they only reside in the database for
* informational purposes (i.e. if you want to look at the raw
* database and see what kernel it's for).
*/
char uts_release[__NEW_UTS_LEN];
char uts_version[__NEW_UTS_LEN];
/*
* Again, this is not functional, it's just there for information: it
* shows the path to the uncompressed kernel image that was used to
* generate this database.
*/
char sys_path[128];
/* List of all functions. */
struct dbtbl_s fncs;
/*
* This is currently only used to look up system_utsname while
* psupdate is building the database--it really should be phased out!
*/
/* List of all bss and data symbols. */
struct dbtbl_s vars;
/*
* The list of tty names that kmemps likes/uses in no longer present
* in the procps psdatabase--it was never being built by procps'
* psupdate anyway, so I removed the entry from the database header.
*/
};
struct sym_s {
unsigned long addr; /* core address in kernel */
int name; /* offset from strings ptr */
};
struct tbl_s {
struct sym_s *tbl;
int nsym;
char *strings; /* ptr to start of strings */
};
extern struct psdb_hdr db_hdr;
extern struct tbl_s fncs, vars;
int read_tbl (struct dbtbl_s *, struct tbl_s *);
void *xmalloc (unsigned int);
void *xrealloc (void *, unsigned int);
#define MLSEEK(FD, WHERE, WHENCE, ERROR)\
if (lseek ((FD), (WHERE), (WHENCE)) == -1) {\
perror ((ERROR));\
exit (errno);\
}
#define MREAD(FD, WHAT, SIZE, ERROR)\
if (read ((FD), (WHAT), (SIZE)) != (SIZE)) {\
perror ((ERROR));\
exit (errno);\
}

37
libproc/pwcache.c Normal file
View File

@@ -0,0 +1,37 @@
#include <stdio.h>
#include <stdlib.h>
#include <pwd.h>
#include "ps.h"
#define HASHSIZE 16 /* power of 2 */
#define HASH(x) ((x) & (HASHSIZE - 1))
static struct pwbuf {
int uid;
char name[12];
struct pwbuf *next;
} *pwhash[HASHSIZE];
char *user_from_uid(int uid)
{
struct pwbuf **p;
struct passwd *pw;
p = &pwhash[HASH(uid)];
while (*p) {
if ((*p)->uid == uid)
return((*p)->name);
p = &(*p)->next;
}
*p = (struct pwbuf *) xmalloc(sizeof(struct pwbuf));
(*p)->uid = uid;
if ((pw = getpwuid(uid)) == NULL)
sprintf((*p)->name, "#%d", uid);
else
sprintf((*p)->name, "%-.8s", pw->pw_name);
(*p)->next = NULL;
return((*p)->name);
}
void bad_user_access_length() { }

395
libproc/readproc.c Normal file
View File

@@ -0,0 +1,395 @@
/*
* New Interface to Process Table -- PROCTAB Stream (a la Directory streams)
* Copyright(C) 1996. Charles L. Blake.
*/
#include "version.h"
#include "readproc.h"
#include "devname.h"
#include "ps.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/dir.h>
#include <sys/types.h>
#include <sys/stat.h>
#define Do(x) (flags & PROC_ ## x) /* convenient shorthand */
/* initiate a process table scan
*/
PROCTAB* openproc(int flags, ...) {
va_list ap;
PROCTAB* PT = xmalloc(sizeof(PROCTAB));
if (!Do(PID) && !(PT->procfs = opendir("/proc")))
return NULL;
PT->flags = flags;
va_start(ap, flags); /* Init args list */
if (Do(PID))
PT->pids = va_arg(ap, pid_t*);
else if (Do(TTY))
PT->ttys = va_arg(ap, dev_t*);
else if (Do(UID)) {
PT->uids = va_arg(ap, uid_t*);
PT->nuid = va_arg(ap, int);
} else if (Do(STAT))
PT->stats = va_arg(ap, char*);
va_end(ap); /* Clean up args list */
if (Do(ANYTTY) && Do(TTY))
PT->flags = PT->flags & ~PROC_TTY; /* turn off TTY flag */
return PT;
}
/* terminate a process table scan
*/
void closeproc(PROCTAB* PT) {
if (PT->procfs) closedir(PT->procfs);
if (PT) free(PT);
}
/* deallocate the space allocated by readproc if the passed rbuf was NULL
*/
void freeproc(proc_t* p) {
if (!p) /* in case p is NULL */
return;
/* ptrs are after strings to avoid copying memory when building them. */
/* so free is called on the address of the address of strvec[0]. */
if (p->cmdline)
free((void*)*p->cmdline);
if (p->environ)
free((void*)*p->environ);
free(p);
}
/* stat2proc() makes sure it can handle arbitrary executable file basenames
for `cmd', i.e. those with embedded whitespace or embedded ')'s. Such names
confuse %s (see scanf(3)), so the string is split and %39c is used instead.
(except for embedded ')' "(%[^)]c)" would work.
*/
void stat2proc(char* S, proc_t* P) {
char* tmp = strrchr(S, ')'); /* split into "PID (cmd" and "<rest>" */
*tmp = '\0'; /* replace trailing ')' with NUL */
/* parse these two strings separately, skipping the leading "(". */
memset(P->cmd, 0, sizeof P->cmd); /* clear even though *P xcalloc'd ?! */
sscanf(S, "%d (%39c", &P->pid, P->cmd);
sscanf(tmp + 2, /* skip space after ')' too */
"%c %d %d %d %d %d %lu %lu %lu %lu %lu %ld %ld %ld %ld %d "
"%d %lu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %LX %LX %LX %LX %lu",
&P->state, &P->ppid, &P->pgrp, &P->session, &P->tty, &P->tpgid,
&P->flags, &P->min_flt, &P->cmin_flt, &P->maj_flt, &P->cmaj_flt,
&P->utime, &P->stime, &P->cutime, &P->cstime, &P->priority, &P->nice,
&P->timeout, &P->it_real_value, &P->start_time, &P->vsize, &P->rss,
&P->rss_rlim, &P->start_code, &P->end_code, &P->start_stack,
&P->kstk_esp, &P->kstk_eip, &P->signal, &P->blocked, &P->sigignore,
&P->sigcatch, &P->wchan);
if (P->tty == 0)
P->tty = -1; /* the old notty val, update elsewhere bef. moving to 0 */
if (linux_version_code < LINUX_VERSION(1,3,39)) {
P->priority = 2*15 - P->priority; /* map old meanings to new */
P->nice = 15 - P->nice;
}
if (linux_version_code < LINUX_VERSION(1,1,30) && P->tty != -1)
P->tty = 4*0x100 + P->tty; /* when tty wasn't full devno */
}
void statm2proc(char* s, proc_t* P) {
sscanf(s, "%ld %ld %ld %ld %ld %ld %ld",
&P->size, &P->resident, &P->share,
&P->trs, &P->lrs, &P->drs, &P->dt);
}
void nulls2sep(char* str, int len, char sep) {
int i;
for (i = 0; i < len; i++)
if (str[i] == 0)
str[i] = sep;
}
int file2str(char *directory, char *what, char *ret, int cap) {
static char filename[80];
int fd, num_read;
sprintf(filename, "%s/%s", directory, what);
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;
}
char** file2strvec(char* directory, char* what) {
char buf[2048]; /* read buf bytes at a time */
char *p, *rbuf = 0, *endbuf, **q, **ret;
int fd, tot = 0, n, c, end_of_file = 0;
int align;
sprintf(buf, "%s/%s", directory, what);
if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return NULL;
/* read whole file into a memory buffer, allocating as we go */
while ((n = read(fd, buf, sizeof buf - 1)) > 0) {
if (n < sizeof buf - 1)
end_of_file = 1;
if (n == 0 && rbuf == 0)
return NULL; /* process died between our open and read */
if (n < 0) {
if (rbuf)
free(rbuf);
return NULL; /* read error */
}
if (end_of_file && buf[n-1]) /* last read char not null */
buf[n++] = '\0'; /* so append null-terminator */
rbuf = xrealloc(rbuf, tot + n); /* allocate more memory */
memcpy(rbuf + tot, buf, n); /* copy buffer into it */
tot += n; /* increment total byte ctr */
if (end_of_file)
break;
}
close(fd);
if (n <= 0 && !end_of_file) {
if (rbuf) free(rbuf);
return NULL; /* read error */
}
endbuf = rbuf + tot; /* count space for pointers */
align = (sizeof(char*)-1) - ((tot + sizeof(char*)-1) & (sizeof(char*)-1));
for (c = 0, p = rbuf; p < endbuf; p++)
if (!*p)
c += sizeof(char*);
c += sizeof(char*); /* one extra for NULL term */
rbuf = xrealloc(rbuf, tot + c + align); /* make room for ptrs AT END */
endbuf = rbuf + tot; /* addr just past data buf */
q = ret = (char**) (endbuf+align); /* ==> free(*ret) to dealloc */
*q++ = p = rbuf; /* point ptrs to the strings */
endbuf--; /* do not traverse final NUL */
while (++p < endbuf)
if (!*p) /* NUL char implies that */
*q++ = p+1; /* next string -> next char */
*q = 0; /* null ptr list terminator */
return ret;
}
/* These are some nice GNU C expression subscope "inline" functions.
The can be used with arbitrary types and evaluate their arguments
exactly once.
*/
/* Test if item X of type T is present in the 0 terminated list L */
# define XinL(T, X, L) ( { \
T x = (X), *l = (L); \
while (*l && *l != x) l++; \
*l == x; \
} )
/* Test if item X of type T is present in the list L of length N */
# define XinLN(T, X, L, N) ( { \
T x = (X), *l = (L); \
int i = 0, n = (N); \
while (i < n && l[i] != x) i++; \
i < n && l[i] == x; \
} )
/* readproc: return a pointer to a proc_t filled with requested info about the
* next process available matching the restriction set. If no more such
* processes are available, return a null pointer (boolean false). Use the
* passed buffer instead of allocating space if it is non-NULL. */
/* This is optimized so that if a PID list is given, only those files are
* searched for in /proc. If other lists are given in addition to the PID list,
* the same logic can follow through as for the no-PID list case. This is
* fairly complex, but it does try to not to do any unnecessary work.
* Unfortunately, the reverse filtering option in which any PID *except* the
* ones listed is pursued.
*/
#define flags (PT->flags)
proc_t* readproc(PROCTAB* PT, proc_t* rbuf) {
static struct direct *ent; /* dirent handle */
static struct stat sb; /* stat buffer */
static char path[32], sbuf[256]; /* bufs for stat,statm */
int allocated = 0, matched = 0; /* flags */
proc_t *p = NULL;
/* loop until a proc matching restrictions is found or no more processes */
/* I know this could be a while loop -- this way is easier to indent ;-) */
next_proc: /* get next PID for consideration */
if (Do(PID)) {
if (!*PT->pids) /* set to next item in pids */
return NULL;
sprintf(path, "/proc/%d", *(PT->pids)++);
matched = 1;
} else { /* get next numeric /proc ent */
while ((ent = readdir(PT->procfs)) &&
(*ent->d_name < '0' || *ent->d_name > '9'))
;
if (!ent || !ent->d_name)
return NULL;
sprintf(path, "/proc/%s", ent->d_name);
}
if (stat(path, &sb) == -1) /* no such dirent (anymore) */
goto next_proc;
if (Do(UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid))
goto next_proc; /* not one of the requested uids */
if (!allocated) { /* assign mem for return buf */
p = rbuf ? rbuf : xcalloc(p, sizeof *p); /* passed buf or alloced mem */
allocated = 1; /* remember space is set up */
}
p->uid = sb.st_uid; /* need a way to get real uid */
if ((file2str(path, "stat", sbuf, sizeof sbuf)) == -1)
goto next_proc; /* error reading /proc/#/stat */
stat2proc(sbuf, p); /* parse /proc/#/stat */
if (!matched && Do(TTY) && !XinL(dev_t, p->tty, PT->ttys))
goto next_proc; /* not one of the requested ttys */
if (!matched && Do(ANYTTY) && p->tty == -1)
goto next_proc; /* no controlling terminal */
if (!matched && Do(STAT) && !strchr(PT->stats,p->state))
goto next_proc; /* not one of the requested states */
if (Do(FILLMEM)) { /* read, parse /proc/#/statm */
if ((file2str(path, "statm", sbuf, sizeof sbuf)) != -1 )
statm2proc(sbuf, p); /* ignore statm errors here */
} /* statm fields just zero */
/* some number->text resolving which is time consuming */
if (Do(FILLTTY))
dev_to_tty(p->ttyc, p->tty);
if (Do(FILLUSR))
strncpy(p->user, user_from_uid(p->uid), sizeof p->user);
if (Do(FILLCMD)) /* read+parse /proc/#/cmdline */
p->cmdline = file2strvec(path, "cmdline");
if (Do(FILLENV)) /* read+parse /proc/#/environ */
p->environ = file2strvec(path, "environ");
if (p->state == 'Z') /* fixup cmd for zombies */
strncat(p->cmd," <zombie>", sizeof p->cmd);
return p;
}
#undef flags
/* Convenient wrapper around openproc and readproc to slurp in the whole process
* tree subset satisfying the constraints of flags and the optional PID list.
* Free allocated memory with freeproctree(). The tree structure is a classic
* left-list children + right-list siblings. The algorithm is a two-pass of the
* process table. Since most process trees will have children with strictly
* increasing PIDs, most of the structure will be picked up in the first pass.
* The second loop then cleans up any nodes which turn out to have preceeded
* their parent in /proc order.
*/
/* Traverse tree 't' breadth-first looking for a process with pid p */
proc_t* LookupPID(proc_t* t, pid_t p) {
proc_t* tmp = NULL;
if (!t)
return NULL;
if (t->pid == p) /* look here/terminate recursion */
return t;
if ((tmp = LookupPID(t->l, p))) /* recurse over children */
return tmp;
for (; t; t=t->r) /* recurse over siblings */
if ((tmp = LookupPID(tmp, p)))
return tmp;
return NULL;
}
proc_t* readproctree(int flags, ...) {
static proc_t tree;
PROCTAB* PT = NULL;
proc_t *node, *tmp=NULL, *tmp2=NULL;
va_list ap;
/* pass through apropriate arguments to openproc */
va_start(ap, flags);
if (Do(UID)) {
/* temporary variables to ensure that va_arg() instances
* are called in the right order
*/
uid_t* u;
int i;
u = va_arg(ap, uid_t*);
i = va_arg(ap, int);
PT = openproc(flags, u, i);
}
else if (Do(PID) || Do(TTY) || Do(STAT))
PT = openproc(flags, va_arg(ap, void*));
else
PT = openproc(flags);
va_end(ap);
/* first pass: build tree, putting orphans on the first level */
tree.l = tree.r = NULL;
while ((node = readproc(PT,0)))
if ((tmp = LookupPID(&tree, node->ppid))) {
node->r = tmp->l->r; /* node --> left list of parent */
tmp->l->r = node;
} else {
node->r = tree.r; /* node --> right list of 'tree' */
tree.r = node;
}
/* second pass: scan tree for PPIDs of level-1 nodes moving links as necessary */
for (node = &tree; node; node = node->r)
if ((tmp = LookupPID(&tree, node->r->ppid))) {
tmp2 = node->r; /* unlink from right list of 'tree' */
node->r = node->r->r;
tmp2->r = tmp->l->r; /* insert as child of found node */
tmp->l->r = node;
}
closeproc(PT);
return &tree;
}
/* Convenient wrapper around openproc and readproc to slurp in the whole process
* table subset satisfying the constraints of flags and the optional PID list.
* Free allocated memory with freeproctab(). Access via tab[N]->member. The
* pointer list is NULL terminated.
*/
proc_t** readproctab(int flags, ...) {
PROCTAB* PT = NULL;
proc_t** tab = NULL;
int n = 0;
va_list ap;
va_start(ap, flags); /* pass through args to openproc */
if (Do(UID)) {
/* temporary variables to ensure that va_arg() instances
* are called in the right order
*/
uid_t* u;
int i;
u = va_arg(ap, uid_t*);
i = va_arg(ap, int);
PT = openproc(flags, u, i);
}
else if (Do(PID) || Do(TTY) || Do(STAT))
PT = openproc(flags, va_arg(ap, void*)); /* assume ptr sizes same */
else
PT = openproc(flags);
va_end(ap);
do { /* read table: */
tab = xrealloc(tab, (n+1)*sizeof(proc_t*));/* realloc as we go, using */
tab[n] = readproc(PT, NULL); /* final null to terminate */
} while (tab[n++]); /* stop when NULL reached */
closeproc(PT);
return tab;
}
/* deallocate a table of pointers to proc structures
*/
void freeproctab(proc_t** tab) {
proc_t** p;
for(p = tab; *p; p++)
freeproc(*p);
free(tab);
}

168
libproc/readproc.h Normal file
View File

@@ -0,0 +1,168 @@
/*
* New Interface to Process Table -- PROCTAB Stream (a la Directory streams)
* Copyright(C) 1996. Charles L. Blake.
*/
/* Basic data structure which holds all information we can get about a process.
* (unless otherwise specified, fields are read from /proc/#/stat)
*/
typedef struct proc_s {
char
user[10], /* user name corresponding to owner of process */
cmd[40], /* basename of executable file in call to exec(2) */
state, /* single-char code for process state (S=sleeping) */
ttyc[5], /* string representation of controlling tty device */
**environ, /* environment string vector (/proc/#/environ) */
**cmdline; /* command line string vector (/proc/#/cmdline) */
int
uid, /* user id */
pid, /* process id */
ppid, /* pid of parent process */
pgrp, /* process group id */
session, /* session id */
tty, /* full device number of controlling terminal */
tpgid, /* terminal process group id */
priority, /* kernel scheduling priority */
nice; /* standard unix nice level of process */
long long
signal, /* mask of pending signals */
blocked, /* mask of blocked signals */
sigignore, /* mask of ignored signals */
sigcatch; /* mask of caught signals */
long
start_time, /* start time of process -- seconds since 1-1-70 */
utime, /* user-mode CPU time accumulated by process */
stime, /* kernel-mode CPU time accumulated by process */
cutime, /* cumulative utime of process and reaped children */
cstime, /* cumulative stime of process and reaped children */
/* the next 7 members come from /proc/#/statm */
size, /* total # of pages of memory */
resident, /* number of resident set (non-swapped) pages (4k) */
share, /* number of pages of shared (mmap'd) memory */
trs, /* text resident set size */
lrs, /* shared-lib resident set size */
drs, /* data resident set size */
dt; /* dirty pages */
unsigned
pcpu; /* %CPU usage (is not filled in by readproc!!!) */
unsigned long
vsize, /* number of pages of virtual memory ... */
rss, /* resident set size from /proc/#/stat */
rss_rlim, /* resident set size ... ? */
timeout, /* ? */
it_real_value, /* ? */
flags, /* kernel flags for the process */
min_flt, /* number of minor page faults since process start */
maj_flt, /* number of major page faults since process start */
cmin_flt, /* cumulative min_flt of process and child processes */
cmaj_flt, /* cumulative maj_flt of process and child processes */
start_code, /* address of beginning of code segment */
end_code, /* address of end of code segment */
start_stack, /* address of the bottom of stack for the process */
kstk_esp, /* kernel stack pointer */
kstk_eip, /* kernel stack pointer */
wchan; /* address of kernel wait channel proc is sleeping in */
struct proc_s *l, /* ptrs for building arbitrary linked structs */
*r; /* (i.e. singly/doubly-linked lists and trees */
} proc_t;
/* PROCTAB: data structure holding the persistent information readproc needs
* from openproc(). The setup is intentionally similar to the dirent interface
* and other system table interfaces (utmp+wtmp come to mind).
*/
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
typedef struct {
DIR* procfs;
int flags;
pid_t* pids; /* pids of the procs */
dev_t* ttys; /* devnos of the cttys */
uid_t* uids; /* uids of procs */
int nuid; /* cannot really sentinel-terminate unsigned short[] */
char* stats; /* status chars (actually output into /proc//stat) */
} PROCTAB;
/* initialize a PROCTAB structure holding needed call-to-call persistent data
*/
PROCTAB* openproc(int flags, ... /* pid_t*|uid_t*|dev_t*|char* [, int n] */ );
/* Convenient wrapper around openproc and readproc to slurp in the whole process
* table subset satisfying the constraints of flags and the optional PID list.
* Free allocated memory with freeproctab(). Access via tab[N]->member. The
* pointer list is NULL terminated.
*/
proc_t** readproctab(int flags, ... /* same as openproc */ );
/* Convenient wrapper around openproc and readproc to slurp in the whole process
* tree subset satisfying the constraints of flags and the optional PID list.
*/
proc_t* readproctree(int flags, ... /* same as openproc */ );
/* clean-up open files, etc from the openproc()
*/
void closeproc(PROCTAB* PT);
/* retrieve the next process matching the criteria set by the openproc()
*/
proc_t* readproc(PROCTAB* PT, proc_t* return_buf);
/* deallocate space allocated by readproc
*/
void freeproc(proc_t* p);
/* deallocate space allocated by readproctab
*/
void freeproctab(proc_t** p);
/* openproc/readproctab:
*
* Return PROCTAB* / *proc_t[] or NULL on error ((probably) "/proc" cannot be
* opened.) By default readproc will consider all processes as valid to parse
* and return, but not actually fill in the cmdline, environ, and /proc/#/statm
* derived memory fields.
*
* `flags' (a bitwise-or of PROC_* below) modifies the default behavior. The
* "fill" options will cause more of the proc_t to be filled in. The "filter"
* options all use the second argument as the pointer to a list of objects:
* process status', process id's, user id's, and tty device numbers. The third
* argument is the length of the list (currently only used for lists of user
* id's since unsigned short[] supports no convenient termination sentinel.)
*/
#define PROC_FILLMEM 0x1 /* read statm into the appropriate proc_t entries */
#define PROC_FILLCMD 0x2 /* alloc and fill in `cmdline' part of proc_t */
#define PROC_FILLENV 0x4 /* alloc and fill in `environ' part of proc_t */
#define PROC_FILLTTY 0x8 /* resolve device number -> tty name via psdevtab */
#define PROC_FILLUSR 0x10 /* resolve user id number -> user name via passwd */
/* consider only processes with one of the passed: */
#define PROC_PID 0x100 /* process id numbers ( 0 terminated) */
#define PROC_TTY 0x200 /* ctty device nos. ( 0 terminated) */
#define PROC_UID 0x400 /* user id numbers ( length needed ) */
#define PROC_STAT 0x800 /* status fields ('\0' terminated) */
#define PROC_ANYTTY 0x1000 /* proc must have a controlling terminal */
/* utility functions which may be of general interest: */
/* slurp /proc/DIR/FILE into a single large string into the passed
buffer. return the number of bytes actually used. used for stat,statm
*/
int file2str(char *dir, char *file, char *buf, int buf_size);
/* convert a file of null terminated strings into an argv-style string vector
* which may be de-allocated with a single free() on a dereference of the return
* value, e.g. free(*ret). used for cmdline, environ.
*/
char** file2strvec(char* directory, char* what);
/* parse /proc/#/stat entries in string s into a proc_t
*/
void stat2proc(char* S, proc_t*);
/* parse /proc/#/statm entries in string s into a proc_t
*/
void statm2proc(char* s, proc_t*);
/* convert a memory buffer with nulls into a single string,
replacing the nulls with sep. No longer used.
*/
void nulls2sep(char* str, int len, char sep);

65
libproc/signals.c Normal file
View File

@@ -0,0 +1,65 @@
/* signals.c - signal name handling */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "signals.h"
typedef struct {
int number;
char *name;
} SIGNAME;
static SIGNAME signals[] = {
#include "signames.h" /* should be in same dir as this file */
{ 0,NULL }};
void list_signals(void)
{
SIGNAME *walk;
int col;
col = 0;
for (walk = signals; walk->name; walk++) {
if (col+strlen(walk->name)+1 > 80) {
putchar('\n');
col = 0;
}
printf("%s%s",col ? " " : "",walk->name);
col += strlen(walk->name)+1;
}
putchar('\n');
}
int get_signal(char *name,char *cmd)
{
SIGNAME *walk;
if (isdigit(*name))
return atoi(name);
for (walk = signals; walk->name; walk++)
if (!strcmp(walk->name,name)) break;
if (walk->name) return walk->number;
fprintf(stderr,"%s: unknown signal; %s -l lists signals.\n",name,cmd);
exit(1);
}
/* get_signal2 is by Michael Shields. 1994/04/25. */
int get_signal2(char *name)
{
SIGNAME *walk;
if (!name)
return(-1);
if (isdigit(*name))
return atoi(name);
for (walk = signals; walk->name; walk++)
if (!strcmp(walk->name,name))
return(walk->number);
return(-1);
}

12
libproc/signals.h Normal file
View File

@@ -0,0 +1,12 @@
/* signals.h - signal name handling */
void list_signals(void);
/* Lists all known signal names on standard output. */
int get_signal(char *name,char *cmd);
int get_signal2(char *name);
/* Returns the signal number of NAME. If no such signal exists, an error
message is displayed and the program is terminated. CMD is the name of the
application. */

32
libproc/signames.h Normal file
View File

@@ -0,0 +1,32 @@
{ 1,"HUP" },
{ 2,"INT" },
{ 3,"QUIT" },
{ 4,"ILL" },
{ 5,"TRAP" },
{ 6,"ABRT" },
{ 6,"IOT" },
{ 7,"BUS" },
{ 8,"FPE" },
{ 9,"KILL" },
{ 10,"USR1" },
{ 11,"SEGV" },
{ 12,"USR2" },
{ 13,"PIPE" },
{ 14,"ALRM" },
{ 15,"TERM" },
{ 16,"STKFLT" },
{ 17,"CHLD" },
{ 18,"CONT" },
{ 19,"STOP" },
{ 20,"TSTP" },
{ 21,"TTIN" },
{ 22,"TTOU" },
{ 23,"URG" },
{ 24,"XCPU" },
{ 25,"XFSZ" },
{ 26,"VTALRM" },
{ 27,"PROF" },
{ 28,"WINCH" },
{ 29,"IO" },
{ 30,"PWR" },
{ 31,"UNUSED" },

20
libproc/status.c Normal file
View File

@@ -0,0 +1,20 @@
#include "ps.h"
#include "readproc.h"
char * status(proc_t* task) {
static char buf[4] = " ";
buf[0] = task->state;
if (task->rss == 0 && task->state != 'Z')
buf[1] = 'W';
else
buf[1] = ' ';
if (task->nice < 0)
buf[2] = '<';
else if (task->nice > 0)
buf[2] = 'N';
else
buf[2] = ' ';
return(buf);
}

176
libproc/sysinfo.c Normal file
View File

@@ -0,0 +1,176 @@
/* File for parsing top-level /proc entities. */
#include "sysinfo.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <fcntl.h>
#include "version.h"
#define BAD_OPEN_MESSAGE \
"Error: /proc must be mounted\n" \
" To mount /proc at boot you need an /etc/fstab line like:\n" \
" /proc /proc proc defaults\n" \
" In the meantime, mount /proc /proc -t proc\n"
#define UPTIME_FILE "/proc/uptime"
#define LOADAVG_FILE "/proc/loadavg"
#define MEMINFO_FILE "/proc/meminfo"
static char buf[1024];
/* This macro opens FILE only if necessary and seeks to 0 so that successive
calls to the functions are more efficient. It also reads the current
contents of the file into the global buf.
*/
#define FILE_TO_BUF(FILE) { \
static int n, fd = -1; \
if (fd == -1 && (fd = open(FILE, O_RDONLY)) == -1) { \
fprintf(stderr, BAD_OPEN_MESSAGE); \
close(fd); \
return 0; \
} \
lseek(fd, 0L, SEEK_SET); \
if ((n = read(fd, buf, sizeof buf - 1)) < 0) { \
perror(FILE); \
close(fd); \
fd = -1; \
return 0; \
} \
buf[n] = '\0'; \
}
#define SET_IF_DESIRED(x,y) if (x) *(x) = (y) /* evals 'x' twice */
int uptime(double *uptime_secs, double *idle_secs) {
double up=0, idle=0;
FILE_TO_BUF(UPTIME_FILE)
if (sscanf(buf, "%lf %lf", &up, &idle) < 2) {
fprintf(stderr, "bad data in " UPTIME_FILE "\n");
return 0;
}
SET_IF_DESIRED(uptime_secs, up);
SET_IF_DESIRED(idle_secs, idle);
return up; /* assume never be zero seconds in practice */
}
int loadavg(double *av1, double *av5, double *av15) {
double avg_1=0, avg_5=0, avg_15=0;
FILE_TO_BUF(LOADAVG_FILE)
if (sscanf(buf, "%lf %lf %lf", &avg_1, &avg_5, &avg_15) < 3) {
fprintf(stderr, "bad data in " LOADAVG_FILE "\n");
exit(1);
}
SET_IF_DESIRED(av1, avg_1);
SET_IF_DESIRED(av5, avg_5);
SET_IF_DESIRED(av15, avg_15);
return 1;
}
/* The following /proc/meminfo parsing routine assumes the following format:
[ <label> ... ] # header lines
[ <label> ] <num> [ <num> ... ] # table rows
[ repeats of above line ]
Any lines with fewer <num>s than <label>s get trailing <num>s set to zero.
The return value is a NULL terminated unsigned** which is the table of
numbers without labels. Convenient enumeration constants for the major and
minor dimensions are available in the header file. Note that this version
requires that labels do not contain digits. It is readily extensible to
labels which do not *begin* with digits, though.
*/
#define MAX_ROW 3 /* these are a little liberal for flexibility */
#define MAX_COL 7
unsigned** meminfo(void) {
static unsigned *row[MAX_ROW + 1]; /* row pointers */
static unsigned num[MAX_ROW * MAX_COL]; /* number storage */
char *p;
char fieldbuf[12]; /* bigger than any field name or size in kb */
int i, j, k, l;
set_linux_version();
FILE_TO_BUF(MEMINFO_FILE)
if (!row[0]) /* init ptrs 1st time through */
for (i=0; i < MAX_ROW; i++) /* std column major order: */
row[i] = num + MAX_COL*i; /* A[i][j] = A + COLS*i + j */
p = buf;
for (i=0; i < MAX_ROW; i++) /* zero unassigned fields */
for (j=0; j < MAX_COL; j++)
row[i][j] = 0;
if (linux_version_code < LINUX_VERSION(2,0,0)) {
for (i=0; i < MAX_ROW && *p; i++) { /* loop over rows */
while(*p && !isdigit(*p)) p++; /* skip chars until a digit */
for (j=0; j < MAX_COL && *p; j++) { /* scanf column-by-column */
l = sscanf(p, "%u%n", row[i] + j, &k);
p += k; /* step over used buffer */
if (*p == '\n' || l < 1) /* end of line/buffer */
break;
}
}
}
else {
while(*p) {
sscanf(p,"%11s%n",fieldbuf,&k);
if(!strcmp(fieldbuf,"MemTotal:")) {
p+=k;
sscanf(p," %d",&(row[meminfo_main][meminfo_total]));
row[meminfo_main][meminfo_total]<<=10;
while(*p++ != '\n');
}
else if(!strcmp(fieldbuf,"MemFree:")) {
p+=k;
sscanf(p," %d",&(row[meminfo_main][meminfo_free]));
row[meminfo_main][meminfo_free]<<=10;
while(*p++ != '\n');
}
else if(!strcmp(fieldbuf,"MemShared:")) {
p+=k;
sscanf(p," %d",&(row[meminfo_main][meminfo_shared]));
row[meminfo_main][meminfo_shared]<<=10;
while(*p++ != '\n');
}
else if(!strcmp(fieldbuf,"Buffers:")) {
p+=k;
sscanf(p," %d",&(row[meminfo_main][meminfo_buffers]));
row[meminfo_main][meminfo_buffers]<<=10;
while(*p++ != '\n');
}
else if(!strcmp(fieldbuf,"Cached:")) {
p+=k;
sscanf(p," %d",&(row[meminfo_main][meminfo_cached]));
row[meminfo_main][meminfo_cached]<<=10;
while(*p++ != '\n');
}
else if(!strcmp(fieldbuf,"SwapTotal:")) {
p+=k;
sscanf(p," %d",&(row[meminfo_swap][meminfo_total]));
row[meminfo_swap][meminfo_total]<<=10;
while(*p++ != '\n');
}
else if(!strcmp(fieldbuf,"SwapFree:")) {
p+=k;
sscanf(p," %d",&(row[meminfo_swap][meminfo_free]));
row[meminfo_swap][meminfo_free]<<=10;
while(*p++ != '\n');
}
else
while(*p++ != '\n'); /* ignore lines we don't understand */
}
row[meminfo_swap][meminfo_used]=row[meminfo_swap][meminfo_total]-row[meminfo_swap][meminfo_free];
row[meminfo_main][meminfo_used]=row[meminfo_main][meminfo_total]-row[meminfo_main][meminfo_free];
}
return row; /* NULL return ==> error */
}
/* shorthand for read_table("/proc/meminfo")[meminfo_main][meminfo_total] */
unsigned read_total_main(void) {
unsigned** mem;
return (mem = meminfo()) ? mem[meminfo_main][meminfo_total] : -1;
}

17
libproc/sysinfo.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef SYSINFO_H
#define SYSINFO_H
int loadavg(double *av1, double *av5, double *av15);
int uptime (double *uptime_secs, double *idle_secs);
unsigned** meminfo(void);
enum meminfo_row { meminfo_main = 0,
meminfo_swap };
enum meminfo_col { meminfo_total = 0, meminfo_used, meminfo_free,
meminfo_shared, meminfo_buffers, meminfo_cached
};
unsigned read_total_main(void);
#endif /* SYSINFO_H */

14
libproc/tree.h Normal file
View File

@@ -0,0 +1,14 @@
struct tree_node {
proc_t *proc;
pid_t pid;
pid_t ppid;
char *line;
char *cmd;
char **cmdline;
char **environ;
int children;
int maxchildren;
int *child;
int have_parent;
};

39
libproc/version.c Normal file
View File

@@ -0,0 +1,39 @@
/* Suite version information for procps utilities
* Copyright (c) 1995 Martin Schulze <joey@infodrom.north.de>
* Ammended by cblake to only export the function symbol.
*/
#include <stdio.h>
#ifdef MINORVERSION
char procps_version[] = "procps version " VERSION "." SUBVERSION "." MINORVERSION;
#else
char procps_version[] = "procps version " VERSION "." SUBVERSION;
#endif
void display_version(void) {
fprintf(stdout, "%s\n", procps_version);
}
/* Linux kernel version information for procps utilities
* Copyright (c) 1996 Charles Blake <cblake@bbn.com>
*/
#include <sys/utsname.h>
#define LINUX_VERSION(x,y,z) (0x10000*(x) + 0x100*(y) + z)
int linux_version_code = 0;
void set_linux_version(void) {
static struct utsname uts;
int x = 0, y = 0, z = 0; /* cleared in case sscanf() < 3 */
if (linux_version_code) return;
if (uname(&uts) == -1) /* failure most likely implies impending death */
exit(1);
if (sscanf(uts.release, "%d.%d.%d", &x, &y, &z) < 3)
fprintf(stderr, /* *very* unlikely to happen by accident */
"Non-standard uts for running kernel:\n"
"release %s=%d.%d.%d gives version code %d\n",
uts.release, x, y, z, LINUX_VERSION(x,y,z));
linux_version_code = LINUX_VERSION(x, y, z);
}

24
libproc/version.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef PROC_VERSION_H
#define PROC_VERSION_H
/* Suite version information for procps utilities
* Copyright (c) 1995 Martin Schulze <joey@infodrom.north.de>
* Linux kernel version information for procps utilities
* Copyright (c) 1996 Charles Blake <cblake@bbn.com>
*/
extern void display_version(void); /* display suite version */
extern char procps_version[]; /* global buf for suite version */
extern int linux_version_code; /* runtime version of LINUX_VERSION_CODE
in /usr/include/linux/version.h */
extern void set_linux_version(void); /* set linux_version_code */
/* Convenience macros for composing/decomposing version codes */
#define LINUX_VERSION(x,y,z) (0x10000*(x) + 0x100*(y) + z)
#define LINUX_VERSION_MAJOR(x) ((x) & 0xFF0000) /* Dare we hope for a */
#define LINUX_VERSION_MINOR(x) ((x) & 0x00FF00) /* Linux 256.0.0? ;-) */
#define LINUX_VERSION_PATCH(x) ((x) & 0x0000FF)
#endif /* PROC_VERSION_H */

89
libproc/whattime.c Normal file
View File

@@ -0,0 +1,89 @@
/* This is a trivial uptime program. I hereby release this program
* into the public domain. I disclaim any responsibility for this
* program --- use it at your own risk. (as if there were any.. ;-)
* -michaelkjohnson (johnsonm@sunsite.unc.edu)
*
* Modified by Larry Greenfield to give a more traditional output,
* count users, etc. (greenfie@gauss.rutgers.edu)
*
* Modified by mkj again to fix a few tiny buglies.
*
* Modified by J. Cowley to add printing the uptime message to a
* string (for top) and to optimize file handling. 19 Mar 1993.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <utmp.h>
#include <sys/ioctl.h>
#include "whattime.h"
#include "sysinfo.h"
static char buf[128];
double av[3];
char *sprint_uptime(void) {
struct utmp *utmpstruct;
int upminutes, uphours, updays;
int pos;
struct tm *realtime;
time_t realseconds;
int numuser;
double uptime_secs, idle_secs;
/* first get the current time */
time(&realseconds);
realtime = localtime(&realseconds);
pos = sprintf(buf, " %2d:%02d%s ",
realtime->tm_hour%12 ? realtime->tm_hour%12 : 12,
realtime->tm_min, realtime->tm_hour > 11 ? "pm" : "am");
/* read and calculate the amount of uptime */
uptime(&uptime_secs, &idle_secs);
updays = (int) uptime_secs / (60*60*24);
strcat (buf, "up ");
pos += 3;
if (updays)
pos += sprintf(buf + pos, "%d day%s, ", updays, (updays != 1) ? "s" : "");
upminutes = (int) uptime_secs / 60;
uphours = upminutes / 60;
uphours = uphours % 24;
upminutes = upminutes % 60;
if(uphours)
pos += sprintf(buf + pos, "%2d:%02d, ", uphours, upminutes);
else
pos += sprintf(buf + pos, "%d min, ", upminutes);
/* count the number of users */
numuser = 0;
setutent();
while ((utmpstruct = getutent())) {
if ((utmpstruct->ut_type == USER_PROCESS) &&
(utmpstruct->ut_name[0] != '\0'))
numuser++;
}
endutent();
pos += sprintf(buf + pos, "%2d user%s, ", numuser, numuser == 1 ? "" : "s");
loadavg(&av[0], &av[1], &av[2]);
pos += sprintf(buf + pos, " load average: %.2f, %.2f, %.2f",
av[0], av[1], av[2]);
return buf;
}
void print_uptime(void)
{
printf("%s\n", sprint_uptime());
}

9
libproc/whattime.h Normal file
View File

@@ -0,0 +1,9 @@
/* whattime.h --- see whattime.c for explanation */
#ifndef __WHATTIME_H
#define __WHATTIME_H
void print_uptime(void);
char *sprint_uptime(void);
#endif

View File

@@ -1,68 +1,205 @@
lib/close.c
lib/command.c
lib/close.c
lib/init.c
lib/sysdeps.c
lib/open.c
lib/read.c
lib/write.c
lib/read_data.c
acconfig.h
glibtop.h
include/glibtop/command.h
lib/parameter.c
lib/write.c
examples/mountlist.c
examples/first.c
examples/second.c
examples/third.c
include/glibtop/close.h
include/glibtop/global.h
include/glibtop/signal.h
include/glibtop/command.h
include/glibtop/cpu.h
include/glibtop/global.h
include/glibtop/error.h
include/glibtop/shm_limits.h
include/glibtop/uptime.h
include/glibtop/output.h
include/glibtop/mem.h
include/glibtop/open.h
include/glibtop/sysdeps.h
include/glibtop/union.h
include/glibtop/read.h
include/glibtop/swap.h
include/glibtop/loadavg.h
include/glibtop/mem.h
include/glibtop/msg_limits.h
include/glibtop/open.h
include/glibtop/output.h
include/glibtop/prockernel.h
include/glibtop/proclist.h
include/glibtop/procmem.h
include/glibtop/procsegment.h
include/glibtop/procsignal.h
include/glibtop/procstate.h
include/glibtop/proctime.h
include/glibtop/procuid.h
include/glibtop/read.h
include/glibtop/read_data.h
include/glibtop/sem_limits.h
include/glibtop/shm_limits.h
include/glibtop/swap.h
include/glibtop/sysdeps.h
include/glibtop/types.h
include/glibtop/union.h
include/glibtop/uptime.h
include/glibtop/version.h
include/glibtop/write.h
include/glibtop/parameter.h
include/glibtop/gnuserv.h
include/glibtop/mountlist.h
include/glibtop/xmalloc.h
include/glibtop/msg_limits.h
include/glibtop/proclist.h
include/glibtop/sem_limits.h
include/glibtop/read_data.h
src/server/main.c
src/server/output.c
src/server/version.c
src/daemon/main.c
src/daemon/slave.c
src/daemon/io.c
src/daemon/server_config.h
src/daemon/daemon.h
src/daemon/gnuserv.c
sysdeps/common/gnuslib.c
sysdeps/common/fsusage.c
sysdeps/common/fsusage.h
sysdeps/common/mountlist.c
sysdeps/common/mountlist.h
sysdeps/linux/loadavg.c
sysdeps/linux/close.c
sysdeps/linux/cpu.c
sysdeps/linux/mem.c
sysdeps/linux/open.c
sysdeps/linux/swap.c
sysdeps/linux/shm_limits.c
sysdeps/linux/msg_limits.c
sysdeps/linux/uptime.c
sysdeps/linux/loadavg.c
sysdeps/linux/sem_limits.c
sysdeps/linux/mem.c
sysdeps/linux/procdata.c
sysdeps/linux/open.c
sysdeps/linux/prockernel.c
sysdeps/linux/proclist.c
sysdeps/stub/proclist.c
sysdeps/stub/close.c
sysdeps/stub/cpu.c
sysdeps/stub/mem.c
sysdeps/stub/open.c
sysdeps/stub/swap.c
sysdeps/stub/loadavg.c
sysdeps/stub/uptime.c
sysdeps/stub/shm_limits.c
sysdeps/stub/msg_limits.c
sysdeps/stub/sem_limits.c
sysdeps/common/sysdeps.c
sysdeps/common/xmalloc.c
sysdeps/common/error.c
sysdeps/names/sysdeps.c
sysdeps/names/cpu.c
sysdeps/linux/procmem.c
sysdeps/linux/procsegment.c
sysdeps/linux/procsignal.c
sysdeps/linux/procstate.c
sysdeps/linux/proctime.c
sysdeps/linux/procuid.c
sysdeps/linux/sem_limits.c
sysdeps/linux/siglist.c
sysdeps/linux/glibtop_server.h
sysdeps/linux/swap.c
sysdeps/linux/uptime.c
sysdeps/linux/glibtop_machine.h
sysdeps/linux/shm_limits.c
sysdeps/names/loadavg.c
sysdeps/names/cpu.c
sysdeps/names/msg_limits.c
sysdeps/names/mem.c
sysdeps/names/prockernel.c
sysdeps/names/proclist.c
sysdeps/names/procmem.c
sysdeps/names/procsegment.c
sysdeps/names/procsignal.c
sysdeps/names/procstate.c
sysdeps/names/proctime.c
sysdeps/names/procuid.c
sysdeps/names/sem_limits.c
sysdeps/names/shm_limits.c
sysdeps/names/swap.c
sysdeps/names/uptime.c
sysdeps/names/shm_limits.c
sysdeps/names/msg_limits.c
sysdeps/names/sem_limits.c
sysdeps/names/proclist.c
sysdeps/names/sysdeps.c
sysdeps/osf1/close.c
sysdeps/osf1/glibtop_machine.h
sysdeps/osf1/loadavg.c
sysdeps/osf1/cpu.c
sysdeps/osf1/msg_limits.c
sysdeps/osf1/mem.c
sysdeps/osf1/procdata.c
sysdeps/osf1/open.c
sysdeps/osf1/sem_limits.c
sysdeps/osf1/shm_limits.c
sysdeps/osf1/glibtop_server.h
sysdeps/osf1/siglist.c
sysdeps/osf1/swap.c
sysdeps/osf1/uptime.c
sysdeps/stub/loadavg.c
sysdeps/stub/close.c
sysdeps/stub/cpu.c
sysdeps/stub/msg_limits.c
sysdeps/stub/mem.c
sysdeps/stub/prockernel.c
sysdeps/stub/open.c
sysdeps/stub/proclist.c
sysdeps/stub/procmem.c
sysdeps/stub/procsegment.c
sysdeps/stub/procsignal.c
sysdeps/stub/procstate.c
sysdeps/stub/proctime.c
sysdeps/stub/procuid.c
sysdeps/stub/sem_limits.c
sysdeps/stub/swap.c
sysdeps/stub/glibtop_server.h
sysdeps/stub/shm_limits.c
sysdeps/stub/siglist.c
sysdeps/stub/uptime.c
sysdeps/kernel/loadavg.c
sysdeps/kernel/close.c
sysdeps/kernel/cpu.c
sysdeps/kernel/msg_limits.c
sysdeps/kernel/mem.c
sysdeps/kernel/procdata.c
sysdeps/kernel/open.c
sysdeps/kernel/prockernel.c
sysdeps/kernel/proclist.c
sysdeps/kernel/procmem.c
sysdeps/kernel/procsegment.c
sysdeps/kernel/procsignal.c
sysdeps/kernel/procstate.c
sysdeps/kernel/proctime.c
sysdeps/kernel/procuid.c
sysdeps/kernel/sem_limits.c
sysdeps/kernel/kernel.h
sysdeps/kernel/glibtop_server.h
sysdeps/kernel/swap.c
sysdeps/kernel/uptime.c
sysdeps/kernel/shm_limits.c
sysdeps/kernel/siglist.c
intl/bindtextdom.c
intl/cat-compat.c
intl/dcgettext.c
intl/dgettext.c
intl/explodename.c
intl/gettext.h
intl/gettextP.h
intl/hash-string.h
intl/finddomain.c
intl/gettext.c
intl/libgettext.h
intl/loadinfo.h
intl/intl-compat.c
intl/l10nflist.c
intl/loadmsgcat.c
intl/localealias.c
intl/textdomain.c
support/argp-ba.c
support/argp-eexst.c
support/argp-fmtstream.c
support/argp-fmtstream.h
support/argp-fs-xinl.c
support/argp-help.c
support/argp-namefrob.h
support/argp-parse.c
support/argp-pv.c
support/argp-pvh.c
support/argp-test.c
support/argp-xinl.c
support/argp.h
support/easy-vsnprintf.c
support/getopt.c
support/getopt.h
support/getopt1.c
support/gnome-argp.c
support/gnome-argp.h
support/long-options.c
support/long-options.h
support/scandir.c
support/strcasecmp.c
support/strerror.c
support/strndup.c
support/strnlen.c
support/strtok_r.c
support/vasprintf.c
support/vsnprintf.c
support/strtod.c
support/memmove.c
support/mkstemp.c
support/strtol.c
support/strtoul.c
glibtop.h

View File

@@ -1 +1,10 @@
SUBDIRS = server proxy daemon
if NEED_LIBGTOP
server_SUBDIRS = server
else
server_SUBDIRS =
endif
SUBDIRS = $(server_SUBDIRS) daemon
DIST_SUBDIRS = server daemon

Some files were not shown because too many files have changed in this diff Show More