diff --git a/.cvsignore b/.cvsignore index 80d5ee28..6398ffdf 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,5 +1,7 @@ Makefile Makefile.in +call-vector.h +call-vector.h aclocal.m4 config.cache config.h diff --git a/ChangeLog b/ChangeLog index 0096508e..a20968b1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2000-01-01 Martin Baulig + + * backends/: New directory. + * backends/server/: New directory. + * backends/sysdeps/: New directory. + + * include/glibtop/backend.h: New file. + + * include/glibtop/call-vector.h.in: New file. Template file + for `call-vector.h'. + * include/glibtop/call-vector.pl: New file. Creates 'call-vector.h' + from `call-vector.h.in'. + + * include/glibtop/errors.h + (GLIBTOP_ERROR_NO_SUCH_BACKEND): New error constant. + (GLIBTOP_ERROR_NOT_IMPLEMENTED): New error constant. + + * include/glibtop/limits.h + (GLIBTOP_BACKEND_NAME_LEN): New constant. + + * glibtop-server-private.h (glibtop_server_private): + Added `GSList *backend_list' and removed `input', `output', + `socket' and `pid'. + + * lib/command.c: Removed. Moved to `backends/server/'. + * lib/read.c: Removed. Moved to `backends/server/'. + * lib/read_data.c: Removed. Moved to `backends/server/'. + * lib/write.c: Removed. Moved to `backends/server/'. + 2000-01-01 Fatih Demir * configure.in: Added tr to ALL_LINGUAS . diff --git a/Makefile.am b/Makefile.am index 82a4fc3e..3c6657ef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,8 +4,8 @@ if BUILD_GNOME_SUPPORT support = support endif -SUBDIRS = po intl $(support) macros misc include sysdeps lib src doc \ - scripts +SUBDIRS = po intl $(support) macros misc include sysdeps backends lib \ + src doc scripts include_HEADERS = glibtop.h configincludedir = $(pkglibdir)/include diff --git a/backends/.cvsignore b/backends/.cvsignore new file mode 100644 index 00000000..da7b4816 --- /dev/null +++ b/backends/.cvsignore @@ -0,0 +1,5 @@ +.deps +.libs +Makefile +Makefile.in +*.lo diff --git a/backends/Makefile.am b/backends/Makefile.am new file mode 100644 index 00000000..2ab590df --- /dev/null +++ b/backends/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = server sysdeps diff --git a/configure.in b/configure.in index e015da3e..ce1f0fd9 100644 --- a/configure.in +++ b/configure.in @@ -347,7 +347,7 @@ fi LIBGTOP_EXTRA_LIBS="$LIBGTOP_EXTRA_LIBS $GLIB_LIBS" -LIBGTOP_LIBS="$LIBGTOP_LIBS -lgtop_sysdeps -lgtop_common -lgtop" +LIBGTOP_LIBS="$LIBGTOP_LIBS -lgtop_sysdeps -lgtop_common -lgtop -lgtop_backend_server -lgtop_backend_sysdeps" LIBGTOP_NAMES_LIBS="$LIBGTOP_LIBS -lgtop_names" @@ -539,6 +539,9 @@ src/Makefile src/daemon/Makefile src/inodedb/Makefile scripts/Makefile +backends/Makefile +backends/server/Makefile +backends/sysdeps/Makefile lib/Makefile doc/Makefile support/Makefile diff --git a/glibtop-server-private.h b/glibtop-server-private.h index 20fcb280..c17b28a8 100644 --- a/glibtop-server-private.h +++ b/glibtop-server-private.h @@ -30,15 +30,14 @@ #include #endif +#include + struct _glibtop_server_private { #ifdef HAVE_GLIBTOP_MACHINE_H glibtop_machine machine; /* Machine dependent data */ #endif - int input [2]; /* Pipe client <- server */ - int output [2]; /* Pipe client -> server */ - int socket; /* Accepted connection of a socket */ - pid_t pid; /* PID of the server */ + GSList *backend_list; }; #endif diff --git a/include/glibtop/.cvsignore b/include/glibtop/.cvsignore index 282522db..1b076f70 100644 --- a/include/glibtop/.cvsignore +++ b/include/glibtop/.cvsignore @@ -1,2 +1,3 @@ Makefile Makefile.in +call-vector.h diff --git a/include/glibtop/Makefile.am b/include/glibtop/Makefile.am index 06c6530e..4cb172e0 100644 --- a/include/glibtop/Makefile.am +++ b/include/glibtop/Makefile.am @@ -9,4 +9,15 @@ glibtop_HEADERS = close.h loadavg.h prockernel.h procstate.h \ parameter.h mountlist.h fsusage.h procmap.h signal.h \ inodedb.h sysinfo.h ppp.h procargs.h netload.h \ netinfo.h interfaces.h limits.h array.h compat_10.h \ - errors.h glib-arrays.h + errors.h glib-arrays.h backend.h call-vector.h + +BUILT_SOURCES = call-vector.h + +call-vector.h: call-vector.pl call-vector.h.in $(top_builddir)/config.h $(top_srcdir)/features.def $(top_srcdir)/scripts/c_types.pl + $(PERL) -I $(top_srcdir)/scripts $(srcdir)/call-vector.pl $(top_srcdir)/features.def $(srcdir)/call-vector.h.in > tmp-t + mv tmp-t call-vector.h + +EXTRA_DIST = call-vector.pl call-vector.h.in + +CLEANFILES = $(BUILT_SOURCES) + diff --git a/include/glibtop/backend.h b/include/glibtop/backend.h new file mode 100644 index 00000000..e0c93c49 --- /dev/null +++ b/include/glibtop/backend.h @@ -0,0 +1,82 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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. + + You should have received a copy of the GNU General Public License + along with LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef __GLIBTOP_BACKEND_H__ +#define __GLIBTOP_BACKEND_H__ + +#include +#include + +#include + +#include + +BEGIN_LIBGTOP_DECLS + +typedef struct _glibtop_backend_info glibtop_backend_info; +typedef struct _glibtop_backend_private glibtop_backend_private; + +typedef struct _glibtop_backend glibtop_backend; + +typedef int (*glibtop_backend_open_func_t) (glibtop *, glibtop_backend *, + u_int64_t, const char **); +typedef int (*glibtop_backend_close_func_t) (glibtop *, glibtop_backend *); + +struct _glibtop_backend_info +{ + const char *name; + glibtop_backend_open_func_t open; + glibtop_backend_close_func_t close; + glibtop_call_vector *call_vector; +}; + +struct _glibtop_backend +{ + glibtop_backend_info *info; + glibtop_backend_private *_priv; +}; + +long +glibtop_register_backend (glibtop_backend_info *info); + +void +glibtop_unregister_backend (long id); + +glibtop_backend_info * +glibtop_backend_by_id (long id); + +glibtop_backend_info * +glibtop_backend_by_name (const char *backend_name); + +void +glibtop_init_backends (void); + +int +glibtop_open_backend_l (glibtop *server, const char *backend_name, + u_int64_t features, const char **backend_args); + +END_LIBGTOP_DECLS + +#endif diff --git a/lib/write.c b/include/glibtop/call-vector.h.in similarity index 65% rename from lib/write.c rename to include/glibtop/call-vector.h.in index 3316555b..4ce8a808 100644 --- a/lib/write.c +++ b/include/glibtop/call-vector.h.in @@ -2,6 +2,8 @@ /* $Id$ */ +@@AUTOGEN_COMMENT@@ + /* Copyright (C) 1998-99 Martin Baulig This file is part of LibGTop 1.0. @@ -23,29 +25,21 @@ Boston, MA 02111-1307, USA. */ -#include +#ifndef __GLIBTOP_CALL_VECTOR_H__ +#define __GLIBTOP_CALL_VECTOR_H__ -/* Writes some data to server. */ +#include +#include -void -glibtop_write_l (glibtop *server, size_t size, void *buf) +BEGIN_LIBGTOP_DECLS + +typedef struct _glibtop_call_vector glibtop_call_vector; + +struct _glibtop_call_vector { - int ret; + @@GLIBTOP_CALL_VECTOR@@ +}; - glibtop_init_r (&server, 0, 0); +END_LIBGTOP_DECLS - if (size == 0) return; - -#ifdef DEBUG - fprintf (stderr, "LIBRARY: really writing %d bytes.\n", size); #endif - - if (server->_priv->socket) { - ret = send (server->_priv->socket, buf, size, 0); - } else { - ret = write (server->_priv->output [1], buf, size); - } - - if (ret < 0) - glibtop_error_io_r (server, _("write %d bytes"), size); -} diff --git a/include/glibtop/call-vector.pl b/include/glibtop/call-vector.pl new file mode 100644 index 00000000..79a95724 --- /dev/null +++ b/include/glibtop/call-vector.pl @@ -0,0 +1,116 @@ +#!/usr/bin/perl + +require 'c_types.pl'; + +die "Usage: $0 features.def call-vector.h.in" unless $#ARGV == 1; + +$[ = 1; # set array base to 1 +$, = ' '; # set output field separator +$\ = "\n"; # set output record separator + +sub toupper { + local($_) = @_; + tr/a-z/A-Z/; + return $_; +} + +sub tolower { + local($_) = @_; + tr/A-Z/a-z/; + return $_; +} + +$func_decl_code = ''; + +open FEATURESDEF, $ARGV[1] or + die "open ($ARGV[1]): $!"; + +while () { + chop; # strip record separator + + if (/^[^\#]/) { + &parse_features_def ($_); + } +} + +close FEATURESDEF; + +sub parse_features_def { + local($line) = @_; + @line_fields = split(/\|/, $line, 9999); + $retval = $line_fields[1]; + $element_def = $line_fields[3]; + $feature = $line_fields[2]; + $param_def = $line_fields[4]; + + $orig = $feature; + $feature =~ s/^@//; + $space = $feature; + $space =~ s/./ /g; + + if ($retval eq 'retval') { + $retval_param = '&retval'; + $retval = 'int'; + } + elsif ($retval !~ /^void$/) { + $retval_param = 'NULL'; + } + else { + $retval_param = 'NULL'; + } + + if ($retval =~ /^(array|pointer)\((.*)\)$/) { + $retval = ($2 eq 'string') ? 'char **' : "$2 *"; + } + + $param_decl = ''; + $nr_params = (@params = split(/:/, $param_def, 9999)); + for ($param = 1; $param <= $nr_params; $param++) { + $list = $params[$param]; + $type = $params[$param]; + $type =~ s/\(.*//; + $list =~ s/^.*\(//; + $list =~ s/\)$//; + $count = (@fields = split(/,/, $list, 9999)); + for ($field = 1; $field <= $count; $field++) { + my $c_type = $typeinfo->{$type}->[1]; + + $param_decl = $param_decl . ', '; + $param_decl = $param_decl . $c_type; + } + } + + if ($line_fields[3] eq '') { + $func_decl_code .= sprintf + (qq[\t%s (*%s) (glibtop *%s);\n], $retval, $feature, $param_decl); + } elsif ($line_fields[3] eq 'array') { + $func_decl_code .= sprintf + (qq[\t%s (*%s) (glibtop *, glibtop_array *%s);\n], $retval, $feature, $param_decl); + } elsif ($line_fields[3] =~ /^array/) { + $func_decl_code .= sprintf + (qq[\t%s (*%s) (glibtop *, glibtop_array *, %s *%s);\n], $retval, $feature, 'glibtop_'.$feature, $param_decl); + } else { + $func_decl_code .= sprintf + (qq[\t%s (*%s) (glibtop *, %s *%s);\n], $retval, $feature, 'glibtop_'.$feature, $param_decl); + } +} + +chop $func_decl_code; + +$auto_gen_comment = sprintf + (qq[/*\n * This file is automatically generated.\n * Please modify `call-vector.pl' and `call-vector.h.in'.\n */]); + +open CALLVECTOR, $ARGV[2] or + die "open ($ARGV[2]): $!"; + +while () { + chop; + + s/^\s*\@\@GLIBTOP_CALL_VECTOR\@\@\s*$/$func_decl_code/; + + s/^\s*\@\@AUTOGEN_COMMENT\@\@\s*$/$auto_gen_comment/; +} continue { + print $_; +} + +close CALLVECTOR; diff --git a/include/glibtop/errors.h b/include/glibtop/errors.h index 7a4556d5..cb54b5a1 100644 --- a/include/glibtop/errors.h +++ b/include/glibtop/errors.h @@ -44,7 +44,10 @@ BEGIN_LIBGTOP_DECLS #define GLIBTOP_ERROR_NO_KERNEL_SUPPORT 8 #define GLIBTOP_ERROR_INCOMPATIBLE_KERNEL 9 -#define GLIBTOP_MAX_ERROR 10 +#define GLIBTOP_ERROR_NO_SUCH_BACKEND 10 +#define GLIBTOP_ERROR_NOT_IMPLEMENTED 11 + +#define GLIBTOP_MAX_ERROR 12 char * glibtop_get_error_string_l (glibtop *server, unsigned error_number); diff --git a/include/glibtop/limits.h b/include/glibtop/limits.h index 01f1e176..45ab0206 100644 --- a/include/glibtop/limits.h +++ b/include/glibtop/limits.h @@ -45,6 +45,9 @@ BEGIN_LIBGTOP_DECLS /* This is ((u_int64_t)-1) */ #define GLIBTOP_UNLIMITED (~(u_int64_t)0) +/* Maximum length of a backend name. */ +#define GLIBTOP_BACKEND_NAME_LEN 40 + END_LIBGTOP_DECLS #endif diff --git a/include/glibtop/open.h b/include/glibtop/open.h index a0fc42bd..5fdc42a5 100644 --- a/include/glibtop/open.h +++ b/include/glibtop/open.h @@ -54,7 +54,7 @@ BEGIN_LIBGTOP_DECLS #define GLIBTOP_ERROR_METHOD_DEFAULT GLIBTOP_ERROR_METHOD_WARN_ONCE void -glibtop_open_l (glibtop *server, const char *program_name, +glibtop_open_l (glibtop *server, const char *backend_name, const unsigned long features, const unsigned flags); void diff --git a/lib/Makefile.am b/lib/Makefile.am index 3ae0ddea..63e563b9 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -4,9 +4,9 @@ INCLUDES = @INCLUDES@ 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 \ - sysdeps.c errors.c glib-arrays.c +libgtop_la_SOURCES = init.c open.c close.c lib.c parameter.c \ + sysdeps.c errors.c glib-arrays.c \ + backend.c init-backends.c open-backend.c libgtop_la_LDFLAGS = $(LT_VERSION_INFO) diff --git a/lib/backend.c b/lib/backend.c new file mode 100644 index 00000000..632db119 --- /dev/null +++ b/lib/backend.c @@ -0,0 +1,93 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ + +/* $Id$ */ + +/* Copyright (C) 1998-99 Martin Baulig + This file is part of LibGTop 1.0. + + Contributed by Martin Baulig , April 1998. + + LibGTop 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. + + LibGTop 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. + + You should have received a copy of the GNU General Public License + along with LibGTop; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include + +#include + +static GHashTable *_glibtop_backend_list = NULL; +static long _glibtop_backend_nr = 0; + +long +glibtop_register_backend (glibtop_backend_info *info) +{ + long id; + + if (!_glibtop_backend_list) + _glibtop_backend_list = g_hash_table_new (NULL, NULL); + + id = ++_glibtop_backend_nr; + + g_hash_table_insert (_glibtop_backend_list, + GINT_TO_POINTER (id), + info); + + return id; +} + +void +glibtop_unregister_backend (long id) +{ + g_hash_table_remove (_glibtop_backend_list, + GINT_TO_POINTER (id)); +} + +glibtop_backend_info * +glibtop_backend_by_id (long id) +{ + return g_hash_table_lookup (_glibtop_backend_list, + GINT_TO_POINTER (id)); +} + +typedef struct { + const char *backend_name; + glibtop_backend_info *info; +} _find_by_name_param_t; + +static void +find_by_name (gpointer key, gpointer value, gpointer user_data) +{ + _find_by_name_param_t *param = (_find_by_name_param_t *) user_data; + glibtop_backend_info *info = (glibtop_backend_info *) value; + + if (!info || !info->name || param->info) + return; + + if (!strcmp (info->name, param->backend_name)) + param->info = info; +} + +glibtop_backend_info * +glibtop_backend_by_name (const char *backend_name) +{ + _find_by_name_param_t param = { backend_name, NULL }; + + g_hash_table_foreach (_glibtop_backend_list, + find_by_name, ¶m); + + return param.info; +} diff --git a/lib/close.c b/lib/close.c index 618e27fd..e8b22153 100644 --- a/lib/close.c +++ b/lib/close.c @@ -33,20 +33,4 @@ void glibtop_close_r (glibtop *server) { - switch (server->method) { - case GLIBTOP_METHOD_UNIX: - case GLIBTOP_METHOD_INET: - glibtop_call_l (server, GLIBTOP_CMND_QUIT, - 0, NULL, 0, NULL, NULL); - - if (close (server->_priv->socket)) - glibtop_warn_io ("close"); - - break; - case GLIBTOP_METHOD_PIPE: - kill (server->_priv->pid, SIGKILL); - close (server->_priv->input [0]); - close (server->_priv->output [1]); - break; - } } diff --git a/lib/command.c b/lib/command.c deleted file mode 100644 index 5bbdc75f..00000000 --- a/lib/command.c +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ - -/* $Id$ */ - -/* Copyright (C) 1998-99 Martin Baulig - This file is part of LibGTop 1.0. - - Contributed by Martin Baulig , April 1998. - - LibGTop 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. - - LibGTop 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. - - You should have received a copy of the GNU General Public License - along with LibGTop; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. -*/ - -#include -#include -#include - -#include -#include - -void * -glibtop_call_l (glibtop *server, unsigned command, size_t send_size, - const void *send_buf, size_t recv_size, void *recv_buf, - int *retval_ptr) -{ - glibtop_command cmnd; - glibtop_response response; - int retval; - - glibtop_init_r (&server, 0, 0); - - memset (&cmnd, 0, sizeof (glibtop_command)); - - 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. */ - - if (send_size <= _GLIBTOP_PARAM_SIZE) { - memcpy (cmnd.parameter, send_buf, send_size); - cmnd.size = send_size; - } else { - cmnd.data_size = send_size; - } - - glibtop_write_l (server, sizeof (glibtop_command), &cmnd); - - glibtop_read_l (server, sizeof (glibtop_response), &response); - -#ifdef DEBUG - fprintf (stderr, "RESPONSE: %lu - %d\n", - response.offset, response.data_size); -#endif - - glibtop_read_l (server, sizeof (int), &retval); - if (retval_ptr) - *retval_ptr = retval; - - if (recv_buf) - memcpy (recv_buf, ((char *) &response) + response.offset, - recv_size); - - if (response.data_size) { - void *ptr = glibtop_malloc_r (server, response.data_size); - - glibtop_read_l (server, response.data_size, ptr); - - return ptr; - } - - return NULL; -} diff --git a/lib/read.c b/lib/init-backends.c similarity index 50% rename from lib/read.c rename to lib/init-backends.c index 722f2766..7153e116 100644 --- a/lib/read.c +++ b/lib/init-backends.c @@ -23,56 +23,24 @@ Boston, MA 02111-1307, USA. */ -#include +#include +#include +#include -/* Reads some data from server. */ +#include -static void -do_read (int s, void *ptr, size_t total_size) -{ - int nread; - size_t already_read = 0, remaining = total_size; - char *tmp_ptr; - - while (already_read < total_size) { - nread = recv (s, ptr, remaining, 0); - - if (nread == 0) { - close (s); - continue; - } - - if (nread <= 0) { - glibtop_error_io ("recv"); - return; - } - - already_read += nread; - remaining -= nread; - /* (char *) ptr += nread; */ - tmp_ptr = ptr; - tmp_ptr += nread; - ptr = tmp_ptr; - } -} +extern glibtop_backend_info glibtop_backend_server; +extern glibtop_backend_info glibtop_backend_sysdeps; void -glibtop_read_l (glibtop *server, size_t size, void *buf) +glibtop_init_backends (void) { - int ret = 0; + static int backends_initialized = 0; - glibtop_init_r (&server, 0, 0); + if (backends_initialized) + return; + backends_initialized = 1; -#ifdef DEBUG - fprintf (stderr, "LIBRARY: really reading %d bytes.\n", size); -#endif - - if (server->_priv->socket) { - do_read (server->_priv->socket, buf, size); - } else { - ret = read (server->_priv->input [0], buf, size); - } - - if (ret < 0) - glibtop_error_io_r (server, _("read %d bytes"), size); + glibtop_register_backend (&glibtop_backend_server); + glibtop_register_backend (&glibtop_backend_sysdeps); } diff --git a/lib/lib.pl b/lib/lib.pl index 54d69320..0e2d14ab 100755 --- a/lib/lib.pl +++ b/lib/lib.pl @@ -32,6 +32,7 @@ print '#include '; print '#include '; print ''; print '#include '; +print '#include '; print ''; print '/* Some required fields are missing. */'; @@ -116,20 +117,6 @@ sub output { $retval = ($2 eq 'string') ? 'char **' : "$2 *"; } - $check_server_code = "\n"; - $check_server_code .= - "\t/* If neccessary, we ask the server for the requested\n" . - "\t * feature. If not, we call the sysdeps function. */\n\n" . - "\tif ((server->flags & _GLIBTOP_INIT_STATE_SERVER) &&\n" . - "\t (server->features & (1 << GLIBTOP_SYSDEPS_" . - &toupper($feature) . ")))\n" . - "\t\tgoto call_server;\n\telse\n" . - "\t\tgoto call_sysdeps;\n\n"; - - $need_temp_storage = $always_use_temp_storage; - $size_code = "\t_LIBGTOP_SEND_len = 0;\n"; - $marshal_code = "\t_LIBGTOP_SEND_offset = 0;\n"; - $marshal_code .= "\tmemset (_LIBGTOP_SEND_buf, 0, _LIBGTOP_SEND_len);\n"; $first_param_name = ''; $call_param = ''; @@ -162,66 +149,54 @@ sub output { } $param_decl = $param_decl . $c_type . ' ' . $fields[$field]; $call_param = $call_param . ', ' . $fields[$field]; - - $size_code .= "\t_LIBGTOP_SEND_len += "; - if (defined $sizeof_funcs->{$type}) { - $size_code .= $sizeof_funcs->{$type}->($fields[$field]); - } else { - $size_code .= sprintf ("sizeof (%s)", $c_type); - } - $size_code .= ";\n"; - - $marshal_code .= "\t_LIBGTOP_SEND_ptr = ". - "(char *) _LIBGTOP_SEND_buf + _LIBGTOP_SEND_offset;\n"; - - if (defined $marshal_funcs->{$type}) { - $marshal_code .= $marshal_funcs->{$type}->($c_type, $fields[$field], "\t"); - } else { - $marshal_code .= sprintf ("\tmemcpy (_LIBGTOP_SEND_ptr, %s, %s);\n", - '&'.$fields[$field], "sizeof ($c_type)"); - } - - $marshal_code .= "\t_LIBGTOP_SEND_offset += "; - if (defined $sizeof_funcs->{$type}) { - $marshal_code .= $sizeof_funcs->{$type}->($fields[$field]); - } else { - $marshal_code .= sprintf ("sizeof (%s)", $c_type); - } - $marshal_code .= ";\n"; } } - $local_var_code = ""; - $local_var_code .= "\tunsigned _LIBGTOP_SEND_offset, _LIBGTOP_SEND_len;\n"; - if ($need_temp_len) { - $local_var_code .= "\tunsigned _LIBGTOP_SEND_temp_len;\n"; - } - $local_var_code .= "\tvoid *_LIBGTOP_SEND_buf;\n"; - $local_var_code .= "\tchar *_LIBGTOP_SEND_ptr;\n"; + $local_var_code = sprintf ("\tGSList *list;\n\tint done = 0;\n"); if ($retval !~ /^void$/) { $local_var_code .= sprintf ("\t%s retval = (%s) 0;\n", $retval, $retval); } - $sysdeps_code = "call_sysdeps:\n"; - if ($orig !~ /^@/) { - $sysdeps_code .= sprintf ("#if (!GLIBTOP_SUID_%s)\n", &toupper($feature)); - } + $sysdeps_code = "\t". + 'fprintf (stderr, "TEST: %p - %p\n", server, server->_priv);'."\n\n"; + + $sysdeps_code .= sprintf + ("\tfor (list = server->_priv->backend_list;\n\t list; list = list->next) {\n\t\tglibtop_backend *backend = list->data;\n\n\t\tif (!backend->info || !backend->info->call_vector)\n\t\t\tcontinue;\n\n\t\tif (backend->info->call_vector->%s) {\n", $feature); if ($line_fields[3] eq '') { - $sysdeps_code .= sprintf ("\t%sglibtop_get_%s_s (server%s);\n", - $prefix, $feature, $call_param); + $sysdeps_code .= sprintf + ("\t\t\tretval = backend->info->call_vector->%s (server%s);\n", + $feature, $call_param); } elsif ($line_fields[3] eq 'array') { - $sysdeps_code .= sprintf ("\t%sglibtop_get_%s_s (server, array%s);\n", - $prefix, $feature, $call_param); + $sysdeps_code .= sprintf + ("\t\t\tretval = backend->info->call_vector->%s (server, array%s);\n", + $feature, $call_param); } elsif ($line_fields[3] =~ /^array/) { - $sysdeps_code .= sprintf ("\t%sglibtop_get_%s_s (server, array, buf%s);\n", - $prefix, $feature, $call_param); + $sysdeps_code .= sprintf + ("\t\t\tretval = backend->info->call_vector->%s (server, array, buf%s);\n", + $feature, $call_param); } else { - $sysdeps_code .= sprintf ("\t%sglibtop_get_%s_s (server, buf%s);\n", - $prefix, $feature, $call_param); + $sysdeps_code .= sprintf + ("\t\t\tretval = backend->info->call_vector->%s (server, buf%s);\n", + $feature, $call_param); } + $sysdeps_code .= sprintf + ("\t\t\tdone = 1;\n\t\t\tbreak;\n\t\t}\n\t}\n"); + + $sysdeps_code .= sprintf + ("\n\tif (!done) {\n\t\tserver->glibtop_errno = GLIBTOP_ERROR_NOT_IMPLEMENTED;\n"); + if ($line_fields[1] eq 'retval') { + $sysdeps_code .= sprintf + ("\t\treturn -GLIBTOP_ERROR_NOT_IMPLEMENTED;\n"); + } else { + $sysdeps_code .= sprintf + ("\t\tgoto do_return;\n"); + } + $sysdeps_code .= sprintf + ("\t}\n\n"); + if ($line_fields[1] eq 'retval') { $sysdeps_code .= "\tif (retval < 0) {\n"; $sysdeps_code .= "\t\tserver->glibtop_errno = -retval;\n"; @@ -231,52 +206,10 @@ sub output { $sysdeps_code .= "\tgoto check_missing;\n"; - if ($orig !~ /^@/) { - $sysdeps_code .= "#else\n\terrno = ENOSYS;\n"; - $sysdeps_code .= sprintf ("\tglibtop_error_io_r (server, \"%s\");\n", - "glibtop_get_" . $feature); - $sysdeps_code .= "\tgoto do_return;\n"; - $sysdeps_code .= "#endif\n"; - } + $init_code = sprintf ("\tglibtop_init_r (&server, (1 << %s), 0);\n\n", + "GLIBTOP_SYSDEPS_".&toupper($feature)); - $total_code = sprintf ("%s%s%s\n", $init_code, $check_server_code, - $sysdeps_code); - - $send_buf_code = "\t_LIBGTOP_SEND_buf = "; - if ($need_temp_storage) { - $send_buf_code .= "glibtop_malloc_r (server, _LIBGTOP_SEND_len+1)"; - } else { - $send_buf_code .= '(void *) &'.$first_param_name; - } - $send_buf_code .= ";\n"; - - $call_code = ''; - $call_code .= sprintf ("\t%sglibtop_call_l (server, GLIBTOP_CMND_%s,\n", - $call_prefix, &toupper($feature)); - $call_code .= sprintf ("\t\t\t%s%s, %s,\n", $call_prefix_space, - "_LIBGTOP_SEND_len", "_LIBGTOP_SEND_ptr"); - if ($line_fields[3] eq '') { - $call_code .= sprintf ("\t\t\t%s0, NULL,\n", $call_prefix_space); - } elsif ($line_fields[3] eq 'array') { - $call_code .= sprintf ("\t\t\t%ssizeof (glibtop_array), array,\n", - $call_prefix_space); - } else { - $call_code .= sprintf ("\t\t\t%ssizeof (glibtop_%s), buf,\n", - $call_prefix_space, $feature); - } - $call_code .= sprintf ("\t\t\t%s%s);\n", $call_prefix_space, $retval_param); - - if ($need_temp_storage) { - $send_buf_free_code = "\tglibtop_free_r (server, _LIBGTOP_SEND_buf);\n"; - } else { - $send_buf_free_code = ""; - } - - $total_code .= sprintf ("call_server:\n%s\n%s\n%s\n%s\n%s\n", - $size_code, $send_buf_code, $marshal_code, - $call_code, $send_buf_free_code); - - $total_code .= "\tgoto check_missing;\n\n"; + $total_code = sprintf ("%s%s\n", $init_code, $sysdeps_code); $check_code = "check_missing:\n"; $check_code .= "\t/* Make sure that all required fields are present. */\n"; @@ -312,9 +245,6 @@ sub output { $feature, 'glibtop_'.$feature, $param_decl); } - $init_code = sprintf ("\tglibtop_init_r (&server, (1 << %s), 0);\n", - "GLIBTOP_SYSDEPS_".&toupper($feature)); - $total_code = sprintf ("%s{\n%s\n%s\n%s}\n", $func_decl, $local_var_code, $total_code); diff --git a/lib/read_data.c b/lib/open-backend.c similarity index 50% rename from lib/read_data.c rename to lib/open-backend.c index cc9d6f99..d4e924f9 100644 --- a/lib/read_data.c +++ b/lib/open-backend.c @@ -23,51 +23,42 @@ Boston, MA 02111-1307, USA. */ +#include +#include #include -#include -/* Reads some data from server. */ +#include -void * -glibtop_read_data_l (glibtop *server) +int +glibtop_open_backend_l (glibtop *server, const char *backend_name, + u_int64_t features, const char **backend_args) { - size_t size; - void *ptr; - int ret; + glibtop_backend_info *info; + glibtop_backend *backend; - glibtop_init_r (&server, 0, 0); + info = glibtop_backend_by_name (backend_name); + if (!info) return -GLIBTOP_ERROR_NO_SUCH_BACKEND; -#ifdef DEBUG - fprintf (stderr, "LIBRARY: reading %d data bytes.\n", sizeof (size_t)); -#endif + backend = glibtop_calloc_r (server, 1, sizeof (glibtop_backend)); + backend->info = info; - if (server->_priv->socket) { - ret = recv (server->_priv->socket, (void *)&size, - sizeof (size_t), 0); - } else { - ret = read (server->_priv->input [0], (void *)&size, - sizeof (size_t)); + if (info->open) { + int retval; + + retval = info->open (server, backend, features, backend_args); + if (retval) { + glibtop_free_r (server, backend->_priv); + glibtop_free_r (server, backend); + return retval; + } } - if (ret < 0) - glibtop_error_io_r (server, _("read data size")); + if (!server->_priv) + server->_priv = glibtop_calloc_r + (server, 1, sizeof (glibtop_server_private)); -#ifdef DEBUG - fprintf (stderr, "LIBRARY: really reading %d data bytes (ret = %d).\n", size, ret); -#endif + server->_priv->backend_list = g_slist_append + (server->_priv->backend_list, backend); - if (!size) return NULL; - - ptr = glibtop_malloc_r (server, size); - - if (server->_priv->socket) { - ret = recv (server->_priv->socket, ptr, size, 0); - } else { - ret = read (server->_priv->input [0], ptr, size); - } - - if (ret < 0) - glibtop_error_io_r (server, _("read data %d bytes")); - - return ptr; + return 0; } diff --git a/lib/open.c b/lib/open.c index 0b41063c..fc40c7d7 100644 --- a/lib/open.c +++ b/lib/open.c @@ -32,160 +32,8 @@ #include -/* Opens pipe to gtop server. Returns 0 on success and -1 on error. */ - void glibtop_open_l (glibtop *server, const char *program_name, const unsigned long features, const unsigned flags) { - int connect_type; - - if (!server->_priv) - server->_priv = glibtop_calloc_r - (server, 1, sizeof (glibtop_server_private)); - - server->name = program_name; - - /* It is important to set _GLIBTOP_INIT_STATE_OPEN here when we - * do recursive calls to glibtop_init_r (). */ - - server->flags |= _GLIBTOP_INIT_STATE_OPEN; - - server->error_method = GLIBTOP_ERROR_METHOD_DEFAULT; - -#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_DIRECT: - server->features = 0; - break; - case GLIBTOP_METHOD_INET: -#ifdef DEBUG - fprintf (stderr, "Connecting to '%s' port %ld.\n", - server->server_host, server->server_port); -#endif - - connect_type = glibtop_make_connection - (server->server_host, server->server_port, - &server->_priv->socket); - -#ifdef DEBUG - fprintf (stderr, "Connect Type is %d.\n", connect_type); -#endif - - server->flags |= _GLIBTOP_INIT_STATE_SERVER; - - server->features = -1; - break; - case GLIBTOP_METHOD_UNIX: -#ifdef DEBUG - fprintf (stderr, "Connecting to Unix Domain Socket.\n"); -#endif - - connect_type = glibtop_make_connection - ("unix", 0, &server->_priv->socket); - -#ifdef DEBUG - fprintf (stderr, "Connect Type is %d.\n", connect_type); -#endif - - server->flags |= _GLIBTOP_INIT_STATE_SERVER; - - server->features = -1; - break; - case GLIBTOP_METHOD_PIPE: -#ifdef DEBUG - fprintf (stderr, "Opening pipe to server (%s).\n", - LIBGTOP_SERVER); -#endif - - if (pipe (server->_priv->input) || - pipe (server->_priv->output)) - glibtop_error_io_r (server, "cannot make a pipe"); - - server->_priv->pid = fork (); - - if (server->_priv->pid < 0) { - glibtop_error_io_r (server, "fork failed"); - } else if (server->_priv->pid == 0) { - close (0); close (1); - close (server->_priv->input [0]); - close (server->_priv->output [1]); - dup2 (server->_priv->input [1], 1); - dup2 (server->_priv->output [0], 0); - execl (LIBGTOP_SERVER, "libgtop-server", NULL); - glibtop_error_io_r (server, "execl (%s)", - LIBGTOP_SERVER); - _exit (2); - } - - close (server->_priv->input [1]); - close (server->_priv->output [0]); - - server->flags |= _GLIBTOP_INIT_STATE_SERVER; - - server->features = -1; - break; - } - - /* If the server has been started, ask it for its features. */ - - if (server->flags & _GLIBTOP_INIT_STATE_SERVER) { - char version [BUFSIZ], buffer [BUFSIZ]; - glibtop_sysdeps sysdeps; - size_t size, nbytes; - - /* First check whether the server version is correct. */ - - sprintf (version, LIBGTOP_VERSION_STRING, - LIBGTOP_VERSION, LIBGTOP_SERVER_VERSION, - sizeof (glibtop_command), - sizeof (glibtop_response), - sizeof (glibtop_union), - sizeof (glibtop_sysdeps)); - - size = strlen (version) + 1; - - glibtop_read_l (server, sizeof (nbytes), &nbytes); - - if (nbytes != size) - glibtop_error_r (server, - "Requested %u bytes but got %u.", - size, nbytes); - - glibtop_read_l (server, nbytes, buffer); - - if (memcmp (version, buffer, size)) - glibtop_error_r (server, "server version is not %s", - LIBGTOP_VERSION); - - /* Now ask it for its features. */ - - glibtop_call_l (server, GLIBTOP_CMND_SYSDEPS, 0, NULL, - sizeof (glibtop_sysdeps), &sysdeps, - NULL); - - server->features = sysdeps.features; - - memcpy (&server->sysdeps, &sysdeps, sizeof (glibtop_sysdeps)); - -#ifdef DEBUG - fprintf (stderr, "Server features are %lu.\n", - server->features); -#endif - } - - /* In any case, we call the open functions of our own sysdeps - * directory. */ - -#ifdef DEBUG - fprintf (stderr, "Calling sysdeps open function.\n"); -#endif - - glibtop_init_s (&server, features, flags); } diff --git a/po/POTFILES.in b/po/POTFILES.in index 3f016531..ab6f6bd7 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -23,14 +23,10 @@ support/error.c support/error.h support/getopt.c lib/close.c -lib/command.c lib/init.c lib/open.c lib/parameter.c -lib/read.c -lib/read_data.c lib/sysdeps.c -lib/write.c lib/errors.c include/glibtop/close.h include/glibtop/command.h diff --git a/src/daemon/server.c b/src/daemon/server.c index 825e260b..32bc8eee 100644 --- a/src/daemon/server.c +++ b/src/daemon/server.c @@ -66,6 +66,7 @@ main(int argc, char *argv[]) { struct utsname uts; int uid, euid, gid, egid; + glibtop *server; /* !!! WE ARE ROOT HERE - CHANGE WITH CAUTION !!! */ @@ -83,8 +84,14 @@ main(int argc, char *argv[]) LIBGTOP_COMPILE_MACHINE); _exit (1); } + + server = glibtop_global_server; - glibtop_init_p (glibtop_global_server, 0, 0); + if (!server->_priv) + server->_priv = glibtop_calloc_r + (server, 1, sizeof (glibtop_server_private)); + + glibtop_init_p (server, 0, 0); if (setreuid (euid, uid)) _exit (1);