int getCommandLine( char *buf, int max );This code should not need to be changed from what you wrote for Assignment 4.
subcommand_t* getSubcommands( char *buf );You might not need to change your code for Assignment 4 for this function. But whereas you were required only to handle simple command lines in the previous assignment, this assignment will test whether you actually can handle multiple commands separated by semicolons correctly. Handling an ampersand at the end of a command line will be tested if you mention it in your man page, but is not required. Be sure to test all kinds of quoting as mentioned in Assignment 4. If there are any limitations on what your code handles properly here, be sure to list them in the BUGS section of your man page.
token_t *tokenize( const subcommand_t *cmd );Your tokenize function should handle quotes and I/O redirection operators correctly for this assignment. (These features were not tested for Assignment 4.) There should be no need to surround redirection operators with spaces. Thus the strings ">out" and "> out" are equivalent. Either one should both result in a single token_t node with the token member pointing to "out" and the tag member equal to T_redirect_out.
char *expandToken( const char *token )The $? token should be handled properly in this Assignment. In addition, you may optionally include support for $$ (the shell's process id).
int executeCommand( subcommand_t *cmd );For this assignment, you are to handle builtin commands using a dispatch table as outlined in class.
Use this prototype for all builtin functions:
typedef int builtin_t( int, char **, char ** );Then you can use this struct for the dispatch table entries:
struct dispatch_t { const char *const cmdName; builtin_t *function; bool canFork; };The purpose of the canFork member of the struct is to mark whether it is all right to fork a separate process to execute the builtin command or not. The cd and exit builtin commands must not execute in separate processes because they have to modify ouch's process. But other builtins can be executed in separate processes, and will have to if their input or output streams are redirected.
Command Name | Function | Can Fork? |
---|---|---|
exit | doExit() | No |
quit | doExit() | No |
doPrint() | Yes | |
cd | doCd() | No |
(Thought question: What would be a better way to have two different names for the same command, as accomplished by the first two entries in the above table?)
Optional: Study Chapter 10 of the Stevens book and modify ouch so it does not exit if the user types Control-C. Be sure this feature works correctly whether the user has started typing a command line when s/he types Control-C or not.
Code this function so that it's own result code is equal to the number of command line arguments it prints.
Sample output:
ouch> date; print The value of '$?' is $? Mon Dec 10 19:22:36 EST 2001 The value of $? is 0 ouch> print "Previous result code was: " $? Previous result code was: 6 ouch>
if ( stdinRedir_fd != -1 ) { dup2( stdinRedir_fd, 0 ); close( stdinRedir_fd ); }Here are the flags to use for opening the three types of output redirection. In all cases, the mode value (the third argument passed to open()) should be 0666. (Remember that the 0 means octal.)
T_redirect_out | O_WRONLY | O_CREAT | O_EXCL |
T_redirect_append | O_WRONLY | O_APPEND |
T_redirect_clobber | O_WRONLY | O_CREAT | O_TRUNC |
ouch.1
, which is to be under RCS management (with a
revision number of 3.x) just like the other files you wrote for this
assignment. You may optinally have man and man/man1 subdirectories in
your project directory, and you may include an "install" target for
your man page that installs it there.Your man page will be graded on grammatical correctness and meaningfulness of content in addition to proper formatting, as described in the man pages document listed in the course schedule.