This page lists all official clarifications for lab 1:

Use #if 0 ... #endif around main(..) in cmdline.c

As a reminder from discussion, you will need to comment out the main(..) routine in cmdline.c. An easy way to do this is surround the definition with #if 0 and #endif:

#if 0
int
main(int argc, char *argv[])
{
...
}
#endif

The distributed patch file will apply this change for you.

BACKGROUND '&' symbol may end a command line

The last command on a command line may be terminated with controlop END or BACKGROUND. For the function command_print(..) in cmdline.c, the following assertion has been modified in the patch to clarify this:

assert((cmd->controlop == END) == (cmd->next == NULL));

is now:

assert((cmd->controlop == END) == (cmd->next == NULL) ||
(cmd->controlop == BACKGROUND) == (cmd->next == NULL));

Please apply the patch to make the change.

Output redirection with invalid commands

The lab specs INCORRECTLY say "Only open a file for output redirection if the command is valid and going to be executed." The output file SHOULD exist afterwards, because you need to create the file before you know that the command is invalid. You may choose to implement the original spec on this by doing some cleanup after exec fails (hint: delete the file). Make sure you document how you've chosen to handle this case in your README.

The same rules apply for redirecting stderr.

Redirecting stdin, stdout, AND stderr is required

The lab handout does not mention it explicitly, but as was mentioned in discussion, you are also required to implement redirecting stderr, denoted with the symbol "2>". For those who implemented the optional exercise in word_parse, you may notice a potential ambituity here. Namely, consider the case:

$echo foo2>file

Does the 2 go with "foo" or ">"? In this case, the command should be parsed as "echo foo2 > file". Note this only affects those who implemented the optional part of word_parse.

command_print's use of ">&" for redirect_stderr is a bug, it should say "2>". Shells like bash use ">& F" to redirect BOTH stdout and stderr to file F. We want to be able to redirect stderr individually, so we use "2>" (like bash does).

See the suggested additions page for more redirection possibilities.

Patterns to match will contain at most one '*' character

Patterns will contain no more than one '*' character. So, commands such as:

$ls *.txt
$ls *.txt | cat file*.txt

are legal, and must be handled, but commands like:

$ls file*.*

are not legal. Of course, you can implement handling more than one '*' if you like, but it is not required as part of the challenge problem.

Handling 'zombie' processes

People have asked about the comments in the code related to 'zombie' processes. A zombie process is a process that has completed execution but the exit status has not been read by the parent process yet (e.g. the parent process has not done a wait for the given process). See '$man ps' for more about zombie processes.

So, now you may ask, how do I clean up these zombie processes? Well, in some other parts of the code we make the system call waitpid(pid, &rc, 0), and your shell BLOCKS until the process you're waiting for (the process whose pid is 'pid') completes. What is the key reason you can't use the same parameters to waitpid when you're cleaning up zombie processes? (Hint: do you know the pid?)

You'll want to find a way to clean up zombie processes regularly (if any exist), and to NOT BLOCK the shell otherwise. Once you figure out what's the right flavor of wait function and the appropriate parameters, you should figure out where it's best to put the call so that it's invoked regularly.

Related to wait calls is the question "How do I get the exit code of a process?" Again, in the man page for wait, you'll find various macros such as WIFEXITED(int status), which returns TRUE if the status in question was from a process that exited normally. You can look at the rest of the macros to see which ones will make your job easiest.

updated 4/26/05