From ceb9471fed96f907e37a6ba031825c31167a8ff4 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Mon, 21 Apr 2025 16:45:28 -0400 Subject: update userland to compile --- user/shell.c | 346 ----------------------------------------------------------- 1 file changed, 346 deletions(-) delete mode 100644 user/shell.c (limited to 'user/shell.c') diff --git a/user/shell.c b/user/shell.c deleted file mode 100644 index f8c13cd..0000000 --- a/user/shell.c +++ /dev/null @@ -1,346 +0,0 @@ -#include - -// should we keep going? -static bool_t time_to_stop = false; - -// number of spawned but uncollected children -static int children = 0; - -/* -** For the test programs in the baseline system, command-line arguments -** follow these rules. The first two entries are as follows: -** -** argv[0] the name used to "invoke" this process -** argv[1] the "character to print" (identifies the process) -** -** Most user programs have one or more additional arguments. -** -** See the comment at the beginning of each user-code source file for -** information on the argument list that code expects. -*/ - -/* -** "Spawn table" process entry. Similar to that in init.c, -** except this one has no place to store the PID of the child. -*/ -typedef struct proc_s { - uint_t index; // process table index - int8_t prio; // process priority - char select[3]; // identifying character, NUL, extra - char *args[N_ARGS]; // argument vector strings -} proc_t; - -/* -** Create a spawn table entry for a process with a string literal -** as its argument buffer. We rely on the fact that the C standard -** ensures our array of pointers will be filled out with NULLs -*/ -#define PROCENT(e, p, s, ...) \ - { \ - e, p, s, \ - { \ - __VA_ARGS__, NULL \ - } \ - } - -// sentinel value for the end of the table - must be updated -// if you have more than 90,210 user programs in the table -#define TBLEND 90210 - -/* -** The spawn table contains entries for processes that are started -** by the shell. -*/ -static proc_t spawn_table[] = { - -// Users A-C each run ProgABC, which loops printing its character -#if defined(SPAWN_A) - PROCENT(ProgABC, PRIO_STD, "A", "userA", "A", "30"), -#endif -#if defined(SPAWN_B) - PROCENT(ProgABC, PRIO_STD, "B", "userB", "B", "30"), -#endif -#if defined(SPAWN_C) - PROCENT(ProgABC, PRIO_STD, "C", "userC", "C", "30"), -#endif - -// Users D and E run ProgDE, which is like ProgABC but doesn't exit() -#if defined(SPAWN_D) - PROCENT(ProgDE, PRIO_STD, "D", "userD", "D", "20"), -#endif -#if defined(SPAWN_E) - PROCENT(ProgDE, PRIO_STD, "E", "userE", "E", "20"), -#endif - -// Users F and G run ProgFG, which sleeps between write() calls -#if defined(SPAWN_F) - PROCENT(ProgFG, PRIO_STD, "F", "userF", "F", "20"), -#endif -#if defined(SPAWN_G) - PROCENT(ProgFG, PRIO_STD, "G", "userG", "G", "10"), -#endif - -// User H tests reparenting of orphaned children -#if defined(SPAWN_H) - PROCENT(ProgH, PRIO_STD, "H", "userH", "H", "4"), -#endif - -// User I spawns several children, kills one, and waits for all -#if defined(SPAWN_I) - PROCENT(ProgI, PRIO_STD, "I", "userI", "I"), -#endif - -// User J tries to spawn 2 * N_PROCS children -#if defined(SPAWN_J) - PROCENT(ProgJ, PRIO_STD, "J", "userJ", "J"), -#endif - -// Users K and L iterate spawning userX and sleeping -#if defined(SPAWN_K) - PROCENT(ProgKL, PRIO_STD, "K", "userK", "K", "8"), -#endif -#if defined(SPAWN_L) - PROCENT(ProgKL, PRIO_STD, "L", "userL", "L", "5"), -#endif - -// Users M and N spawn copies of userW and userZ via ProgMN -#if defined(SPAWN_M) - PROCENT(ProgMN, PRIO_STD, "M", "userM", "M", "5", "f"), -#endif -#if defined(SPAWN_N) - PROCENT(ProgMN, PRIO_STD, "N", "userN", "N", "5", "t"), -#endif - -// There is no user O - -// User P iterates, reporting system time and stats, and sleeping -#if defined(SPAWN_P) - PROCENT(ProgP, PRIO_STD, "P", "userP", "P", "3", "2"), -#endif - -// User Q tries to execute a bad system call -#if defined(SPAWN_Q) - PROCENT(ProgQ, PRIO_STD, "Q", "userQ", "Q"), -#endif - -// User R reports its PID, PPID, and sequence number; it -// calls fork() but not exec(), with each child getting the -// next sequence number, to a total of five copies -#if defined(SPAWN_R) - PROCENT(ProgR, PRIO_STD, "R", "userR", "R", "20", "1"), -#endif - -// User S loops forever, sleeping 13 sec. on each iteration -#if defined(SPAWN_S) - PROCENT(ProgS, PRIO_STD, "S", "userS", "S", "13"), -#endif - -// Users T-V run ProgTUV(); they spawn copies of userW -// User T waits for any child -// User U waits for each child by PID -// User V kills each child -#if defined(SPAWN_T) - PROCENT(ProgTUV, PRIO_STD, "T", "userT", "T", "6", "w"), -#endif -#if defined(SPAWN_U) - PROCENT(ProgTUV, PRIO_STD, "U", "userU", "U", "6", "W"), -#endif -#if defined(SPAWN_V) - PROCENT(ProgTUV, PRIO_STD, "V", "userV", "V", "6", "k"), -#endif - - // a dummy entry to use as a sentinel - { TBLEND } - - // these processes are spawned by the ones above, and are never - // spawned directly. - - // PROCENT( ProgW, PRIO_STD, "?", "userW", "W", "20", "3" ), - // PROCENT( ProgX, PRIO_STD, "?", "userX", "X", "20" ), - // PROCENT( ProgY, PRIO_STD, "?", "userY", "Y", "10" ), - // PROCENT( ProgZ, PRIO_STD, "?", "userZ", "Z", "10" ) -}; - -/* -** usage function -*/ -static void usage(void) -{ - swrites("\nTests - run with '@x', where 'x' is one or more of:\n "); - proc_t *p = spawn_table; - while (p->index != TBLEND) { - swritech(' '); - swritech(p->select[0]); - } - swrites("\nOther commands: @* (all), @h (help), @x (exit)\n"); -} - -/* -** run a program from the program table, or a builtin command -*/ -static int run(char which) -{ - char buf[128]; - register proc_t *p; - - if (which == 'h') { - // builtin "help" command - usage(); - - } else if (which == 'x') { - // builtin "exit" command - time_to_stop = true; - - } else if (which == '*') { - // torture test! run everything! - for (p = spawn_table; p->index != TBLEND; ++p) { - int status = spawn(p->index, p->args); - if (status > 0) { - ++children; - } - } - - } else { - // must be a single test; find and run it - for (p = spawn_table; p->index != TBLEND; ++p) { - if (p->select[0] == which) { - // found it! - int status = spawn(p->index, p->args); - if (status > 0) { - ++children; - } - return status; - } - } - - // uh-oh, made it through the table without finding the program - sprint(buf, "shell: unknown cmd '%c'\n", which); - swrites(buf); - usage(); - } - - return 0; -} - -/** -** edit - perform any command-line editing we need to do -** -** @param line Input line buffer -** @param n Number of valid bytes in the buffer -*/ -static int edit(char line[], int n) -{ - char *ptr = line + n - 1; // last char in buffer - - // strip the EOLN sequence - while (n > 0) { - if (*ptr == '\n' || *ptr == '\r') { - --n; - } else { - break; - } - } - - // add a trailing NUL byte - if (n > 0) { - line[n] = '\0'; - } - - return n; -} - -/** -** shell - extremely simple shell for spawning test programs -** -** Scheduled by _kshell() when the character 'u' is typed on -** the console keyboard. -*/ -USERMAIN(main) -{ - // keep the compiler happy - (void)argc; - (void)argv; - - // report that we're up and running - swrites("Shell is ready\n"); - - // print a summary of the commands we'll accept - usage(); - - // loop forever - while (!time_to_stop) { - char line[128]; - char *ptr; - - // the shell reads one line from the keyboard, parses it, - // and performs whatever command it requests. - - swrites("\n> "); - int n = read(CHAN_SIO, line, sizeof(line)); - - // shortest valid command is "@?", so must have 3+ chars here - if (n < 3) { - // ignore it - continue; - } - - // edit it as needed; new shortest command is 2+ chars - if ((n = edit(line, n)) < 2) { - continue; - } - - // find the '@' - int i = 0; - for (ptr = line; i < n; ++i, ++ptr) { - if (*ptr == '@') { - break; - } - } - - // did we find an '@'? - if (i < n) { - // yes; process any commands that follow it - ++ptr; - - for (; *ptr != '\0'; ++ptr) { - char buf[128]; - int pid = run(*ptr); - - if (pid < 0) { - // spawn() failed - sprint(buf, "+++ Shell spawn %c failed, code %d\n", *ptr, - pid); - cwrites(buf); - } - - // should we end it all? - if (time_to_stop) { - break; - } - } // for - - // now, wait for all the spawned children - while (children > 0) { - // wait for the child - int32_t status; - char buf[128]; - int whom = waitpid(0, &status); - - // figure out the result - if (whom == E_NO_CHILDREN) { - break; - } else if (whom < 1) { - sprint(buf, "shell: waitpid() returned %d\n", whom); - } else { - --children; - sprint(buf, "shell: PID %d exit status %d\n", whom, status); - } - // report it - swrites(buf); - } - } // if i < n - } // while - - cwrites("!!! shell exited loop???\n"); - exit(1); -} -- cgit v1.2.3-freya