syslog_in_unix.c
author viric@llimona
Tue, 30 May 2006 12:34:25 +0200
changeset 57 de776a4548da
parent 53 667cd5966695
permissions -rw-r--r--
Added the check for a pid file (syslog.pid by default).
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
     1
#include <unistd.h> // Per les crides a fitxer
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
     2
#include <stdio.h>  // Per l'I/O de stdin/stdout
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
     3
#include <errno.h>  // Pels errors de les crides a fitxer
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
     4
#include <string.h> // Per strerror()
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
     5
#include <stdlib.h> // Per abort()
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
     6
#include <sys/types.h>  // Per crides de fitxer
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
     7
#include <sys/socket.h>  // Per les macros bool,true,false
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
     8
#include <sys/un.h>  // Per les estructures dels unix sockets
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
     9
#include <assert.h> // Per assert()
29
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
    10
#include <stdbool.h>
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
    11
#include <signal.h> // per SIGTERM i similars
38
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    12
#include <sys/select.h> // per select()
9
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    13
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    14
#include "rfc3164.h"
26
7227789ca718 Added a c file for signal programming.
viric@mandarina
parents: 15
diff changeset
    15
#include "syslog.h"
9
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    16
29
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
    17
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
    18
static bool finish = false;
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
    19
9
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    20
void show_help(const char * restrict program)
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    21
{
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    22
	printf("Usage: %s <unix_socket>\n", program);
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    23
}
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    24
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    25
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    26
int listen_unix(const char * restrict socketname)
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    27
{
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    28
	int socket_unix;
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    29
	struct sockaddr_un source_unix;
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    30
	int result;
15
fea6e87812f0 Now everything works - the rfc3164 message parser must be improved.
viric@llimona
parents: 11
diff changeset
    31
	int sockopt;
9
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    32
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    33
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    34
	socket_unix = socket(PF_UNIX, SOCK_DGRAM, 0 );
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    35
	if (socket_unix == -1)
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    36
	{
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    37
		printf("Unix socket creation error: %s\n", strerror(errno));
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    38
		abort();
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    39
	}
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    40
15
fea6e87812f0 Now everything works - the rfc3164 message parser must be improved.
viric@llimona
parents: 11
diff changeset
    41
	/* Allow socket reuse */
fea6e87812f0 Now everything works - the rfc3164 message parser must be improved.
viric@llimona
parents: 11
diff changeset
    42
	sockopt = 1;
fea6e87812f0 Now everything works - the rfc3164 message parser must be improved.
viric@llimona
parents: 11
diff changeset
    43
	result = setsockopt(socket_unix, SOL_SOCKET, SO_REUSEADDR, &sockopt,
fea6e87812f0 Now everything works - the rfc3164 message parser must be improved.
viric@llimona
parents: 11
diff changeset
    44
		sizeof(sockopt));
fea6e87812f0 Now everything works - the rfc3164 message parser must be improved.
viric@llimona
parents: 11
diff changeset
    45
	assert(result == 0);
fea6e87812f0 Now everything works - the rfc3164 message parser must be improved.
viric@llimona
parents: 11
diff changeset
    46
9
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    47
	/* Unix socket listen address */
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    48
	memset(&source_unix, 0, sizeof(source_unix));
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    49
	source_unix.sun_family = AF_UNIX;
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    50
	strcpy(source_unix.sun_path, socketname);
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    51
	result = bind(socket_unix, (struct sockaddr *) &source_unix,
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    52
		sizeof(source_unix));
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    53
	assert(result == 0);
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    54
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    55
	/* Here we should take care of the socket permissions */
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    56
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    57
	return socket_unix;
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    58
}
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    59
15
fea6e87812f0 Now everything works - the rfc3164 message parser must be improved.
viric@llimona
parents: 11
diff changeset
    60
