syslog_kernel.c
author viric@llimona
Thu, 06 Apr 2006 01:47:35 +0200
changeset 18 84fa30ea0b0d
parent 15 fea6e87812f0
child 19 273d1c138a56
permissions -rw-r--r--
Ara sí - versió 1

#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h> // Per sprintf, fprintf
#include <sys/wait.h> // Per wait
#include <string.h> // Per memset
#include <signal.h> // Pels senyals
#include <assert.h> // Pels assert
#include <stdlib.h> // Per l'abort

#include "rfc3164.h"

const char syslog_in_unix[] = "syslog_in_unix";
const char syslog_in_npipe[] = "syslog_in_npipe";
const char syslog_in_udp[] = "syslog_in_udp";

#define TEST_NPIPE "prova_npipe"
#define TEST_UDP 4000
#define TEST_UNIX "prova_unix"

void child_handler(int parameter)
{
	pid_t pid;
	int status;

	do
	{
		pid = waitpid(-1, &status, WNOHANG);
		/* Debug */
		if (WIFEXITED(status))
		{
			fprintf(stderr, "Child %i died fine:%i\n",
				pid, WEXITSTATUS(status));
		} else 
			fprintf(stderr, "Child %i signaled strange.\n",
				pid);
	} while(pid == 0);
}

int run_program(const char * restrict programname,
		const char * restrict parameter1, int comm_pipe[])
{
	int pid;

	pid = fork();
	assert(pid != -1);
	if (pid == 0)
	{
		close(0);
		close(1);
		dup(comm_pipe[0]);
		dup(comm_pipe[1]);
		execl(programname, programname, parameter1, NULL);
		/* Unreachable */
		fprintf(stderr, "Child exec failed(%s %s): %s\n",
			programname, parameter1, strerror(errno));
		abort();
		return 0;
	}
	else
	{
		fprintf(stderr, "Child forked(%s %s): %i\n",
			programname, parameter1, pid);
		return pid;
	}
}

int init_in_unix(const char * restrict socketname, int input_pipe[])
{
	return run_program(syslog_in_unix, socketname, input_pipe);
}

int init_in_udp(unsigned int port, int input_pipe[])
{
	char buffer[20];
	
	snprintf(buffer, 20, "%u", port);

	return run_program(syslog_in_udp, buffer, input_pipe);
}

int init_in_npipe(const char * restrict pipename, int input_pipe[])
{
	return run_program(syslog_in_npipe, pipename, input_pipe);
}

void kernel_loop()
{
	int input_pipe[2];
	char missatge[MESSAGE_LENGTH+1];
	int status;

	pipe(input_pipe);

	init_in_npipe(TEST_NPIPE, input_pipe);
	init_in_udp(TEST_UDP, input_pipe);
	init_in_unix(TEST_UNIX, input_pipe);

	/* We don't want to write to the programs */
	close(input_pipe[1]);

	while(true)
	{
		status = read(input_pipe[0], missatge, MESSAGE_LENGTH);

		if (status > 0)
		{
			/* Add a ZERO */
			missatge[status] = '\0';
			/* The \n is included in the message */
			printf("Received: %s",missatge);
		}
		else if (status == -1 && errno == EINTR)
			continue;
		else
			break;
	}

	if (status == -1)
	{
		printf("Error reading from the main pipe: %s\n", 
			strerror(errno));
	}


}

void install_signal_handlers()
{
	struct sigaction my_action;
	int result;

	my_action.sa_handler = child_handler;
	my_action.sa_flags = SA_NOCLDSTOP;
	memset(&my_action.sa_mask, 0, sizeof(my_action.sa_mask));

	result = sigaction(SIGCHLD, &my_action, NULL);
	assert(result == 0);
}

int main(int argn, char *argv[])
{
	install_signal_handlers();
	kernel_loop();
}