kern/user/progR.c

102 lines
2.3 KiB
C

#include <common.h>
/**
** 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!
}