//--ENTRY POINT-- int main (int argc, char *argv[]) { if (argc!=2) { fprintf(stderr, "Invalild number of arguments.\n"); return 1; } node_type *root; root=get_tree_from_file(argv[1]); pid_t FIRST; int status; FIRST=fork(); if (FIRST<0) { fork_err(getpid()); exit(EXIT_FAILURE); } if (FIRST==0) { //Process Tree R00T: create_ptree(root, 0); exit(EXIT_SUCCESS); } else { //MAIN: wait_for_ready_children(1); //All children are in slumber! show_pstree(FIRST); kill(FIRST, SIGCONT); if ((wait(&status))==-1) { sign_err(FIRST, "main"); exit(EXIT_FAILURE); } else { explain_wait_status(FIRST, status); } } return 0; }
int main (void) { char c; pid_t pid; pid = fork_err(); if (pid != 0) { exit(0); } setsid_err(); pid = fork_err(); if (pid != 0) { pause(); } setpgid_err(0, 0); pid = fork_err(); if (pid == 0) { while (1) { pause(); } } kill_err(pid, SIGSTOP); int i = 0; for (i = 0; i < 3; ++i) { fork_err(); } while(1) { pause(); } return 0; }
//--FUNCTIONS-- void create_ptree(node_type *cur, size_t lvl) { int status; pid_t *CHILDREN=NULL; //Children PID array. if (cur->nr_children>0) { //Allocation of children PID array memory. CHILDREN=(pid_t *)malloc((cur->nr_children)*sizeof(pid_t)); if (CHILDREN==NULL) { alloc_err; exit(EXIT_FAILURE); } } pid_t par=getpid(), child=0, retv=0; change_pname(cur->name); //Change name. // proc_enter(par); //Enter message. size_t i=0; for (i=0; i<cur->nr_children; i++) { //Create heirs. // fprintf(stderr, "FORK LV: %u - IT: %u\n", lvl, i); //DEBUG child=fork(); if (child<0) { //Sanity. fork_err(cur); exit(EXIT_FAILURE); } if (child==0) { //Recursion for child: create_ptree(&cur->children[i], lvl+1); //... } else { //Rest of parent: CHILDREN[i]=child; continue; } } if (cur->nr_children>0) { //Node: //Wait for heirs to sleep. wait_for_ready_children(cur->nr_children); } //else //Leaf: Fall-through. if (raise(SIGSTOP)) { //Sleep yourself. sign_err(par, "0"); exit(EXIT_FAILURE); } actual_msg(par, cur->name); //Wake-up and print awake message. // fprintf(stderr, "i=%u, child=%ld, CHILDREN[i]=%ld\n", i, (long)child, (long)CHILDREN[i]); if (cur->nr_children>0) { for (i=0; i<cur->nr_children; i++) {//Parents continue and bury their children 1 by 1. cont_msg(cur->name, CHILDREN[i]); if ((kill(CHILDREN[i], SIGCONT))==-1) { sign_err(par, "1"); exit(EXIT_FAILURE); } // wait_for_ready_children(1); //NEEDs DEBUGGING: Doesn't work with this instead of the 2 next commands. retv=wait(&status); //Wait the just awoken child to terminate before you wake up the next (condition for the depth first traversal). bury_msg(cur->name, retv); //Bury message. } } //else //Fall-through. // proc_exit(par); //Exit message. // kill(par, SIGKILL); exit(EXIT_SUCCESS); //Children and parents who buried theirs, just roll off and die. }