#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();
}