author | viric@mandarina |
Sun, 15 Feb 2009 19:12:08 +0100 | |
changeset 261 | dc8f1609bad8 |
parent 251 | 5e0802df5788 |
child 267 | 11631dd11ff8 |
permissions | -rw-r--r-- |
49 | 1 |
/* |
2 |
Task Spooler - a task queue system for the unix user |
|
231
558b281b88f5
Updating the Copyright years from 2007 to 2007-2008.
llbatlle@taga
parents:
146
diff
changeset
|
3 |
Copyright (C) 2007-2008 LluĂs Batlle i Rossell |
49 | 4 |
|
5 |
Please find the license in the provided COPYING file. |
|
6 |
*/ |
|
44 | 7 |
#include <unistd.h> |
8 |
#include <string.h> |
|
1 | 9 |
#include <sys/types.h> |
10 |
#include <sys/socket.h> |
|
11 |
#include <sys/un.h> |
|
12 |
#include <errno.h> |
|
3 | 13 |
#include <stdlib.h> |
9 | 14 |
#include <stdio.h> |
146 | 15 |
#include <sys/time.h> |
25 | 16 |
#include <signal.h> |
3 | 17 |
|
18 |
#include "main.h" |
|
1 | 19 |
|
20 |
extern int server_socket; |
|
21 |
||
251
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
22 |
static char *socket_path; |
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
23 |
|
25 | 24 |
static int fork_server(); |
25 |
||
251
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
26 |
void create_socket_path(char **path) |
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
27 |
{ |
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
28 |
char *tmpdir; |
119
361b08d33762
$USER is no more used for crating the socket path. Now the UID is used.
viric@llimona
parents:
92
diff
changeset
|
29 |
char userid[20]; |
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
30 |
int size; |
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
31 |
|
64 | 32 |
/* As a priority, TS_SOCKET mandates over the path creation */ |
251
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
33 |
*path = getenv("TS_SOCKET"); |
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
34 |
if (*path != 0) |
64 | 35 |
{ |
36 |
/* We need this in our memory, for forks and future 'free'. */ |
|
251
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
37 |
size = strlen(*path) + 1; |
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
38 |
*path = (char *) malloc(size); |
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
39 |
strcpy(*path, getenv("TS_SOCKET")); |
64 | 40 |
return; |
41 |
} |
|
42 |
||
43 |
/* ... if the $TS_SOCKET doesn't exist ... */ |
|
44 |
||
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
45 |
/* Create the path */ |
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
46 |
tmpdir = getenv("TMPDIR"); |
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
47 |
if (tmpdir == NULL) |
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
48 |
tmpdir = "/tmp"; |
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
49 |
|
119
361b08d33762
$USER is no more used for crating the socket path. Now the UID is used.
viric@llimona
parents:
92
diff
changeset
|
50 |
sprintf(userid, "%u", (unsigned int) getuid()); |
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
51 |
|
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
52 |
/* Calculate the size */ |
119
361b08d33762
$USER is no more used for crating the socket path. Now the UID is used.
viric@llimona
parents:
92
diff
changeset
|
53 |
size = strlen(tmpdir) + strlen("/socket-ts.") + strlen(userid) + 1; |
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
54 |
|
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
55 |
/* Freed after preparing the socket address */ |
251
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
56 |
*path = (char *) malloc(size); |
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
57 |
|
251
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
58 |
sprintf(*path, "%s/socket-ts.%s", tmpdir, userid); |
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
59 |
} |
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
60 |
|
1 | 61 |
int try_connect(int s) |
62 |
{ |
|
2 | 63 |
struct sockaddr_un addr; |
64 |
int res; |
|
1 | 65 |
|
2 | 66 |
addr.sun_family = AF_UNIX; |
251
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
67 |
strcpy(addr.sun_path, socket_path); |
1 | 68 |
|
2 | 69 |
res = connect(s, (struct sockaddr *) &addr, sizeof(addr)); |
70 |
return res; |
|
1 | 71 |
} |
72 |
||
25 | 73 |
void wait_server_up(int fd) |
1 | 74 |
{ |
25 | 75 |
char a; |
76 |
||
77 |
read(fd, &a, 1); |
|
78 |
close(fd); |
|
1 | 79 |
} |
80 |
||
25 | 81 |
/* Returns the fd where to wait for the parent notification */ |
82 |
static int fork_server() |
|
1 | 83 |
{ |
2 | 84 |
int pid; |
25 | 85 |
int p[2]; |
1 | 86 |
|
2 | 87 |
/* !!! stdin/stdout */ |
25 | 88 |
pipe(p); |
1 | 89 |
|
2 | 90 |
pid = fork(); |
91 |
switch (pid) |
|
92 |
{ |
|
93 |
case 0: /* Child */ |
|
25 | 94 |
close(p[0]); |
3 | 95 |
close(server_socket); |
66
f70a27afd92e
Adding "swap jobs" with -U. Fixed a big problem with fds 0, 1, 2.
viric@mandarina
parents:
64
diff
changeset
|
96 |
/* Close all std handles for the server */ |
f70a27afd92e
Adding "swap jobs" with -U. Fixed a big problem with fds 0, 1, 2.
viric@mandarina
parents:
64
diff
changeset
|
97 |
close(0); |
f70a27afd92e
Adding "swap jobs" with -U. Fixed a big problem with fds 0, 1, 2.
viric@mandarina
parents:
64
diff
changeset
|
98 |
close(1); |
f70a27afd92e
Adding "swap jobs" with -U. Fixed a big problem with fds 0, 1, 2.
viric@mandarina
parents:
64
diff
changeset
|
99 |
close(2); |
133 | 100 |
setsid(); |
251
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
101 |
server_main(p[1], socket_path); |
3 | 102 |
exit(0); |
2 | 103 |
break; |
104 |
case -1: /* Error */ |
|
25 | 105 |
return -1; |
2 | 106 |
default: /* Parent */ |
25 | 107 |
close(p[1]); |
2 | 108 |
} |
25 | 109 |
/* Return the read fd */ |
110 |
return p[0]; |
|
111 |
} |
|
112 |
||
113 |
void notify_parent(int fd) |
|
114 |
{ |
|
115 |
char a = 'a'; |
|
116 |
write(fd, &a, 1); |
|
117 |
close(fd); |
|
1 | 118 |
} |
119 |
||
120 |
int ensure_server_up() |
|
121 |
{ |
|
2 | 122 |
int res; |
25 | 123 |
int notify_fd; |
1 | 124 |
|
129
312083fb8899
Change PF_UNIX to AF_UNIX. According to socket(2), this is better.
viric@llimona
parents:
119
diff
changeset
|
125 |
server_socket = socket(AF_UNIX, SOCK_STREAM, 0); |
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
126 |
if (server_socket == -1) |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
127 |
error("getting the server socket"); |
1 | 128 |
|
251
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
129 |
create_socket_path(&socket_path); |
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
130 |
|
2 | 131 |
res = try_connect(server_socket); |
1 | 132 |
|
2 | 133 |
/* Good connection */ |
134 |
if (res == 0) |
|
135 |
return 1; |
|
1 | 136 |
|
2 | 137 |
/* If error other than "No one listens on the other end"... */ |
3 | 138 |
if (!(errno == ENOENT || errno == ECONNREFUSED)) |
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
139 |
error("c: cannot connect to the server"); |
1 | 140 |
|
3 | 141 |
if (errno == ECONNREFUSED) |
251
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
142 |
unlink(socket_path); |
3 | 143 |
|
2 | 144 |
/* Try starting the server */ |
25 | 145 |
notify_fd = fork_server(); |
146 |
wait_server_up(notify_fd); |
|
2 | 147 |
res = try_connect(server_socket); |
1 | 148 |
|
2 | 149 |
/* The second time didn't work. Abort. */ |
150 |
if (res == -1) |
|
9 | 151 |
{ |
152 |
fprintf(stderr, "The server didn't come up.\n"); |
|
153 |
exit(-1); |
|
154 |
} |
|
1 | 155 |
|
251
5e0802df5788
Making a ts.error file for each socket ($TS_SOCKET.error)
viric@mandarina
parents:
231
diff
changeset
|
156 |
free(socket_path); |
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
25
diff
changeset
|
157 |
|
2 | 158 |
/* Good connection on the second time */ |
159 |
return 1; |
|
1 | 160 |
} |