Blame lib/open.c

Packit d37888
/* Copyright (C) 1998-99 Martin Baulig
Packit d37888
   This file is part of LibGTop 1.0.
Packit d37888
Packit d37888
   Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998.
Packit d37888
Packit d37888
   LibGTop is free software; you can redistribute it and/or modify it
Packit d37888
   under the terms of the GNU General Public License as published by
Packit d37888
   the Free Software Foundation; either version 2 of the License,
Packit d37888
   or (at your option) any later version.
Packit d37888
Packit d37888
   LibGTop is distributed in the hope that it will be useful, but WITHOUT
Packit d37888
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Packit d37888
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit d37888
   for more details.
Packit d37888
Packit d37888
   You should have received a copy of the GNU General Public License
Packit d37888
   along with LibGTop; see the file COPYING. If not, write to the
Packit d37888
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Packit d37888
   Boston, MA 02110-1301, USA.
Packit d37888
*/
Packit d37888
Packit d37888
#include <config.h>
Packit d37888
#include <glibtop.h>
Packit d37888
#include <glibtop/open.h>
Packit d37888
#include <glibtop/read.h>
Packit d37888
#include <glibtop/error.h>
Packit d37888
#include <glibtop/version.h>
Packit d37888
#include <glibtop/sysdeps.h>
Packit d37888
#include <glibtop/command.h>
Packit d37888
Packit d37888
#include <glibtop/gnuserv.h>
Packit d37888
Packit d37888
/* Opens pipe to gtop server. Returns 0 on success and -1 on error. */
Packit d37888
Packit d37888
void
Packit d37888
glibtop_open_l (glibtop *server, const char *program_name,
Packit d37888
		const unsigned long features, const unsigned flags)
