Name: _____________________ Class: CET 421
SSN/ID:   _____________________ Section & Group: ____________
Project: Rolling and Enhancing Your Shell


Rolling Your Shell

Write a small program that loops reading a line from standard input and checks the first word of the input line. If the first word is one of the following internal commands (or aliases) perform the designated task. Otherwise use the standard ANSI C system function to execute the line through the default system shell.

Internal Commands/Aliases:

clr
clear the screen using the system function clear:    system("clear").
dir <directory>
list the current directory contents (ls -al <directory>) - you will need to provide some command line parsing capability to extract the target directory for listing . Once you have built the replacement command line, use the system function to execute it.
environ
list all the environment strings - the environment strings can be accessed from within a program by specifying the POSIX compliant environment list:
    extern char **environ;
as a global variable. environ is an array of pointers to the environment strings terminated with a NULL pointer. (see environ.c and below for examples of use)
quit
quit from the program with a zero return value. Use the standard exit function.

You might want to design your program to make this list of 'aliases' extendable by storing the alias strings and the alias functions in arrays...

External Commands:

For all other command line inputs, relay the command line to the parent shell for execution using the system function.

When parsing the command line you may have to explicitly or implicitly malloc (strdup) storage for a copy of the command line. Ensure that you free any malloced memory after it is no longer needed. You may find strtok useful for parsing.

The C Standard Library has a number of other string related functions that you may find useful (string.h)contains links to descriptions of the other main "string" functions).

The source of the basis for a simple shell using strtok and system is contained in strtokeg.c.

Note the number, type and style of comments in strtokeg.c - this is the level of commentry expected of the code you hand in for your projects.

Code should be in 'straight' C using the compiler of your choice (cc or gcc).

Always use nice to execute your test programs at lower priority to ensure they do not inconvenience other users if they go 'haywire'. e.g.:
 
   >nice a.out

Environment & Command Line Arguments

Basic information can be passed to a C process via:

Command Line Parameters

int main(int argc, char * argv[])
{
   int i;


   printf("argc = %d\n");                  // print arg count
   for (i = 0; i < argc; i++)              // print args
      printf("argv[%d]: %s\n",i, argv[i]);
   exit(0);
}

invoked through the command line:

echoarg arg1 TEST fooo

will result in the following output:

argc = 4
argv[0]: echoarg
argv[1]: arg1
argv[2]: TEST
argv[3]: fooo

Accessing The Environment

While some implementations of C provide a 3rd argument to main (char * envp[] ) with which to pass the environment, ANSI C only defines two arguments to main so the preferred way of passing the environment is by a built-in pointer (POSIX):

extern char **environ;  // NULL terminated array of char *
           
main(int argc, char *argv[])
{
   int i;
   for (i = 0; environ[i] != NULL; i++)
      printf("%s\n",environ[i]);
   exit(0);
}

example output:

GROUP=staff
HOME=/usr/user
LOGNAME=user
PATH=/bin:/usr/bin:usr/user/bin
PWD=/usr/user/work
SHELL=/bin/tcsh
USER=user

Updating The Environment

You can use the functions getenv, putenv, setenv to access and/or change individual environment variables.

Internal storage is the exclusive property of the process and may be modified freely, but there is not necessarily room for new variables or larger values.

If the pointer environ is made to point to a new environment space it will be passed on to any programs subsequently envoked.

If copying the environment, you should find out how many entries are in the environ table and malloc enough space to hold that table and any extra string pointers you may want to put in it.

Remember, the environment is an array of pointers. The strings pointed to by those pointers need to exist in their own malloced memory space.

Extending Your Shell

Earlier, you wrote a simple shell that looped reading a line from standard input and checked the first word of the input line. Now, you should try adding the extra functionality listed below.

Internal Commands/Aliases:

Add the capability to change the current directory and set and change environment strings:

cd <directory>

Change the current default directory to <directory>. If the <directory> argument is not present, report the current directory. This command should also change the PWD environment string. For this you will need to study the chdir (Glass p 431), getcwd and putenv functions.

While you are at it you might as well put the name of the current working directory in the shell prompt!

Be careful using putenv - the string you provide becomes part of the environment and should not be changed (or freed!). i.e. it should be made static - global or malloced (or strduped).

You should now be looking at the specifications for the second project to see what extensions you will need to add to the code you have generated in these exercises.

Code should be in 'straight' C using the compiler of your choice (cc or gcc).

Always use nice to execute your test programs at lower priority to ensure they do not inconvenience other users if they go 'haywire'. e.g.:
 
   >nice a.out

Hand In: Email your final script files to rickys@sethi.org.


Ricky J. Sethi <rickys at sethi.org>
Last modified: Mon Jun 6 01:18:11 PDT 2005