Eric Breck and Yanling Wang 
***********************************************
SECTION 1 usages of builtin command
***********************************************

1) jobs 
Print out the list of jobs in the background, including
the jobid, process status(Running or Stopped), and command line.

2)history
Print out the list of most recent HISTORY_MAX commands. HISTORY_MAX
is defined in compile time in history.h. Now it is set to 10.

3)cd [pathname]
in unix:
cd [pathname] -- if no path name is given, cd will change current
work directory to HOME; otherwise, it will change current work 
directory to pathname.

in windows:
cd [pathname] -- if no path name is given, cd will print out current
work directory; otherwise, it will change current work directory to
pathname.

This command has to be a foreground command itself.

4)exit 
It quits the shell program if there is no job in the background. Otherwise
prints out the list of all background jobs and warns the user to kill them
before exit.
This command has to be a foreground command itself.


5)kill [-sigspec] jobspec0 [jobspec1 ...]
  kill -l [sigspec ...] /* only in linux */

Terminate a list of processes that are defined by the jobspec, jobspec could be
a process id, or a jobid, or a prefix of command line if there is no
ambiguity. You can also specify which signal you want to send to the specified
job. In windows, sigspec is an integer that determines the exit code of
terminated program. The sigspec in UNIX could be the signal name (with or
without SIG) (upper or lower case) or the signal index. 

in linux, you can use kill -l to find out information about available signal
names and index.

6)help [command ...]
Print out the builtin command syntax. If a command is specified, only print
out the information for given command.

7)fg jobspec
Wake up the process specified by the jobspec, and put it in the foreground.
This command has to be a foreground command itself.

8)bg jobspec
Wake up a stopped process specified by the jobspec, and let it run in the
background. 
This command has to be a foreground command itself.

9)stop jobspec
Send a SIGSTOP signal to the specified process. 

10)ldir [pathname]
Print out last modification time, file size, file name for all files and
directories in the specified directory, or in the current work directory
if [pathname] is not given.

11) ctrl-Z (linux only)
In linux, when there is a process running in the foreground, you can type
ctrl-z to stop the process, put it in the background(with status as Stopped)
and get back to the shell prompt.

***********************************************
SECTION 2 implementation of required features 
***********************************************

1. Prompt
 To get the current working directory, there is a simple system call in linux
       char *getcwd(char *buf, size_t size);
  which copies the absolute path name into the given string buffer.
 
 In windows, there is a similar system call from Runtime Library
char *_getcwd( 
   char *buffer,
   int maxlen 
);
 that would do the same thing.

2. reading command lines.