Packit d37888
{
Packit d37888
	int connect_type;
Packit d37888
Packit d37888
	server->name = program_name;
Packit d37888
Packit d37888
	/* It is important to set _GLIBTOP_INIT_STATE_OPEN here when we
Packit d37888
	 * do recursive calls to glibtop_init_r (). */
Packit d37888
Packit d37888
	server->flags |= _GLIBTOP_INIT_STATE_OPEN;
Packit d37888
Packit d37888
	server->error_method = GLIBTOP_ERROR_METHOD_DEFAULT;
Packit d37888
Packit d37888
	glibtop_debug ("SIZEOF: %zu - %zu - %zu - %zu - %zu - %zu",
Packit d37888
		 sizeof (glibtop_command), sizeof (glibtop_response),
Packit d37888
		 sizeof (glibtop_mountentry), sizeof (glibtop_union),
Packit d37888
		 sizeof (glibtop_sysdeps), sizeof (glibtop_response_union));
Packit d37888
Packit d37888
	switch (server->method) {
Packit d37888
	case GLIBTOP_METHOD_DIRECT:
Packit d37888
		server->features = 0;
Packit d37888
		break;
Packit d37888
	case GLIBTOP_METHOD_INET:
Packit d37888
		glibtop_debug ("Connecting to '%s' port %ld.",
Packit d37888
			 server->server_host, server->server_port);
Packit d37888
Packit d37888
		connect_type = glibtop_make_connection
Packit d37888
			(server->server_host, server->server_port,
Packit d37888
			 &server->socket);
Packit d37888
Packit d37888
		glibtop_debug ("Connect Type is %d.", connect_type);
Packit d37888
Packit d37888
		server->flags |= _GLIBTOP_INIT_STATE_SERVER;
Packit d37888
Packit d37888
		server->features = -1;
Packit d37888
		break;
Packit d37888
	case GLIBTOP_METHOD_UNIX:
Packit d37888
		glibtop_debug ("Connecting to Unix Domain Socket.");
Packit d37888
Packit d37888
		connect_type = glibtop_make_connection
Packit d37888
			("unix", 0, &server->socket);
Packit d37888
Packit d37888
		glibtop_debug ("Connect Type is %d.", connect_type);
Packit d37888
Packit d37888
		server->flags |= _GLIBTOP_INIT_STATE_SERVER;
Packit d37888
Packit d37888
		server->features = -1;
Packit d37888
		break;
Packit d37888
	case GLIBTOP_METHOD_PIPE:
Packit d37888
		glibtop_debug ("Opening pipe to server (%s).",
Packit d37888
			 server->server_command);
Packit d37888
Packit d37888
		if (pipe (server->input) || pipe (server->output))
Packit d37888
			glibtop_error_io_r (server, "cannot make a pipe");
Packit d37888
Packit d37888
		server->pid  = fork ();
Packit d37888
Packit d37888
		if (server->pid < 0) {
Packit d37888
			glibtop_error_io_r (server, "fork failed");
Packit d37888
		} else if (server->pid == 0) {
Packit d37888
			close (0); close (1);
Packit d37888
			close (server->input [0]); close (server->output [1]);
Packit d37888
			dup2 (server->input [1], 1);
Packit d37888
			dup2 (server->output [0], 0);
Packit d37888
			execl (server->server_command, "libgtop-server", NULL);
Packit d37888
			glibtop_error_io_r (server, "execl (%s)",
Packit d37888
					    server->server_command);
Packit d37888
			_exit (2);
Packit d37888
		}
Packit d37888
Packit d37888
		close (server->input [1]);
Packit d37888
		close (server->output [0]);
Packit d37888
Packit d37888
		server->flags |= _GLIBTOP_INIT_STATE_SERVER;
Packit d37888
Packit d37888
		server->features = -1;
Packit d37888
		break;
Packit d37888
	}
Packit d37888
Packit d37888
	/* If the server has been started, ask it for its features. */
Packit d37888
Packit d37888
	if (server->flags & _GLIBTOP_INIT_STATE_SERVER) {
Packit d37888
		char version [BUFSIZ], buffer [BUFSIZ];
Packit d37888
		glibtop_sysdeps sysdeps;
Packit d37888
		size_t size, nbytes;
Packit d37888
Packit d37888
		/* First check whether the server version is correct. */
Packit d37888
Packit d37888
		sprintf (version, LIBGTOP_VERSION_STRING,
Packit d37888
			 LIBGTOP_VERSION, LIBGTOP_SERVER_VERSION,
Packit d37888
			 (guint) sizeof (glibtop_command),
Packit d37888
			 (guint) sizeof (glibtop_response),
Packit d37888
			 (guint) sizeof (glibtop_union),
Packit d37888
			 (guint) sizeof (glibtop_sysdeps));
Packit d37888
Packit d37888
		size = strlen (version) + 1;
Packit d37888
Packit d37888
		glibtop_read_l (server, sizeof (nbytes), &nbytes);
Packit d37888
Packit d37888
		if (nbytes != size)
Packit d37888
			glibtop_error_r (server,
Packit d37888
					 "Requested %u bytes but got %u.",
Packit d37888
					 (unsigned)size, (unsigned)nbytes);
Packit d37888
Packit d37888
		glibtop_read_l (server, nbytes, buffer);
Packit d37888
Packit d37888
		if (memcmp (version, buffer, size))
Packit d37888
			glibtop_error_r (server, "server version is not %s",
Packit d37888
					 LIBGTOP_VERSION);
Packit d37888
Packit d37888
		/* Now ask it for its features. */
Packit d37888
Packit d37888
		glibtop_call_l (server, GLIBTOP_CMND_SYSDEPS, 0, NULL,
Packit d37888
				sizeof (glibtop_sysdeps), &sysdeps);
Packit d37888
Packit d37888
		server->features = sysdeps.features;
Packit d37888
Packit d37888
		memcpy (&server->sysdeps, &sysdeps, sizeof (glibtop_sysdeps));
Packit d37888
Packit d37888
		glibtop_debug ("Server features are %#0lx.",
Packit d37888
			 server->features);
Packit d37888
	}
Packit d37888
Packit d37888
	/* In any case, we call the open functions of our own sysdeps
Packit d37888
	 * directory. */
Packit d37888
Packit d37888
	glibtop_debug ("Calling sysdeps open function.");
Packit d37888
Packit d37888
	glibtop_init_s (&server, features, flags);
Packit d37888
}