aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEarl Chew <earl_chew@agilent.com>2009-08-02 02:23:27 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-08-02 02:23:27 +0200
commit80a3418b8c96300826842f109cd297280d3fbe05 (patch)
tree6467801de1340e1354510fc3a0c45b6298dcfa0b
parentaebb742939d4100fbd1c7e94c68f9265e0805fd8 (diff)
downloadbusybox-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.c63
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
89struct globals { 90struct 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
141static char *add_str(char *p, const char *to_add) 142/* libbb candidate */
143static 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)
305static void startservice(struct svdir *s) 309static 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;