diff --git a/qa/kern/fork_chain.c b/qa/kern/fork_chain.c index 90ba6a3..8e28ebc 100644 --- a/qa/kern/fork_chain.c +++ b/qa/kern/fork_chain.c @@ -22,161 +22,72 @@ int r1; int r2; #define CHILD_READY(pid) ((long)rendezvous(&r1, (void*)(~(pid)))) -#define C2P_READY(pid) ((long)rendezvous(&r2, (void*)(~(pid)))) +//#define C2P_READY(pid) ((long)rendezvous(&r2, (void*)(~(pid)))) -int *__libposix_sigchld_target_pid; - -static void -release_inherited_resources(void) -{ - notify(nil); - rfork(RFCNAMEG|RFCENVG|RFNOTEG|RFCFDG); - bind("#p", "/proc", MREPL); - rfork(RFNOMNT); -} +int *__target_pid; static void forwarding_note_handler(void *ureg, char *note) { - postnote(PNPROC, *__libposix_sigchld_target_pid, note); - noted(NCONT); + postnote(PNPROC, *__target_pid, note); + noted(NDFLT); } static void -forward_wait_msg(int sigchld_receiver, char *name) +donothing(void) { - int n; - char buf[512], err[ERRMAX], note[512], *fld[5]; - - snprint(buf, sizeof(buf), "/proc/%d/args", getpid()); - n = open(buf, OWRITE); - write(n, name, strlen(name)+1); - close(n); - - n = 0; -WaitInterrupted: - n = await(buf, sizeof buf-1); - if(n < 0){ - rerrstr(err, ERRMAX); - if(strstr(err, "no living children") == nil) - goto WaitInterrupted; - snprint(note, sizeof(note), "%s: %r", name); - if(sigchld_receiver) - postnote(PNPROC, sigchld_receiver, note); - exits(note); - } - buf[n] = '\0'; - if(jehanne_tokenize(buf, fld, nelem(fld)) != nelem(fld)){ - snprint(note, sizeof(note), "%s: couldn't parse wait message", name); - if(sigchld_receiver) - postnote(PNPROC, sigchld_receiver, note); - exits(note); - } - snprint(note, sizeof(note), "posix: 20"); - if(sigchld_receiver){ - postnote(PNPROC, sigchld_receiver, note); - } - exits(fld[4]); + int i = 0; + while(i < 100) + sleep(3000); + exits(nil); } - static int -fork_with_sigchld(void) +crazy_fork(void) { int father = getpid(); int p2c; long c2p = -1, child = -1; - char proxy_name[256]; - /* Father here: - * - create P2C - * - wait for C2P to be ready - * - register P2C in children list - * - return P2C pid - */ switch(p2c = rfork(RFPROC|RFMEM)){ case -1: return -1; case 0: - /* P2C here: - * - create C2P - * - wait for the child pid - * - release all inherited resources - * - install forwarding_note_handler - * - send to father the C2P pid - * - start waiting for the child - */ switch(c2p = rfork(RFPROC|RFMEM)){ case -1: - while(C2P_READY(-2) == -1) - ; exits("rfork (c2p)"); case 0: - /* C2P here: - * - create child - * - wait for it to get a copy of everything - * - release all inherited resources - * - install forwarding_note_handler - * - send to P2C the child pid - * - start forwarding notes to the father - */ switch(child = fork()){ case -1: - while(CHILD_READY(-2) == -1) - ; exits("rfork (child)"); case 0: - /* Beloved child here - */ -// __libposix_setup_new_process(); return 0; default: - release_inherited_resources(); - *__libposix_sigchld_target_pid = father; - notify(forwarding_note_handler); - snprint(proxy_name, sizeof(proxy_name), "libposix signal proxy %d < %d", father, child); while(CHILD_READY(child) == -1) ; - forward_wait_msg(father, proxy_name); + *__target_pid = father; + notify(forwarding_note_handler); + donothing(); } default: while((child = CHILD_READY(-3)) == -1) ; child = ~child; - if(child < 0){ - while(C2P_READY(-2) == -1) - ; - waitpid(); - exits("rfork (child)"); - } - release_inherited_resources(); - *__libposix_sigchld_target_pid = child; + *__target_pid = child; notify(forwarding_note_handler); - snprint(proxy_name, sizeof(proxy_name), "libposix signal proxy %d > %d", father, child); - while(C2P_READY(c2p) == -1) - ; - forward_wait_msg(0, proxy_name); + donothing(); } default: - while((c2p = C2P_READY(-3)) == -1) - ; - c2p = ~c2p; - if(c2p < 0){ - waitpid(); - return -1; - } break; } - print("f %d; p2c %d, c2p %d\n", father, p2c, c2p); - return p2c; } int -passOnSIGCHLD(void *v, char *s) +pass_on_die(void *v, char *s) { - if(strncmp(s, "posix: 20", 4) == 0){ + if(strncmp(s, "die", 4) == 0){ print("PASS\n"); exits("PASS"); } @@ -187,28 +98,31 @@ void main(void) { int c, target_pid = 0; - __libposix_sigchld_target_pid = &target_pid; + __target_pid = &target_pid; - if (!atnotify(passOnSIGCHLD, 1)){ + if (!atnotify(pass_on_die, 1)){ fprint(2, "%r\n"); exits("atnotify fails"); } - c = fork_with_sigchld(); + c = crazy_fork(); switch(c){ case -1: print("FAIL: fork\n"); exits("FAIL"); case 0: + print("child is %d; child's parent is %d\n", getpid(), getppid()); + *__target_pid = getppid(); + notify(forwarding_note_handler); /* wait to be killed */ - print("child is %d\n", getpid()); -// for(;;); - sleep(30000); + donothing(); break; default: - print("father is %d\n", getpid()); + print("father is %d; forked child is %d\n", getpid(), c); + sleep(1000); /* give children time to notify() */ + print("starting note chain\n"); postnote(PNPROC, c, "die"); - /* wait to be killed */ + /* wait to be killed by the chain */ sleep(30000); } print("FAIL\n");