void server_loop(const char * restrict socketname)
9
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    61
{
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    62
	int socket_unix;
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    63
	int result;
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    64
	char message[MESSAGE_LENGTH+1];
38
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    65
	fd_set read_fd_set;
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    66
	struct timeval read_timeout;
9
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    67
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    68
	socket_unix = listen_unix(socketname);
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    69
38
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    70
	FD_ZERO(&read_fd_set);
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    71
29
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
    72
	while (finish == false)
9
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
    73
	{
38
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    74
		if (FD_ISSET(socket_unix, &read_fd_set))
29
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
    75
		{
38
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    76
			result = recv(socket_unix, message, MESSAGE_LENGTH, 0);
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    77
			if(result >= 0)
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    78
			{
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    79
				process_message(message);
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    80
				/* Debug */
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    81
				if(!strcmp(message,"close"))
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    82
					break;
53
667cd5966695 Finer message processing - now only at file and screen output appear '\n'.
viric@llimona
parents: 41
diff changeset
    83
				write(1, message, result);
38
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    84
			} else if (result == -1)
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    85
			{
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    86
				if (errno != EINTR)
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    87
					break;
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    88
			}
29
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
    89
		}
38
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    90
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    91
		/* Prepare the fd_set */
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    92
		FD_ZERO(&read_fd_set);
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    93
		FD_SET(socket_unix, &read_fd_set);
39
60858d13b22c Log file output written in a C module. Now the kernel doesn't check the errors
viric@mandarina
parents: 38
diff changeset
    94
		/* We set the timeout in order to save us easily from the race
60858d13b22c Log file output written in a C module. Now the kernel doesn't check the errors
viric@mandarina
parents: 38
diff changeset
    95
		 * condition for signal receiving (select/pselect) */
38
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    96
		read_timeout.tv_sec = 5;
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    97
		read_timeout.tv_usec = 0;
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    98
		result = select(socket_unix+1, &read_fd_set, NULL, NULL,
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
    99
				&read_timeout);
41
fc273c0e8250 Corrected a bug regarding select and signal receiving.
viric@llimona
parents: 40
diff changeset
   100
		if (result == -1)
fc273c0e8250 Corrected a bug regarding select and signal receiving.
viric@llimona
parents: 40
diff changeset
   101
			FD_ZERO(&read_fd_set);
38
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
   102
		assert( !(result == -1 && errno != EINTR) );
9
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   103
	}
29
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
   104
9
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   105
	result = close(socket_unix);
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   106
	if (result == -1)
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   107
	{
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   108
		printf("Unix socket close error: %s\n", strerror(errno));
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   109
		abort();
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   110
	}
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   111
	result = unlink(socketname);
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   112
	if (result == -1)
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   113
	{
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   114
		printf("Unix socket unlink error: %s\n", strerror(errno));
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   115
		abort();
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   116
	}
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   117
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   118
}
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   119
29
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
   120
static void term_handler(int parameter)
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
   121
{
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
   122
	finish=true;
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
   123
}
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
   124
9
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   125
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   126
int main(int argn, char **argv)
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   127
{
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   128
	/* Processem els parĂ metres d'entrada */
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   129
	if (argn != 2) {
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   130
		show_help(argv[0]);
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   131
		return 2;
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   132
	}
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   133
26
7227789ca718 Added a c file for signal programming.
viric@mandarina
parents: 15
diff changeset
   134
	program_ignore_hup();
29
e51d10f5ded4 in_unix now handles SIGTERM.
viric@mandarina
parents: 26
diff changeset
   135
	program_handler(SIGTERM, term_handler);
40
8c781743e0d0 Comment added for the SIGINT handler.
viric@llimona
parents: 39
diff changeset
   136
8c781743e0d0 Comment added for the SIGINT handler.
viric@llimona
parents: 39
diff changeset
   137
	/* If Ctrl-C is typed in a xterm, it will send SIGINT to the
8c781743e0d0 Comment added for the SIGINT handler.
viric@llimona
parents: 39
diff changeset
   138
	group process running in it. So even if we only run the kernel,
8c781743e0d0 Comment added for the SIGINT handler.
viric@llimona
parents: 39
diff changeset
   139
	this son will receive the xterm's SIGINT. We must handle that,
8c781743e0d0 Comment added for the SIGINT handler.
viric@llimona
parents: 39
diff changeset
   140
	as this program should unlink the socket, and not only close it. */
38
65c2ca03cc0f The SIGINT works in syslog_in_unix. The main loop uses select().
viric@mandarina
parents: 29
diff changeset
   141
	program_handler(SIGINT, term_handler);
26
7227789ca718 Added a c file for signal programming.
viric@mandarina
parents: 15
diff changeset
   142
9
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   143
	server_loop(argv[1]);
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   144
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   145
	return 0;
3fd9ecdc4299 First implementation of unix sockets
viric@mandarina
parents:
diff changeset
   146
}