#include /** ** User function R: exit, sleep, write, fork, getpid, getppid, ** ** Reports itself and its sequence number, along with its PID and ** its parent's PID. It then delays, forks, delays, reports again, ** and exits. ** ** Invoked as: userR x n [ s ] ** where x is the ID character ** n is the sequence number of the initial incarnation ** s is the initial delay time (defaults to 10) */ USERMAIN(main) { char ch = 'r'; // default character to print int delay = 10; // initial delay count int seq = 99; // my sequence number char buf[128]; // process the command-line arguments switch (argc) { case 4: delay = str2int(argv[3], 10); // FALL THROUGH case 3: seq = str2int(argv[2], 10); // FALL THROUGH case 2: ch = argv[1][0]; break; default: sprint(buf, "userR: argc %d, args: ", argc); cwrites(buf); for (int i = 0; i <= argc; ++i) { sprint(buf, " %s", argv[argc] ? argv[argc] : "(null)"); cwrites(buf); } cwrites("\n"); } /* ** C oddity: a label cannot immediately precede a declaration. ** ** Declarations are not considered "statements" in C. Prior to ** C99, all declarations had to precede any statements inside a ** block. Labels can only appear before statements. C99 allowed ** the mixing of declarations and statements, but did not relax ** the requirement that labels precede only statements. ** ** That's why the declarations of these variables occur before the ** label, but their initializations occur after the label. ** ** As the PSA says on TV, "The more you know..." :-) */ int32_t pid; int32_t ppid; restart: // announce our presence pid = getpid(); ppid = getppid(); sprint(buf, " %c[%d,%d,%d]", ch, seq, pid, ppid); swrites(buf); sleep(SEC_TO_MS(delay)); // create the next child in sequence if (seq < 5) { ++seq; int32_t n = fork(); switch (n) { case -1: // failure? sprint(buf, "** R[%d] fork code %d\n", pid, n); cwrites(buf); break; case 0: // child goto restart; default: // parent --seq; sleep(SEC_TO_MS(delay)); } } // final report - PPID may change, but PID and seq shouldn't pid = getpid(); ppid = getppid(); sprint(buf, " %c[%d,%d,%d]", ch, seq, pid, ppid); swrites(buf); exit(0); return (42); // shut the compiler up! }