summaryrefslogtreecommitdiff
path: root/runit/runsv.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-03-09 22:46:06 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-03-09 22:46:06 +0000
commit3aba666514c8c1d6d5b21961e8f4253fd6dd2cca (patch)
tree3cbe1912235897d984fd62fdafb07b703be53209 /runit/runsv.c
parentbebbd8c9baaa7a2da5ac9ab484f54ce3115982d5 (diff)
downloadbusybox-w32-3aba666514c8c1d6d5b21961e8f4253fd6dd2cca.tar.gz
busybox-w32-3aba666514c8c1d6d5b21961e8f4253fd6dd2cca.tar.bz2
busybox-w32-3aba666514c8c1d6d5b21961e8f4253fd6dd2cca.zip
runsv: random code savings, ~300 bytes
Diffstat (limited to '')
-rw-r--r--runit/runsv.c135
1 files changed, 63 insertions, 72 deletions
diff --git a/runit/runsv.c b/runit/runsv.c
index 4a71ae966..813709d41 100644
--- a/runit/runsv.c
+++ b/runit/runsv.c
@@ -23,20 +23,20 @@ static int selfpipe[2];
23 23
24struct svdir { 24struct svdir {
25 int pid; 25 int pid;
26 int state; 26 smallint state;
27 int ctrl; 27 smallint ctrl;
28 int want; 28 smallint want;
29 smallint islog;
29 struct taia start; 30 struct taia start;
30 int fdlock; 31 int fdlock;
31 int fdcontrol; 32 int fdcontrol;
32 int fdcontrolwrite; 33 int fdcontrolwrite;
33 int islog;
34}; 34};
35static struct svdir svd[2]; 35static struct svdir svd[2];
36 36
37static int sigterm = 0; 37static smallint sigterm;
38static int haslog = 0; 38static smallint haslog;
39static int pidchanged = 1; 39static smallint pidchanged = 1;
40static int logpipe[2]; 40static int logpipe[2];
41static char *dir; 41static char *dir;
42 42
@@ -66,8 +66,6 @@ static void warnx_cannot(const char *m)
66 bb_error_msg("%s: warning: cannot %s", dir, m); 66 bb_error_msg("%s: warning: cannot %s", dir, m);
67} 67}
68 68
69static void stopservice(struct svdir *);
70
71static void s_child(int sig_no) 69static void s_child(int sig_no)
72{ 70{
73 write(selfpipe[1], "", 1); 71 write(selfpipe[1], "", 1);
@@ -119,17 +117,14 @@ static void update_status(struct svdir *s)
119 if (fd < 0) 117 if (fd < 0)
120 return; 118 return;
121 if (s->pid) { 119 if (s->pid) {
122 char spid[sizeof(s->pid)*3 + 2]; 120 char spid[sizeof(int)*3 + 2];
123 int size = sprintf(spid, "%d\n", s->pid); 121 int size = sprintf(spid, "%u\n", (unsigned)s->pid);
124 write(fd, spid, size); 122 write(fd, spid, size);
125 } 123 }
126 close(fd); 124 close(fd);
127 if (s->islog) { 125 if (rename_or_warn("supervise/pid.new",
128 if (rename_or_warn("supervise/pid.new", "log/supervise/pid")) 126 s->islog ? "log/supervise/pid" : "log/supervise/pid"+4))
129 return;
130 } else if (rename_or_warn("supervise/pid.new", "supervise/pid")) {
131 return; 127 return;
132 }
133 pidchanged = 0; 128 pidchanged = 0;
134 } 129 }
135 130
@@ -168,11 +163,8 @@ static void update_status(struct svdir *s)
168 close(fd); 163 close(fd);
169 } 164 }
170 165
171 if (s->islog) { 166 rename_or_warn("supervise/stat.new",
172 rename_or_warn("supervise/stat.new", "log/supervise/stat"); 167 s->islog ? "log/supervise/stat" : "log/supervise/stat"+4);
173 } else {
174 rename_or_warn("supervise/stat.new", "log/supervise/stat"+4);
175 }
176 168
177 /* supervise compatibility */ 169 /* supervise compatibility */
178 taia_pack(status, &s->start); 170 taia_pack(status, &s->start);
@@ -197,7 +189,7 @@ static void update_status(struct svdir *s)
197 fd = open_trunc_or_warn("supervise/status.new"); 189 fd = open_trunc_or_warn("supervise/status.new");
198 if (fd < 0) 190 if (fd < 0)
199 return; 191 return;
200 l = write(fd, status, sizeof status); 192 l = write(fd, status, sizeof(status));
201 if (l < 0) { 193 if (l < 0) {
202 warn_cannot("write supervise/status.new"); 194 warn_cannot("write supervise/status.new");
203 close(fd); 195 close(fd);
@@ -205,15 +197,12 @@ static void update_status(struct svdir *s)
205 return; 197 return;
206 } 198 }
207 close(fd); 199 close(fd);
208 if (l < sizeof status) { 200 if (l < sizeof(status)) {
209 warnx_cannot("write supervise/status.new: partial write"); 201 warnx_cannot("write supervise/status.new: partial write");
210 return; 202 return;
211 } 203 }
212 if (s->islog) { 204 rename_or_warn("supervise/status.new",
213 rename_or_warn("supervise/status.new", "log/supervise/status"); 205 s->islog ? "log/supervise/status" : "log/supervise/status"+4);
214 } else {
215 rename_or_warn("supervise/status.new", "log/supervise/status"+4);
216 }
217} 206}
218 207
219static unsigned custom(struct svdir *s, char c) 208static unsigned custom(struct svdir *s, char c)
@@ -225,7 +214,7 @@ static unsigned custom(struct svdir *s, char c)
225 char *prog[2]; 214 char *prog[2];
226 215
227 if (s->islog) return 0; 216 if (s->islog) return 0;
228 memcpy(a, "control/?", 10); 217 strcpy(a, "control/?");
229 a[8] = c; 218 a[8] = c;
230 if (stat(a, &st) == 0) { 219 if (stat(a, &st) == 0) {
231 if (st.st_mode & S_IXUSR) { 220 if (st.st_mode & S_IXUSR) {
@@ -238,7 +227,7 @@ static unsigned custom(struct svdir *s, char c)
238 if (haslog && fd_copy(1, logpipe[1]) == -1) 227 if (haslog && fd_copy(1, logpipe[1]) == -1)
239 warn_cannot("setup stdout for control/?"); 228 warn_cannot("setup stdout for control/?");
240 prog[0] = a; 229 prog[0] = a;
241 prog[1] = 0; 230 prog[1] = NULL;
242 execve(a, prog, environ); 231 execve(a, prog, environ);
243 fatal_cannot("run control/?"); 232 fatal_cannot("run control/?");
244 } 233 }
@@ -249,24 +238,24 @@ static unsigned custom(struct svdir *s, char c)
249 } 238 }
250 return !wait_exitcode(w); 239 return !wait_exitcode(w);
251 } 240 }
252 } 241 } else {
253 else { 242 if (errno != ENOENT)
254 if (errno == ENOENT) return 0; 243 warn_cannot("stat control/?");
255 warn_cannot("stat control/?");
256 } 244 }
257 return 0; 245 return 0;
258} 246}
259 247
260static void stopservice(struct svdir *s) 248static void stopservice(struct svdir *s)
261{ 249{
262 if (s->pid && ! custom(s, 't')) { 250 if (s->pid && !custom(s, 't')) {
263 kill(s->pid, SIGTERM); 251 kill(s->pid, SIGTERM);
264 s->ctrl |=C_TERM; 252 s->ctrl |= C_TERM;
265 update_status(s); 253 update_status(s);
266 } 254 }
267 if (s->want == W_DOWN) { 255 if (s->want == W_DOWN) {
268 kill(s->pid, SIGCONT); 256 kill(s->pid, SIGCONT);
269 custom(s, 'd'); return; 257 custom(s, 'd');
258 return;
270 } 259 }
271 if (s->want == W_EXIT) { 260 if (s->want == W_EXIT) {
272 kill(s->pid, SIGCONT); 261 kill(s->pid, SIGCONT);
@@ -312,10 +301,7 @@ static void startservice(struct svdir *s)
312 sig_uncatch(SIGTERM); 301 sig_uncatch(SIGTERM);
313 sig_unblock(SIGTERM); 302 sig_unblock(SIGTERM);
314 execve(*run, run, environ); 303 execve(*run, run, environ);
315 if (s->islog) 304 fatal2_cannot(s->islog ? "start log/" : "start ", *run);
316 fatal2_cannot("start log/", *run);
317 else
318 fatal2_cannot("start ", *run);
319 } 305 }
320 if (s->state != S_FINISH) { 306 if (s->state != S_FINISH) {
321 taia_now(&s->start); 307 taia_now(&s->start);
@@ -329,6 +315,8 @@ static void startservice(struct svdir *s)
329 315
330static int ctrl(struct svdir *s, char c) 316static int ctrl(struct svdir *s, char c)
331{ 317{
318 int sig;
319
332 switch (c) { 320 switch (c) {
333 case 'd': /* down */ 321 case 'd': /* down */
334 s->want = W_DOWN; 322 s->want = W_DOWN;
@@ -344,23 +332,22 @@ static int ctrl(struct svdir *s, char c)
344 if (s->islog) break; 332 if (s->islog) break;
345 s->want = W_EXIT; 333 s->want = W_EXIT;
346 update_status(s); 334 update_status(s);
347 if (s->pid && s->state != S_FINISH) stopservice(s); 335 /* FALLTHROUGH */
348 break;
349 case 't': /* sig term */ 336 case 't': /* sig term */
350 if (s->pid && s->state != S_FINISH) stopservice(s); 337 if (s->pid && s->state != S_FINISH) stopservice(s);
351 break; 338 break;
352 case 'k': /* sig kill */ 339 case 'k': /* sig kill */
353 if (s->pid && ! custom(s, c)) kill(s->pid, SIGKILL); 340 if (s->pid && !custom(s, c)) kill(s->pid, SIGKILL);
354 s->state = S_DOWN; 341 s->state = S_DOWN;
355 break; 342 break;
356 case 'p': /* sig pause */ 343 case 'p': /* sig pause */
357 if (s->pid && ! custom(s, c)) kill(s->pid, SIGSTOP); 344 if (s->pid && !custom(s, c)) kill(s->pid, SIGSTOP);
358 s->ctrl |=C_PAUSE; 345 s->ctrl |= C_PAUSE;
359 update_status(s); 346 update_status(s);
360 break; 347 break;
361 case 'c': /* sig cont */ 348 case 'c': /* sig cont */
362 if (s->pid && ! custom(s, c)) kill(s->pid, SIGCONT); 349 if (s->pid && !custom(s, c)) kill(s->pid, SIGCONT);
363 if (s->ctrl & C_PAUSE) s->ctrl &=~C_PAUSE; 350 if (s->ctrl & C_PAUSE) s->ctrl &= ~C_PAUSE;
364 update_status(s); 351 update_status(s);
365 break; 352 break;
366 case 'o': /* once */ 353 case 'o': /* once */
@@ -369,25 +356,29 @@ static int ctrl(struct svdir *s, char c)
369 if (!s->pid) startservice(s); 356 if (!s->pid) startservice(s);
370 break; 357 break;
371 case 'a': /* sig alarm */ 358 case 'a': /* sig alarm */
372 if (s->pid && ! custom(s, c)) kill(s->pid, SIGALRM); 359 sig = SIGALRM;
373 break; 360 goto sendsig;
374 case 'h': /* sig hup */ 361 case 'h': /* sig hup */
375 if (s->pid && ! custom(s, c)) kill(s->pid, SIGHUP); 362 sig = SIGHUP;
376 break; 363 goto sendsig;
377 case 'i': /* sig int */ 364 case 'i': /* sig int */
378 if (s->pid && ! custom(s, c)) kill(s->pid, SIGINT); 365 sig = SIGINT;
379 break; 366 goto sendsig;
380 case 'q': /* sig quit */ 367 case 'q': /* sig quit */
381 if (s->pid && ! custom(s, c)) kill(s->pid, SIGQUIT); 368 sig = SIGQUIT;
382 break; 369 goto sendsig;
383 case '1': /* sig usr1 */ 370 case '1': /* sig usr1 */
384 if (s->pid && ! custom(s, c)) kill(s->pid, SIGUSR1); 371 sig = SIGUSR1;
385 break; 372 goto sendsig;
386 case '2': /* sig usr2 */ 373 case '2': /* sig usr2 */
387 if (s->pid && ! custom(s, c)) kill(s->pid, SIGUSR2); 374 sig = SIGUSR2;
388 break; 375 goto sendsig;
389 } 376 }
390 return 1; 377 return 1;
378 sendsig:
379 if (s->pid && !custom(s, c))
380 kill(s->pid, sig);
381 return 1;
391} 382}
392 383
393int runsv_main(int argc, char **argv); 384int runsv_main(int argc, char **argv);
@@ -413,12 +404,12 @@ int runsv_main(int argc, char **argv)
413 sig_catch(SIGTERM, s_term); 404 sig_catch(SIGTERM, s_term);
414 405
415 xchdir(dir); 406 xchdir(dir);
416 svd[0].pid = 0; 407 /* bss: svd[0].pid = 0; */
417 svd[0].state = S_DOWN; 408 if (S_DOWN) svd[0].state = S_DOWN; /* otherwise already 0 (bss) */
418 svd[0].ctrl = C_NOOP; 409 if (C_NOOP) svd[0].ctrl = C_NOOP;
419 svd[0].want = W_UP; 410 if (W_UP) svd[0].want = W_UP;
420 svd[0].islog = 0; 411 /* bss: svd[0].islog = 0; */
421 svd[1].pid = 0; 412 /* bss: svd[1].pid = 0; */
422 taia_now(&svd[0].start); 413 taia_now(&svd[0].start);
423 if (stat("down", &s) != -1) svd[0].want = W_DOWN; 414 if (stat("down", &s) != -1) svd[0].want = W_DOWN;
424 415
@@ -445,10 +436,10 @@ int runsv_main(int argc, char **argv)
445 } 436 }
446 437
447 if (mkdir("supervise", 0700) == -1) { 438 if (mkdir("supervise", 0700) == -1) {
448 r = readlink("supervise", buf, 256); 439 r = readlink("supervise", buf, sizeof(buf));
449 if (r != -1) { 440 if (r != -1) {
450 if (r == 256) 441 if (r == sizeof(buf))
451 fatal2x_cannot("readlink ./supervise: ", "name too long"); 442 fatal2x_cannot("readlink ./supervise", ": name too long");
452 buf[r] = 0; 443 buf[r] = 0;
453 mkdir(buf, 0700); 444 mkdir(buf, 0700);
454 } else { 445 } else {
@@ -466,7 +457,7 @@ int runsv_main(int argc, char **argv)
466 r = readlink("log/supervise", buf, 256); 457 r = readlink("log/supervise", buf, 256);
467 if (r != -1) { 458 if (r != -1) {
468 if (r == 256) 459 if (r == 256)
469 fatal2x_cannot("readlink ./log/supervise: ", "name too long"); 460 fatal2x_cannot("readlink ./log/supervise", ": name too long");
470 buf[r] = 0; 461 buf[r] = 0;
471 fd = xopen(".", O_RDONLY|O_NDELAY); 462 fd = xopen(".", O_RDONLY|O_NDELAY);
472 xchdir("./log"); 463 xchdir("./log");
@@ -552,7 +543,7 @@ int runsv_main(int argc, char **argv)
552 if (child == svd[0].pid) { 543 if (child == svd[0].pid) {
553 svd[0].pid = 0; 544 svd[0].pid = 0;
554 pidchanged = 1; 545 pidchanged = 1;
555 svd[0].ctrl &=~C_TERM; 546 svd[0].ctrl &=~ C_TERM;
556 if (svd[0].state != S_FINISH) { 547 if (svd[0].state != S_FINISH) {
557 fd = open_read("finish"); 548 fd = open_read("finish");
558 if (fd != -1) { 549 if (fd != -1) {
@@ -574,7 +565,7 @@ int runsv_main(int argc, char **argv)
574 svd[1].pid = 0; 565 svd[1].pid = 0;
575 pidchanged = 1; 566 pidchanged = 1;
576 svd[1].state = S_DOWN; 567 svd[1].state = S_DOWN;
577 svd[1].ctrl &=~C_TERM; 568 svd[1].ctrl &= ~C_TERM;
578 taia_uint(&deadline, 1); 569 taia_uint(&deadline, 1);
579 taia_add(&deadline, &svd[1].start, &deadline); 570 taia_add(&deadline, &svd[1].start, &deadline);
580 taia_now(&svd[1].start); 571 taia_now(&svd[1].start);