Linux version uses GNU readline library (note: does not use history,
 so up and down arrows don't work).

Windows version just uses fgets -- but miraculously, this seems to
support up-and-down to get previous commands.  I don't know why.

relative/absolute pathnames: this should work

3. PATH.

Linux uses execvp, which does search the path

Windows uses CreateProcess(NULL,...) - according to the docs, if you
specify the module name, it doesn't search $PATH, but if you give the
exe name in the command line, it does search $PATH.

4. IO redirection.

Works on both Linux and Windows (just > and <, none of the fancy stuff).

Builtins can be redirected under Linux, but not under Windows.  This is
because under Linux I can fork the shell and treat redirection of a
builtin just like redirection of a non-builtin.  Doing it for Windows
would be possible, but would require a different approach.

5. Backgrounding commands.  Backgrounding external commands should work
in both Windows and Linux.  The & may appear anywhere on the command
line (even more than once :).  It should break up a word (as if it
were whitespace)

Backgrounding builtins should work under Linux.  It does not work under
Windows, there not being a fork there.

Oh, and backgrounding (or redirecting) the builtins 'exit', 'cd', and
'fg' doesn't work, but it doesn't make sense anyway...

6. Command history.  This should work.  HISTORY_MAX in history.h is the
#define which specifies the history size.  Change it to anything you like
(at compile time).

7. !-repetition This should work: !n does
  command n         (if n>0) command current+n (if n<0) (nothing)
  if n==0

Of course, if n refers to an event that has been forgotten or hasn't
happened yet, an error message is given.

!!, as is standard, is equivalent to !-1

Note: the ! has to be the VERY FIRST character on the line, and the
entire line is replaced with the repeated line.



8. Built-in Commands
jobs:
Usage: jobs takes in no argument (or ignores all extra argument).
$jobs

  jobs will print out a list of jobs that are running in the background,
with their jobid, status (running, stopped, etc.) and the command line
that started this background job.

   Also, everytime we enter a command, the shell will query the status
of every background job in turns. If any of the background job terminated
(either normally, or being killed), we will print out the information 
about this job and remove this job from the job list. To do this efficiently,
I simply marked this job as terminated, and remove all terminated jobs
all at once whenever I need to go through the job list again.
   
   To query the status of each background job, I used waitpid in linux
and GetExitCodeProcess in Windows. In linux, waitpid is called with
option WNOHANG and WUNTRACED so that it will return even if the process
being queried did not terminate. GetExitCodeProcess in windows will
give a status STILL_ACTIVE if the process is still alive, and exit
code of the process otherwise.


cd:
Usage: cd will change current directory. For linux, "cd" without any
argument will retrieve the HOME directory from the environment variable
and change to the home directory. In Windows, there is no HOME directory,
so "cd" without any argument will simply print out current path name,
which is similar to "pwd" in Linux.

$cd pathname
or
$cd

cd is implemented in Linux with the system call 
       int chdir(const char *path);
and in Windows with a similar system call from the Runtime Library:
int _chdir( 
   const char *dirname 
);

exit:
Usage: will exit the shell program if there is no background jobs. Otherwise,
will print out the list of background jobs and continue the shell program.
$exit


kill:
Usage: kill is different in Linux from in Windows.
In Linux, kill can have several options:

1) print out the list of all Signals
$kill -l 

2) print out the signal name and number for a given signal
$kill -l sigspec
Here the sigspec could be a signal number, or signal name
that looks like SIGTERM, or just the name without SIG, 
e.g., TERM. It can parse both upper and lower case names.

3)Send SIGTERM to one or more jobs
$kill job1 job2 ...
The jobs could be specified either by jobid "%jobid", or
pid "pid", or the first few characters in the command line,
e.g. "emacs&" as long as there is only one match in the job
list.

4)Specify the signal to send to one or more jobs
$kill -sigspec job1 job2 ...
sigspec could be the signal number (i.e., 15 for SIGTERM, 
9 for SIGKILL, etc) or the signal name, with or without
"SIG", (i.e., TERM, kill, SIGSTOP, etc.).

In Windows, there is no support for kill -l. It won't do
any thing. But you can specify the exit code that you want
to send to a list of jobs. The default exit code will
be 0.

$kill job1 job2 ...
$kill -exitcode job1 job2 ...

help:
print out the syntax of all commands or the specified commands.

history:
print out the last HISTORY_MAX commands typed in. HISTORY_MAX
is defined in history.h in compile time. The default is now 10.


9 If the user choose to exit while there are background processes,
we will print out the list of the background processes, and will not
quit.


***********************************************
SECTION 3 command line parsing
***********************************************
A note on syntax.  < > & and whitespace are metacharacters.
Words are extended sequences of anything other than these characters.
The first word after a > or a < is its argument, and is removed from
the command-line as far as the spawned process is concerned.  &s after
the first one don't do anything.

***********************************************
SECTION 4 optional features
***********************************************
1 optional parameters.
We support optional parameters for kill, you can specify the
signal you want to send by kill, and you can specify the process
to kill in different ways (jobid, pid and prefix of command line). 
You can also query the names of a signal with index or the index
with name in linux.

2 more on job control
We have full support for job control. You can stop a foreground
job by typing ctrl-Z. You can also stop a background job by 
"stop jobspec". Both ways, the shell will send SIGSTOP signal
to the specified process. 

To restart a stopped process, you can either use bg to start it
in the background, or fg to start the process in the foreground.

3 ldir in Windows
We implemented ldir that will print certain file/directory information.

4 Tab completion and command prompt editing.
This comes for free by using readline from GNU library. 
In windows, up and down arrows are supported by the system
call gets() directly as well.
