16a17,22 > void eval_bg(int nwords, char *xword[]); > void eval_builtin(int nwords, char *xword[]); > void eval_echo(char *xword[]); > void eval_quit(char *xword[]); > void eval_nonbuiltin(int nwords, char *xword[]); > void eval_wait(char *xword[]); 17a24 > void init (void); 19a27,33 > > struct ltstr { > bool operator()(const char *s1, const char *s2) const { > return strcmp(s1, s2) < 0; > } > }; > 23a38 > { "foo", 0}, 29a45 > { "ps", "-l", 0}, 34a51,54 > pid_t bg_pid; // $! (internal format) > char bg_pid_str[10]; // $! (string format) > Bool is_done = NO; // set to YES by quit command > int quit_status; // exit status of shell (quit arg) 52a73,77 > static inline Bool is_bg(int nwords, char *xword[]) { // YES if bg command > if (strcmp(xword[0], "&") == 0) return YES; > else return NO; > } > 60a86,90 > static inline Bool > is_defined(char *name) { // YES if var name is "!" > return ( ( (strcmp(name, "!") == 0) ) ? YES : NO ); > } > 67d96 < 78c107 < for (int i=0; cmnd[i][0] != NULL; i++) { --- > for (int i=0; (cmnd[i][0] != NULL) && (!is_done); i++) { 80a110,111 > if( debug ) fprintf(stderr, "========================== %s\n", cmnd[i][0] ); > for (int j=0; cmnd[i][j] != 0; j++) ++nwords; 92c123 < // ... eval builtin command ... --- > eval_builtin(nwords, xword); 95c126,127 < // ... eval non-builtin command --- > if (is_bg(nwords, xword)) eval_bg(nwords, xword); > else eval_nonbuiltin(nwords, xword); 101c133 < return 0; --- > return quit_status; 105d136 < // --| Get command-line args |-- 131d161 < 142a173 > char *var_name; 144,145c175,183 < DEBUG( (stderr, "\t\t+++ do_subst: word %d is variable %s\n", < i, word[i]) ); --- > var_name = &(word[i][1]); > if (is_defined(var_name)) { // lookup value > DEBUG( (stderr, "\t\t+++ do_subst: %s = <%s>\n", > var_name, bg_pid_str) ); > xword[i] = strdup(bg_pid_str); > } else { // undefined var = "" > DEBUG( (stderr, "\t\t+++ do_subst: %s = UNDEF\n", var_name) ); > xword[i] = strdup(""); > } 148a187 > xword[i] = strdup(word[i]); 150d188 < xword[i] = strdup(word[i]); 172a211,303 > // --| evaluate non-builtin commands |-- > void > eval_nonbuiltin(int nwords, char *xword[]) { > pid_t pid; > int status; > > DEBUG( (stderr, "*** eval_nonbuiltin called with: ") ); > DebugWords(xword); > > pid = Fork(); > if( debug ) fprintf( stderr, "*** Syscall from pid %d: Fork returned %d\n", > getpid(), pid ); > if (pid == 0) { // child > Execvp(xword[0], xword); > exit(1); > } else { > DEBUG( (stderr, "*** eval_nonbuiltin: child pid = %d\n", pid) ); > Waitpid(pid, &status, 0); > } > } > > // --| evaluate backgrounded command |-- > void > eval_bg(int nwords, char *xword[]) { > int status; > > DEBUG( (stderr, "\t\t+++ eval_bg called\n") ); > DebugWords(xword); > > bg_pid = Fork(); > if( debug ) fprintf( stderr, "*** Syscall from pid %d: Fork returned %d\n", > getpid(), bg_pid ); > if (bg_pid == 0) { // child > Execvp(xword[1], &xword[1]); > exit(1); > } > sprintf(bg_pid_str, "%d", bg_pid); > > DEBUG( (stderr, "*** eval_bg: child pid = %d (str: %s)\n", > bg_pid, bg_pid_str) ); > } > > // --| evaluate builtin commands |-- > > void > eval_builtin(int nwords, char *xword[]) { > DEBUG( (stderr, "*** eval_builtin called with: ") ); > DebugWords(xword); > > if (strcmp(xword[0], "quit") == 0) { > eval_quit(xword); > is_done = YES; > } else if (strcmp(xword[0], "echo") == 0) eval_echo(xword); > else if (strcmp(xword[0], "wait") == 0) eval_wait(xword); > else { > // nothing for now > } > } > > void > eval_echo(char *xword[]) { // --| echo W ... |-- > DEBUG( (stderr, "*** eval_echo called with: ") ); > DebugWords(xword); > show_words(&(xword[1])); > } > > void > eval_quit(char *xword[]) { // --| quit; quit W |-- > DEBUG( (stderr, "*** eval_quit called with: ") ); > DebugWords(xword); > > if (xword[1] != NULL) quit_status = atoi(xword[1]); > else quit_status = 0; > } > > void > eval_wait(char *xword[]) { // --| wait W |-- > int status; > pid_t pid = atoi(xword[1]); > int rc; > > DEBUG( (stderr, "*** eval_wait called with: ") ); > DebugWords(xword); > > rc = waitpid(pid, &status, 0); > if (rc != pid) { // bad pid > fprintf(stderr, "*** eval_wait: waitpid(%d,...) returned %d\n", pid, rc); > exit(1); > } else if( debug ) { > fprintf(stderr, "*** eval_wait: waitpid(%d,...) returned %d\n", pid, rc); > } > } >