diff options
author | Freya Murphy <freya@freyacat.org> | 2025-03-27 11:39:12 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-03-27 11:39:12 -0400 |
commit | 0ff301cda68669c59351e5854ce98f2cf460543f (patch) | |
tree | cfe8f976261962420ada64b821559b9da0a56841 /user/shell.c | |
parent | add compile_flags.txt for clangd lsp (diff) | |
download | comus-0ff301cda68669c59351e5854ce98f2cf460543f.tar.gz comus-0ff301cda68669c59351e5854ce98f2cf460543f.tar.bz2 comus-0ff301cda68669c59351e5854ce98f2cf460543f.zip |
pull upstream changes, add auto formatting
Diffstat (limited to 'user/shell.c')
-rw-r--r-- | user/shell.c | 221 |
1 files changed, 112 insertions, 109 deletions
diff --git a/user/shell.c b/user/shell.c index 5412033..628e9b7 100644 --- a/user/shell.c +++ b/user/shell.c @@ -24,10 +24,10 @@ static int children = 0; ** 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[MAX_ARGS]; // argument vector strings + uint_t index; // process table index + int8_t prio; // process priority + char select[3]; // identifying character, NUL, extra + char *args[MAX_ARGS]; // argument vector strings } proc_t; /* @@ -35,11 +35,17 @@ typedef struct proc_s { ** 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 } } +#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 +#define TBLEND 90210 /* ** The spawn table contains entries for processes that are started @@ -47,102 +53,102 @@ typedef struct proc_s { */ static proc_t spawn_table[] = { - // Users A-C each run ProgABC, which loops printing its character +// Users A-C each run ProgABC, which loops printing its character #if defined(SPAWN_A) - PROCENT( ProgABC, PRIO_STD, "A", "userA", "A", "30" ), + PROCENT(ProgABC, PRIO_STD, "A", "userA", "A", "30"), #endif #if defined(SPAWN_B) - PROCENT( ProgABC, PRIO_STD, "B", "userB", "B", "30" ), + PROCENT(ProgABC, PRIO_STD, "B", "userB", "B", "30"), #endif #if defined(SPAWN_C) - PROCENT( ProgABC, PRIO_STD, "C", "userC", "C", "30" ), + PROCENT(ProgABC, PRIO_STD, "C", "userC", "C", "30"), #endif - // Users D and E run ProgDE, which is like ProgABC but doesn't exit() +// 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" ), + PROCENT(ProgDE, PRIO_STD, "D", "userD", "D", "20"), #endif #if defined(SPAWN_E) - PROCENT( ProgDE, PRIO_STD, "E", "userE", "E", "20" ), + PROCENT(ProgDE, PRIO_STD, "E", "userE", "E", "20"), #endif - // Users F and G run ProgFG, which sleeps between write() calls +// Users F and G run ProgFG, which sleeps between write() calls #if defined(SPAWN_F) - PROCENT( ProgFG, PRIO_STD, "F", "userF", "F", "20" ), + PROCENT(ProgFG, PRIO_STD, "F", "userF", "F", "20"), #endif #if defined(SPAWN_G) - PROCENT( ProgFG, PRIO_STD, "G", "userG", "G", "10" ), + PROCENT(ProgFG, PRIO_STD, "G", "userG", "G", "10"), #endif - // User H tests reparenting of orphaned children +// User H tests reparenting of orphaned children #if defined(SPAWN_H) - PROCENT( ProgH, PRIO_STD, "H", "userH", "H", "4" ), + PROCENT(ProgH, PRIO_STD, "H", "userH", "H", "4"), #endif - // User I spawns several children, kills one, and waits for all +// User I spawns several children, kills one, and waits for all #if defined(SPAWN_I) - PROCENT( ProgI, PRIO_STD, "I", "userI", "I" ), + PROCENT(ProgI, PRIO_STD, "I", "userI", "I"), #endif - // User J tries to spawn 2 * N_PROCS children +// User J tries to spawn 2 * N_PROCS children #if defined(SPAWN_J) - PROCENT( ProgJ, PRIO_STD, "J", "userJ", "J" ), + PROCENT(ProgJ, PRIO_STD, "J", "userJ", "J"), #endif - // Users K and L iterate spawning userX and sleeping +// Users K and L iterate spawning userX and sleeping #if defined(SPAWN_K) - PROCENT( ProgKL, PRIO_STD, "K", "userK", "K", "8" ), + PROCENT(ProgKL, PRIO_STD, "K", "userK", "K", "8"), #endif #if defined(SPAWN_L) - PROCENT( ProgKL, PRIO_STD, "L", "userL", "L", "5" ), + PROCENT(ProgKL, PRIO_STD, "L", "userL", "L", "5"), #endif - // Users M and N spawn copies of userW and userZ via ProgMN +// 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" ), + PROCENT(ProgMN, PRIO_STD, "M", "userM", "M", "5", "f"), #endif #if defined(SPAWN_N) - PROCENT( ProgMN, PRIO_STD, "N", "userN", "N", "5", "t" ), + PROCENT(ProgMN, PRIO_STD, "N", "userN", "N", "5", "t"), #endif - // There is no user O +// There is no user O - // User P iterates, reporting system time and stats, and sleeping +// User P iterates, reporting system time and stats, and sleeping #if defined(SPAWN_P) - PROCENT( ProgP, PRIO_STD, "P", "userP", "P", "3", "2" ), + PROCENT(ProgP, PRIO_STD, "P", "userP", "P", "3", "2"), #endif - // User Q tries to execute a bad system call +// User Q tries to execute a bad system call #if defined(SPAWN_Q) - PROCENT( ProgQ, PRIO_STD, "Q", "userQ", "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 +// 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" ), + PROCENT(ProgR, PRIO_STD, "R", "userR", "R", "20", "1"), #endif - // User S loops forever, sleeping 13 sec. on each iteration +// User S loops forever, sleeping 13 sec. on each iteration #if defined(SPAWN_S) - PROCENT( ProgS, PRIO_STD, "S", "userS", "S", "13" ), + 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 +// 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" ), + PROCENT(ProgTUV, PRIO_STD, "T", "userT", "T", "6", "w"), #endif #if defined(SPAWN_U) - PROCENT( ProgTUV, PRIO_STD, "U", "userU", "U", "6", "W" ), + PROCENT(ProgTUV, PRIO_STD, "U", "userU", "U", "6", "W"), #endif #if defined(SPAWN_V) - PROCENT( ProgTUV, PRIO_STD, "V", "userV", "V", "6", "k" ), + PROCENT(ProgTUV, PRIO_STD, "V", "userV", "V", "6", "k"), #endif - + // a dummy entry to use as a sentinel { TBLEND } @@ -158,51 +164,49 @@ static proc_t spawn_table[] = { /* ** usage function */ -static void usage( void ) { - swrites( "\nTests - run with '@x', where 'x' is one or more of:\n " ); +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] ); + while (p->index != TBLEND) { + swritech(' '); + swritech(p->select[0]); } - swrites( "\nOther commands: @* (all), @h (help), @x (exit)\n" ); + 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 ) { +static int run(char which) +{ char buf[128]; register proc_t *p; - if( which == 'h' ) { - + if (which == 'h') { // builtin "help" command usage(); - } else if( which == 'x' ) { - + } else if (which == 'x') { // builtin "exit" command time_to_stop = true; - } else if( which == '*' ) { - + } 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 ) { + 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 ) { + 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 ) { + int status = spawn(p->index, p->args); + if (status > 0) { ++children; } return status; @@ -210,8 +214,8 @@ static int run( char which ) { } // uh-oh, made it through the table without finding the program - sprint( buf, "shell: unknown cmd '%c'\n", which ); - swrites( buf ); + sprint(buf, "shell: unknown cmd '%c'\n", which); + swrites(buf); usage(); } @@ -224,12 +228,13 @@ static int run( char which ) { ** @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 +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' ) { + while (n > 0) { + if (*ptr == '\n' || *ptr == '\r') { --n; } else { break; @@ -237,7 +242,7 @@ static int edit( char line[], int n ) { } // add a trailing NUL byte - if( n > 0 ) { + if (n > 0) { line[n] = '\0'; } @@ -250,94 +255,92 @@ static int edit( char line[], int n ) { ** Scheduled by _kshell() when the character 'u' is typed on ** the console keyboard. */ -USERMAIN( main ) { - +USERMAIN(main) +{ // keep the compiler happy - (void) argc; - (void) argv; + (void)argc; + (void)argv; // report that we're up and running - swrites( "Shell is ready\n" ); + swrites("Shell is ready\n"); // print a summary of the commands we'll accept usage(); // loop forever - while( !time_to_stop ) { + 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) ); - + swrites("\n> "); + int n = read(CHAN_SIO, line, sizeof(line)); + // shortest valid command is "@?", so must have 3+ chars here - if( n < 3 ) { + if (n < 3) { // ignore it continue; } // edit it as needed; new shortest command is 2+ chars - if( (n=edit(line,n)) < 2 ) { + if ((n = edit(line, n)) < 2) { continue; } // find the '@' int i = 0; - for( ptr = line; i < n; ++i, ++ptr ) { - if( *ptr == '@' ) { + for (ptr = line; i < n; ++i, ++ptr) { + if (*ptr == '@') { break; } } // did we find an '@'? - if( i < n ) { - + if (i < n) { // yes; process any commands that follow it ++ptr; - for( ; *ptr != '\0'; ++ptr ) { + for (; *ptr != '\0'; ++ptr) { char buf[128]; - int pid = run( *ptr ); + int pid = run(*ptr); - if( pid < 0 ) { + if (pid < 0) { // spawn() failed - sprint( buf, "+++ Shell spawn %c failed, code %d\n", - *ptr, pid ); - cwrites( buf ); + sprint(buf, "+++ Shell spawn %c failed, code %d\n", *ptr, + pid); + cwrites(buf); } // should we end it all? - if( time_to_stop ) { + if (time_to_stop) { break; } } // for // now, wait for all the spawned children - while( children > 0 ) { + while (children > 0) { // wait for the child int32_t status; char buf[128]; - int whom = waitpid( 0, &status ); + int whom = waitpid(0, &status); // figure out the result - if( whom == E_NO_CHILDREN ) { + if (whom == E_NO_CHILDREN) { break; - } else if( whom < 1 ) { - sprint( buf, "shell: waitpid() returned %d\n", whom ); + } 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 ); + sprint(buf, "shell: PID %d exit status %d\n", whom, status); } // report it - swrites( buf ); + swrites(buf); } - } // if i < n - } // while + } // if i < n + } // while - cwrites( "!!! shell exited loop???\n" ); - exit( 1 ); + cwrites("!!! shell exited loop???\n"); + exit(1); } |