author | viric@llimona |
Fri, 13 Apr 2007 20:52:28 +0200 | |
changeset 127 | c620eacd7630 |
parent 120 | 790bc4cecd3b |
child 129 | 312083fb8899 |
permissions | -rw-r--r-- |
49 | 1 |
/* |
2 |
Task Spooler - a task queue system for the unix user |
|
3 |
Copyright (C) 2007 LluĂs Batlle i Rossell |
|
4 |
||
5 |
Please find the license in the provided COPYING file. |
|
6 |
*/ |
|
1 | 7 |
#include <sys/types.h> |
8 |
#include <sys/socket.h> |
|
44 | 9 |
#include <sys/select.h> |
94 | 10 |
#include <sys/time.h> |
11 |
#include <sys/resource.h> |
|
1 | 12 |
#include <sys/un.h> |
13 |
#include <errno.h> |
|
3 | 14 |
#include <string.h> |
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
26
diff
changeset
|
15 |
#include <stdlib.h> |
44 | 16 |
#include <unistd.h> |
94 | 17 |
#include <limits.h> |
99
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
18 |
#include <signal.h> |
120 | 19 |
#include <fcntl.h> |
1 | 20 |
|
21 |
#include <stdio.h> |
|
22 |
||
3 | 23 |
#include "main.h" |
1 | 24 |
|
25 |
enum |
|
26 |
{ |
|
64 | 27 |
MAXCONN=1000 |
1 | 28 |
}; |
29 |
||
30 |
enum Break |
|
31 |
{ |
|
2 | 32 |
BREAK, |
33 |
NOBREAK |
|
1 | 34 |
}; |
35 |
||
3 | 36 |
/* Prototypes */ |
37 |
static void server_loop(int ls); |
|
38 |
static enum Break |
|
39 |
client_read(int index); |
|
40 |
static void end_server(int ls); |
|
8 | 41 |
static void s_newjob_ok(int index); |
42 |
static void s_runjob(int index); |
|
3 | 43 |
|
44 |
struct Client_conn |
|
45 |
{ |
|
46 |
int socket; |
|
47 |
int hasjob; |
|
48 |
int jobid; |
|
49 |
}; |
|
50 |
||
51 |
/* Globals */ |
|
52 |
static struct Client_conn client_cs[MAXCONN]; |
|
53 |
static int nconnections; |
|
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
26
diff
changeset
|
54 |
static char *path; |
94 | 55 |
static int max_descriptors; |
56 |
||
99
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
57 |
static void sigterm_handler(int n) |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
58 |
{ |
120 | 59 |
const char *dumpfilename; |
60 |
int fd; |
|
61 |
||
62 |
/* Dump the job list if we should to */ |
|
63 |
dumpfilename = getenv("TS_SAVELIST"); |
|
64 |
if (dumpfilename != NULL) |
|
65 |
{ |
|
66 |
fd = open(dumpfilename, O_WRONLY | O_APPEND | O_CREAT, 0600); |
|
67 |
if (fd != -1) |
|
68 |
{ |
|
69 |
joblist_dump(fd); |
|
70 |
close(fd); |
|
71 |
} else |
|
72 |
warning("The TS_SAVELIST file \"%s\" cannot be opened", |
|
73 |
dumpfilename); |
|
74 |
} |
|
75 |
||
99
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
76 |
/* path will be initialized for sure, before installing the handler */ |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
77 |
unlink(path); |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
78 |
exit(1); |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
79 |
} |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
80 |
|
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
81 |
static void install_sigterm_handler() |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
82 |
{ |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
83 |
struct sigaction act; |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
84 |
|
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
85 |
act.sa_handler = sigterm_handler; |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
86 |
/* Reset the mask */ |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
87 |
memset(&act.sa_mask,0,sizeof(act.sa_mask)); |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
88 |
act.sa_flags = 0; |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
89 |
|
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
90 |
sigaction(SIGTERM, &act, NULL); |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
91 |
} |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
92 |
|
94 | 93 |
static int get_max_descriptors() |
94 |
{ |
|
95 |
const int MARGIN = 5; /* stdin, stderr, listen socket, and whatever */ |
|
96 |
int max; |
|
97 |
struct rlimit rlim; |
|
98 |
int res; |
|
99 |
||
100 |
max = MAXCONN; |
|
101 |
if (max > FD_SETSIZE) |
|
102 |
max = FD_SETSIZE; |
|
103 |
||
104 |
/* I'd like to use OPEN_MAX or NR_OPEN, but I don't know if any |
|
105 |
* of them is POSIX compliant */ |
|
106 |
||
107 |
res = getrlimit(RLIMIT_NOFILE, &rlim); |
|
108 |
if (res != 0) |
|
109 |
warning("getrlimit for open files"); |
|
110 |
else |
|
111 |
{ |
|
112 |
if (max > rlim.rlim_cur) |
|
113 |
max = rlim.rlim_cur; |
|
114 |
} |
|
115 |
||
116 |
if (max - MARGIN < 1) |
|
117 |
error("Too few opened descriptors available"); |
|
118 |
||
119 |
return max - MARGIN; |
|
120 |
} |
|
1 | 121 |
|
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
26
diff
changeset
|
122 |
void server_main(int notify_fd, char *_path) |
1 | 123 |
{ |
44 | 124 |
int ls; |
2 | 125 |
struct sockaddr_un addr; |
126 |
int res; |
|
1 | 127 |
|
104 | 128 |
process_type = SERVER; |
94 | 129 |
max_descriptors = get_max_descriptors(); |
130 |
||
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
26
diff
changeset
|
131 |
path = _path; |
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
26
diff
changeset
|
132 |
|
3 | 133 |
nconnections = 0; |
134 |
||
2 | 135 |
ls = socket(PF_UNIX, SOCK_STREAM, 0); |
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
136 |
if(ls == -1) |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
137 |
error("cannot create the listen socket in the server"); |
1 | 138 |
|
2 | 139 |
addr.sun_family = AF_UNIX; |
140 |
strcpy(addr.sun_path, path); |
|
1 | 141 |
|
2 | 142 |
res = bind(ls, (struct sockaddr *) &addr, sizeof(addr)); |
143 |
if (res == -1) |
|
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
144 |
error("Error binding."); |
1 | 145 |
|
2 | 146 |
res = listen(ls, 0); |
147 |
if (res == -1) |
|
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
148 |
error("Error listening."); |
1 | 149 |
|
99
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
150 |
install_sigterm_handler(); |
88d96be4e0e9
Never leave the socket if the server dies by SIGTERM.
viric@llimona
parents:
94
diff
changeset
|
151 |
|
25 | 152 |
notify_parent(notify_fd); |
153 |
||
2 | 154 |
server_loop(ls); |
1 | 155 |
} |
156 |
||
8 | 157 |
static int get_conn_of_jobid(int jobid) |
158 |
{ |
|
159 |
int i; |
|
160 |
for(i=0; i< nconnections; ++i) |
|
161 |
if (client_cs[i].hasjob && client_cs[i].jobid == jobid) |
|
162 |
return i; |
|
163 |
return -1; |
|
164 |
} |
|
165 |
||
3 | 166 |
static void server_loop(int ls) |
1 | 167 |
{ |
2 | 168 |
fd_set readset; |
169 |
int i; |
|
170 |
int maxfd; |
|
171 |
int keep_loop = 1; |
|
8 | 172 |
int newjob; |
1 | 173 |
|
2 | 174 |
while (keep_loop) |
175 |
{ |
|
176 |
FD_ZERO(&readset); |
|
94 | 177 |
maxfd = 0; |
178 |
/* If we can accept more connections, go on. |
|
179 |
* Otherwise, the system block them (no accept will be done). */ |
|
180 |
if (nconnections < max_descriptors) |
|
181 |
{ |
|
182 |
FD_SET(ls,&readset); |
|
183 |
maxfd = ls; |
|
184 |
} |
|
2 | 185 |
for(i=0; i< nconnections; ++i) |
186 |
{ |
|
3 | 187 |
FD_SET(client_cs[i].socket, &readset); |
188 |
if (client_cs[i].socket > maxfd) |
|
189 |
maxfd = client_cs[i].socket; |
|
2 | 190 |
} |
191 |
select(maxfd + 1, &readset, NULL, NULL, NULL); |
|
192 |
if (FD_ISSET(ls,&readset)) |
|
193 |
{ |
|
194 |
int cs; |
|
195 |
cs = accept(ls, NULL, NULL); |
|
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
196 |
if (cs == -1) |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
197 |
error("Accepting from %i", ls); |
3 | 198 |
client_cs[nconnections++].socket = cs; |
2 | 199 |
} |
200 |
for(i=0; i< nconnections; ++i) |
|
3 | 201 |
if (FD_ISSET(client_cs[i].socket, &readset)) |
2 | 202 |
{ |
203 |
enum Break b; |
|
3 | 204 |
b = client_read(i); |
2 | 205 |
/* Check if we should break */ |
206 |
if (b == BREAK) |
|
207 |
keep_loop = 0; |
|
208 |
} |
|
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
209 |
/* This will return firstjob->jobid or -1 */ |
8 | 210 |
newjob = next_run_job(); |
211 |
if (newjob != -1) |
|
212 |
{ |
|
213 |
int conn; |
|
214 |
conn = get_conn_of_jobid(newjob); |
|
19
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
215 |
/* This next marks the firstjob state to RUNNING */ |
5efc347cca8d
The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents:
18
diff
changeset
|
216 |
s_mark_job_running(); |
8 | 217 |
s_runjob(conn); |
218 |
} |
|
2 | 219 |
} |
1 | 220 |
|
2 | 221 |
end_server(ls); |
1 | 222 |
} |
223 |
||
3 | 224 |
static void end_server(int ls) |
1 | 225 |
{ |
2 | 226 |
close(ls); |
227 |
unlink(path); |
|
28
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
26
diff
changeset
|
228 |
/* This comes from the parent, in the fork after server_main. |
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
26
diff
changeset
|
229 |
* This is the last use of path in this process.*/ |
107abb4ec98a
Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents:
26
diff
changeset
|
230 |
free(path); |
1 | 231 |
} |
232 |
||
3 | 233 |
static void remove_connection(int index) |
1 | 234 |
{ |
2 | 235 |
int i; |
3 | 236 |
|
237 |
if(client_cs[index].hasjob) |
|
2 | 238 |
{ |
3 | 239 |
s_removejob(client_cs[index].jobid); |
2 | 240 |
} |
3 | 241 |
|
242 |
for(i=index; i<(nconnections-1); ++i) |
|
243 |
{ |
|
244 |
memcpy(&client_cs[i], &client_cs[i+1], sizeof(client_cs[0])); |
|
245 |
} |
|
246 |
nconnections--; |
|
1 | 247 |
} |
248 |
||
3 | 249 |
|
250 |
static enum Break |
|
251 |
client_read(int index) |
|
1 | 252 |
{ |
3 | 253 |
struct msg m; |
2 | 254 |
int s; |
255 |
int res; |
|
1 | 256 |
|
3 | 257 |
s = client_cs[index].socket; |
1 | 258 |
|
2 | 259 |
/* Read the message */ |
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
260 |
res = recv_msg(s, &m); |
8 | 261 |
if (res == -1) |
262 |
{ |
|
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
263 |
warning("client read"); |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
264 |
close(s); |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
265 |
remove_connection(index); |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
266 |
/* It will not fail, even if the index is not a notification */ |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
267 |
s_remove_notification(index); |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
268 |
return NOBREAK; |
8 | 269 |
} |
2 | 270 |
if (res == 0) |
271 |
{ |
|
272 |
close(s); |
|
3 | 273 |
remove_connection(index); |
45 | 274 |
/* It will not fail, even if the index is not a notification */ |
275 |
s_remove_notification(index); |
|
2 | 276 |
return NOBREAK; |
277 |
} |
|
1 | 278 |
|
3 | 279 |
client_cs[index].hasjob = 0; |
280 |
||
2 | 281 |
/* Process message */ |
31 | 282 |
if (m.type == KILL_SERVER) |
2 | 283 |
return BREAK; /* break in the parent*/ |
1 | 284 |
|
3 | 285 |
if (m.type == NEWJOB) |
286 |
{ |
|
18 | 287 |
client_cs[index].jobid = s_newjob(s, &m); |
3 | 288 |
client_cs[index].hasjob = 1; |
4 | 289 |
s_newjob_ok(index); |
3 | 290 |
} |
291 |
||
22 | 292 |
if (m.type == RUNJOB_OK) |
293 |
{ |
|
294 |
char *buffer = 0; |
|
32 | 295 |
if (m.u.output.store_output) |
22 | 296 |
{ |
297 |
/* Receive the output filename */ |
|
32 | 298 |
buffer = (char *) malloc(m.u.output.ofilename_size); |
22 | 299 |
res = recv_bytes(client_cs[index].socket, buffer, |
32 | 300 |
m.u.output.ofilename_size); |
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
301 |
if (res != m.u.output.ofilename_size) |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
302 |
error("Reading the ofilename"); |
22 | 303 |
} |
35 | 304 |
s_process_runjob_ok(client_cs[index].jobid, buffer, |
305 |
m.u.output.pid); |
|
22 | 306 |
} |
307 |
||
3 | 308 |
if (m.type == LIST) |
5 | 309 |
{ |
310 |
s_list(client_cs[index].socket); |
|
9 | 311 |
/* We must actively close, meaning End of Lines */ |
5 | 312 |
close(client_cs[index].socket); |
313 |
remove_connection(index); |
|
314 |
} |
|
3 | 315 |
|
8 | 316 |
if (m.type == ENDJOB) |
317 |
{ |
|
114 | 318 |
job_finished(&m.u.result); |
42 | 319 |
check_notify_list(client_cs[index].jobid); |
8 | 320 |
} |
321 |
||
20
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
322 |
if (m.type == CLEAR_FINISHED) |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
323 |
{ |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
324 |
s_clear_finished(); |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
325 |
} |
d85b4c0745fa
"-c" added, for clearing the finished tasks' list.
viric@llimona
parents:
19
diff
changeset
|
326 |
|
32 | 327 |
if (m.type == ASK_OUTPUT) |
328 |
{ |
|
329 |
s_send_output(client_cs[index].socket, m.u.jobid); |
|
330 |
} |
|
331 |
||
41 | 332 |
if (m.type == REMOVEJOB) |
333 |
{ |
|
334 |
s_remove_job(client_cs[index].socket, m.u.jobid); |
|
335 |
} |
|
336 |
||
42 | 337 |
if (m.type == WAITJOB) |
338 |
{ |
|
339 |
s_wait_job(client_cs[index].socket, m.u.jobid); |
|
340 |
} |
|
341 |
||
53 | 342 |
if (m.type == URGENT) |
343 |
{ |
|
344 |
s_move_urgent(client_cs[index].socket, m.u.jobid); |
|
345 |
} |
|
346 |
||
66
f70a27afd92e
Adding "swap jobs" with -U. Fixed a big problem with fds 0, 1, 2.
viric@mandarina
parents:
64
diff
changeset
|
347 |
if (m.type == SWAP_JOBS) |
f70a27afd92e
Adding "swap jobs" with -U. Fixed a big problem with fds 0, 1, 2.
viric@mandarina
parents:
64
diff
changeset
|
348 |
{ |
f70a27afd92e
Adding "swap jobs" with -U. Fixed a big problem with fds 0, 1, 2.
viric@mandarina
parents:
64
diff
changeset
|
349 |
s_swap_jobs(client_cs[index].socket, m.u.swap.jobid1, |
f70a27afd92e
Adding "swap jobs" with -U. Fixed a big problem with fds 0, 1, 2.
viric@mandarina
parents:
64
diff
changeset
|
350 |
m.u.swap.jobid2); |
f70a27afd92e
Adding "swap jobs" with -U. Fixed a big problem with fds 0, 1, 2.
viric@mandarina
parents:
64
diff
changeset
|
351 |
} |
f70a27afd92e
Adding "swap jobs" with -U. Fixed a big problem with fds 0, 1, 2.
viric@mandarina
parents:
64
diff
changeset
|
352 |
|
63 | 353 |
if (m.type == GET_STATE) |
354 |
{ |
|
355 |
s_send_state(client_cs[index].socket, m.u.jobid); |
|
356 |
} |
|
357 |
||
2 | 358 |
return NOBREAK; /* normal */ |
1 | 359 |
} |
4 | 360 |
|
8 | 361 |
static void s_runjob(int index) |
362 |
{ |
|
363 |
int s; |
|
364 |
struct msg m; |
|
365 |
||
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
366 |
if (!client_cs[index].hasjob) |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
367 |
error("Run job of the client %i which doesn't have any job", index); |
8 | 368 |
|
369 |
s = client_cs[index].socket; |
|
370 |
||
371 |
m.type = RUNJOB; |
|
372 |
||
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
373 |
send_msg(s, &m); |
8 | 374 |
} |
375 |
||
376 |
static void s_newjob_ok(int index) |
|
4 | 377 |
{ |
378 |
int s; |
|
379 |
struct msg m; |
|
380 |
||
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
381 |
if (!client_cs[index].hasjob) |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
382 |
error("Run job of the client %i which doesn't have any job", index); |
4 | 383 |
|
384 |
s = client_cs[index].socket; |
|
385 |
||
386 |
m.type = NEWJOB_OK; |
|
387 |
m.u.jobid = client_cs[index].jobid; |
|
388 |
||
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
389 |
send_msg(s, &m); |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
390 |
} |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
391 |
|
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
392 |
static void dump_conn_struct(FILE *out, const struct Client_conn *p) |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
393 |
{ |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
394 |
fprintf(out, " new_conn\n"); |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
395 |
fprintf(out, " socket %i\n", p->socket); |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
396 |
fprintf(out, " hasjob \"%i\"\n", p->hasjob); |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
397 |
fprintf(out, " jobid %i\n", p->jobid); |
4 | 398 |
} |
92
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
399 |
|
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
400 |
void dump_conns_struct(FILE *out) |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
401 |
{ |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
402 |
int i; |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
403 |
|
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
404 |
fprintf(out, "New_conns"); |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
405 |
|
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
406 |
for(i=0; i < nconnections; ++i) |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
407 |
{ |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
408 |
dump_conn_struct(out, &client_cs[i]); |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
409 |
} |
05004c52ecff
Better error reports on internal handled errors.
viric@llimona
parents:
66
diff
changeset
|
410 |
} |