author | viric@llimona |
Tue, 30 May 2006 12:02:13 +0200 | |
changeset 55 | c72dbd390cf2 |
parent 53 | 667cd5966695 |
permissions | -rw-r--r-- |
9 | 1 |
#include <unistd.h> // Per les crides a fitxer |
2 |
#include <stdio.h> // Per l'I/O de stdin/stdout |
|
3 |
#include <errno.h> // Pels errors de les crides a fitxer |
|
4 |
#include <string.h> // Per strerror() |
|
5 |
#include <stdlib.h> // Per abort() |
|
6 |
#include <sys/types.h> // Per crides de fitxer |
|
7 |
#include <sys/socket.h> // Per les macros bool,true,false |
|
8 |
#include <sys/un.h> // Per les estructures dels unix sockets |
|
9 |
#include <assert.h> // Per assert() |
|
29 | 10 |
#include <stdbool.h> |
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 | 13 |
|
14 |
#include "rfc3164.h" |
|
26 | 15 |
#include "syslog.h" |
9 | 16 |
|
29 | 17 |
|
18 |
static bool finish = false; |
|
19 |
||
9 | 20 |
void show_help(const char * restrict program) |
21 |
{ |
|
22 |
printf("Usage: %s <unix_socket>\n", program); |
|
23 |
} |
|
24 |
||
25 |
||
26 |
int listen_unix(const char * restrict socketname) |
|
27 |
{ |
|
28 |
int socket_unix; |
|
29 |
struct sockaddr_un source_unix; |
|
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 | 32 |
|
33 |
||
34 |
socket_unix = socket(PF_UNIX, SOCK_DGRAM, 0 ); |
|
35 |
if (socket_unix == -1) |
|
36 |
{ |
|
37 |
printf("Unix socket creation error: %s\n", strerror(errno)); |
|
38 |
abort(); |
|
39 |
} |
|
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 | 47 |
/* Unix socket listen address */ |
48 |
memset(&source_unix, 0, sizeof(source_unix)); |
|
49 |
source_unix.sun_family = AF_UNIX; |
|
50 |
strcpy(source_unix.sun_path, socketname); |
|
51 |
result = bind(socket_unix, (struct sockaddr *) &source_unix, |
|
52 |
sizeof(source_unix)); |
|
53 |
assert(result == 0); |
|
54 |
||
55 |
/* Here we should take care of the socket permissions */ |
|
56 |
||
57 |
return socket_unix; |
|
58 |
} |
|
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 | 61 |
{ |
62 |
int socket_unix; |
|
63 |
int result; |
|
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 | 67 |
|
68 |
socket_unix = listen_unix(socketname); |
|
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 | 72 |
while (finish == false) |
9 | 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 | 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 | 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 | 103 |
} |
29 | 104 |
|
9 | 105 |
result = close(socket_unix); |
106 |
if (result == -1) |
|
107 |
{ |
|
108 |
printf("Unix socket close error: %s\n", strerror(errno)); |
|
109 |
abort(); |
|
110 |
} |
|
111 |
result = unlink(socketname); |
|
112 |
if (result == -1) |
|
113 |
{ |
|
114 |
printf("Unix socket unlink error: %s\n", strerror(errno)); |
|
115 |
abort(); |
|
116 |
} |
|
117 |
||
118 |
} |
|
119 |
||
29 | 120 |
static void term_handler(int parameter) |
121 |
{ |
|
122 |
finish=true; |
|
123 |
} |
|
124 |
||
9 | 125 |
|
126 |
int main(int argn, char **argv) |
|
127 |
{ |
|
128 |
/* Processem els parĂ metres d'entrada */ |
|
129 |
if (argn != 2) { |
|
130 |
show_help(argv[0]); |
|
131 |
return 2; |
|
132 |
} |
|
133 |
||
26 | 134 |
program_ignore_hup(); |
29 | 135 |
program_handler(SIGTERM, term_handler); |
40 | 136 |
|
137 |
/* If Ctrl-C is typed in a xterm, it will send SIGINT to the |
|
138 |
group process running in it. So even if we only run the kernel, |
|
139 |
this son will receive the xterm's SIGINT. We must handle that, |
|
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 | 142 |
|
9 | 143 |
server_loop(argv[1]); |
144 |
||
145 |
return 0; |
|
146 |
} |