summaryrefslogtreecommitdiff
path: root/user/shell.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-03-27 11:39:12 -0400
committerFreya Murphy <freya@freyacat.org>2025-03-27 11:39:12 -0400
commit0ff301cda68669c59351e5854ce98f2cf460543f (patch)
treecfe8f976261962420ada64b821559b9da0a56841 /user/shell.c
parentadd compile_flags.txt for clangd lsp (diff)
downloadcomus-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.c221
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);
}