HOMEWORK 4 (COMMENTS AND COMMON MISTAKES) o Many students gave no explanation for whether their output was correct or not. o "$!" is the PID of the latest backgrounded process; i.e., the value returned from Fork() to the parent when evaluating a command to be run in the background. o There is no requirement that you have to use a function map to implement recognition of builtin commands. Some approaches are: Approach 1 (Used in HW 4 solution): - Bool is_builtin(char *cmnd): Returns YES if cmnd is builtin Uses array of builtin command names "char *builtin[]". - void eval_builtin(int nwords, char *xword[]): Evaluates builtin commands Criticism of Approach: - is_builtin() and eval_builtin() are NOT integrated: + is_builtin() uses builtin[] array but eval_builtin() doesn't Approach 2 (Improvement to Approach 1): - Might be better to have a lookup function that mapped each builtin commands to a unique integer which could then be used by eval_builtin() in a switch statement. - Something like: enum BuiltinOp { ECHO, QUIT, WAIT, SET }; char *builtin[] = { "echo", "quit", "wait", "set", 0}; static inline int get_builtin(char *cmnd) { for (int i=0; builtin[i] != NULL; i++) { if (strcmp(builtin[i], cmnd) == 0) return i; } return -1; } void eval_builtin(int op, int nwords, char *xword[]) { switch (op) { case ECHO: ... case QUIT: ... case WAIT: ... case SET: ... default: ... shouldn't happen ... } } Approach 3 (Function Map): - See test28f.C. typedef void (*func_t)(char *[]); map eval; // functions ... (*(eval[xword[0]]))(xword); // call eval builtin