diff options
author | Earl Chew <earl_chew@agilent.com> | 2009-08-02 02:23:27 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-08-02 02:23:27 +0200 |
commit | 80a3418b8c96300826842f109cd297280d3fbe05 (patch) | |
tree | 6467801de1340e1354510fc3a0c45b6298dcfa0b | |
parent | aebb742939d4100fbd1c7e94c68f9265e0805fd8 (diff) | |
download | busybox-w32-80a3418b8c96300826842f109cd297280d3fbe05.tar.gz busybox-w32-80a3418b8c96300826842f109cd297280d3fbe05.tar.bz2 busybox-w32-80a3418b8c96300826842f109cd297280d3fbe05.zip |
runsv: run ./finish with parameters (runit compat)
function old new delta
startservice 288 377 +89
runsv_main 1763 1783 +20
Signed-off-by: Earl Chew <earl_chew@agilent.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | runit/runsv.c | 63 |
1 files changed, 45 insertions, 18 deletions
diff --git a/runit/runsv.c b/runit/runsv.c index e93e25a4d..4dfdd3dc1 100644 --- a/runit/runsv.c +++ b/runit/runsv.c | |||
@@ -84,6 +84,7 @@ struct svdir { | |||
84 | int fdlock; | 84 | int fdlock; |
85 | int fdcontrol; | 85 | int fdcontrol; |
86 | int fdcontrolwrite; | 86 | int fdcontrolwrite; |
87 | int wstat; | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | struct globals { | 90 | struct globals { |
@@ -138,7 +139,8 @@ static void s_term(int sig_no UNUSED_PARAM) | |||
138 | write(selfpipe.wr, "", 1); /* XXX */ | 139 | write(selfpipe.wr, "", 1); /* XXX */ |
139 | } | 140 | } |
140 | 141 | ||
141 | static char *add_str(char *p, const char *to_add) | 142 | /* libbb candidate */ |
143 | static char *bb_stpcpy(char *p, const char *to_add) | ||
142 | { | 144 | { |
143 | while ((*p = *to_add) != '\0') { | 145 | while ((*p = *to_add) != '\0') { |
144 | p++; | 146 | p++; |
@@ -189,24 +191,26 @@ static void update_status(struct svdir *s) | |||
189 | char *p = stat_buf; | 191 | char *p = stat_buf; |
190 | switch (s->state) { | 192 | switch (s->state) { |
191 | case S_DOWN: | 193 | case S_DOWN: |
192 | p = add_str(p, "down"); | 194 | p = bb_stpcpy(p, "down"); |
193 | break; | 195 | break; |
194 | case S_RUN: | 196 | case S_RUN: |
195 | p = add_str(p, "run"); | 197 | p = bb_stpcpy(p, "run"); |
196 | break; | 198 | break; |
197 | case S_FINISH: | 199 | case S_FINISH: |
198 | p = add_str(p, "finish"); | 200 | p = bb_stpcpy(p, "finish"); |
199 | break; | 201 | break; |
200 | } | 202 | } |
201 | if (s->ctrl & C_PAUSE) p = add_str(p, ", paused"); | 203 | if (s->ctrl & C_PAUSE) |
202 | if (s->ctrl & C_TERM) p = add_str(p, ", got TERM"); | 204 | p = bb_stpcpy(p, ", paused"); |
205 | if (s->ctrl & C_TERM) | ||
206 | p = bb_stpcpy(p, ", got TERM"); | ||
203 | if (s->state != S_DOWN) | 207 | if (s->state != S_DOWN) |
204 | switch (s->sd_want) { | 208 | switch (s->sd_want) { |
205 | case W_DOWN: | 209 | case W_DOWN: |
206 | p = add_str(p, ", want down"); | 210 | p = bb_stpcpy(p, ", want down"); |
207 | break; | 211 | break; |
208 | case W_EXIT: | 212 | case W_EXIT: |
209 | p = add_str(p, ", want exit"); | 213 | p = bb_stpcpy(p, ", want exit"); |
210 | break; | 214 | break; |
211 | } | 215 | } |
212 | *p++ = '\n'; | 216 | *p++ = '\n'; |
@@ -263,7 +267,7 @@ static unsigned custom(struct svdir *s, char c) | |||
263 | warn_cannot("vfork for control/?"); | 267 | warn_cannot("vfork for control/?"); |
264 | return 0; | 268 | return 0; |
265 | } | 269 | } |
266 | if (!pid) { | 270 | if (pid == 0) { |
267 | /* child */ | 271 | /* child */ |
268 | if (haslog && dup2(logpipe.wr, 1) == -1) | 272 | if (haslog && dup2(logpipe.wr, 1) == -1) |
269 | warn_cannot("setup stdout for control/?"); | 273 | warn_cannot("setup stdout for control/?"); |
@@ -305,12 +309,33 @@ static void stopservice(struct svdir *s) | |||
305 | static void startservice(struct svdir *s) | 309 | static void startservice(struct svdir *s) |
306 | { | 310 | { |
307 | int p; | 311 | int p; |
308 | const char *run; | 312 | const char *arg[4]; |
309 | 313 | char exitcode[sizeof(int)*3 + 2]; | |
310 | if (s->state == S_FINISH) | 314 | char sigcode[sizeof(int)*3 + 2]; |
311 | run = "./finish"; | 315 | |
312 | else { | 316 | if (s->state == S_FINISH) { |
313 | run = "./run"; | 317 | /* Two arguments are given to ./finish. The first one is ./run exit code, |
318 | * or -1 if ./run didnt exit normally. The second one is | ||
319 | * the least significant byte of the exit status as determined by waitpid; | ||
320 | * for instance it is 0 if ./run exited normally, and the signal number | ||
321 | * if ./run was terminated by a signal. If runsv cannot start ./run | ||
322 | * for some reason, the exit code is 111 and the status is 0. | ||
323 | */ | ||
324 | arg[0] = "./finish"; | ||
325 | arg[1] = "-1"; | ||
326 | if (WIFEXITED(s->wstat)) { | ||
327 | sprintf(exitcode, "%u", (int) WEXITSTATUS(s->wstat)); | ||
328 | arg[1] = exitcode; | ||
329 | } | ||
330 | //arg[2] = "0"; | ||
331 | //if (WIFSIGNALED(s->wstat)) { | ||
332 | sprintf(sigcode, "%u", (int) WTERMSIG(s->wstat)); | ||
333 | arg[2] = sigcode; | ||
334 | //} | ||
335 | arg[3] = NULL; | ||
336 | } else { | ||
337 | arg[0] = "./run"; | ||
338 | arg[1] = NULL; | ||
314 | custom(s, 'u'); | 339 | custom(s, 'u'); |
315 | } | 340 | } |
316 | 341 | ||
@@ -340,8 +365,8 @@ static void startservice(struct svdir *s) | |||
340 | , SIG_DFL);*/ | 365 | , SIG_DFL);*/ |
341 | sig_unblock(SIGCHLD); | 366 | sig_unblock(SIGCHLD); |
342 | sig_unblock(SIGTERM); | 367 | sig_unblock(SIGTERM); |
343 | execl(run, run, (char *) NULL); | 368 | execv(arg[0], (char**) arg); |
344 | fatal2_cannot(s->islog ? "start log/" : "start ", run); | 369 | fatal2_cannot(s->islog ? "start log/" : "start ", arg[0]); |
345 | } | 370 | } |
346 | /* parent */ | 371 | /* parent */ |
347 | if (s->state != S_FINISH) { | 372 | if (s->state != S_FINISH) { |
@@ -591,9 +616,10 @@ int runsv_main(int argc UNUSED_PARAM, char **argv) | |||
591 | if ((child == -1) && (errno != EINTR)) | 616 | if ((child == -1) && (errno != EINTR)) |
592 | break; | 617 | break; |
593 | if (child == svd[0].pid) { | 618 | if (child == svd[0].pid) { |
619 | svd[0].wstat = wstat; | ||
594 | svd[0].pid = 0; | 620 | svd[0].pid = 0; |
595 | pidchanged = 1; | 621 | pidchanged = 1; |
596 | svd[0].ctrl &=~ C_TERM; | 622 | svd[0].ctrl &= ~C_TERM; |
597 | if (svd[0].state != S_FINISH) { | 623 | if (svd[0].state != S_FINISH) { |
598 | fd = open_read("finish"); | 624 | fd = open_read("finish"); |
599 | if (fd != -1) { | 625 | if (fd != -1) { |
@@ -612,6 +638,7 @@ int runsv_main(int argc UNUSED_PARAM, char **argv) | |||
612 | } | 638 | } |
613 | if (haslog) { | 639 | if (haslog) { |
614 | if (child == svd[1].pid) { | 640 | if (child == svd[1].pid) { |
641 | svd[0].wstat = wstat; | ||
615 | svd[1].pid = 0; | 642 | svd[1].pid = 0; |
616 | pidchanged = 1; | 643 | pidchanged = 1; |
617 | svd[1].state = S_DOWN; | 644 | svd[1].state = S_DOWN; |