% % This file was automatically produced at Feb 27 2003, 17:15:55 by % c2latex -c simplesh.c % \documentclass[11pt,a4paper]{article} \setlength{\textwidth}{15cm} \setlength{\textheight}{22.5cm} \setlength{\hoffset}{-2cm} \setlength{\voffset}{-2cm} \begin{document} \expandafter\ifx\csname indentation\endcsname\relax% \newlength{\indentation}\fi \setlength{\indentation}{0.5em} \begin{flushleft} {$/\ast$\it{}\mbox{}\\ \hspace*{2\indentation}Nick Urbanik $<$nicku@vtc.edu.hk$>$\mbox{}\\ \hspace*{2\indentation}(very) simple shell.\mbox{}\\ \hspace*{2\indentation}No global variables in this one.\mbox{}\\ $\ast/$}\mbox{}\\ \mbox{}\\ {\tt \#include} $<${\tt{}stdio.h}$>$\mbox{}\\ {\tt \#include} $<${\tt{}unistd.h}$>$\mbox{}\\ {\tt \#include} $<${\tt{}string.h}$>$\mbox{}\\ {\tt \#include} $<${\tt{}libgen.h}$>$\mbox{}\\ {\tt \#include} $<${\tt{}stdlib.h}$>$\mbox{}\\ {\tt \#include} $<${\tt{}ctype.h}$>$\mbox{}\\ {\tt \#include} $<${\tt{}sys/wait.h}$>$\mbox{}\\ \mbox{}\\ {\bf void} print\_prompt( {\bf const} {\bf char} $\ast$prog )\mbox{}\\ \{\mbox{}\\ \hspace*{8\indentation}printf( {\tt"\%s-$>$ "}, prog );\mbox{}\\ \}\mbox{}\\ \mbox{}\\ {\bf void} built\_in\_commands( {\bf char} $\ast$ {\bf const} $\ast$args )\mbox{}\\ \{\mbox{}\\ \hspace*{8\indentation}{\bf if} ( strcmp( args[ 0 ], {\tt"exit"} ) == 0 ) exit( 0 );\mbox{}\\ \}\mbox{}\\ \mbox{}\\ {$/\ast$\it{}\mbox{}\\ \hspace*{2\indentation}Read the command into a buffer line[].\mbox{}\\ \hspace*{2\indentation}Then set an array of pointers, one to the start of each word.\mbox{}\\ \hspace*{2\indentation}A word starts at the first non-whitespace character after\mbox{}\\ \hspace*{2\indentation}either the beginning of the line, or whitespace.\mbox{}\\ \hspace*{2\indentation}Terminate the array of pointers to arguements with a NULL\mbox{}\\ \hspace*{2\indentation}pointer, as required for execv$\ast$().\mbox{}\\ \mbox{}\\ \hspace*{2\indentation}We also null-terminate each argument, as required.\mbox{}\\ \hspace*{2\indentation}Handle specially the case where the command is exit.\mbox{}\\ \hspace*{2\indentation}Exit if get end of file.\mbox{}\\ \hspace*{1\indentation}$\ast/$}\mbox{}\\ \mbox{}\\ {\tt \#define} MAX\_ARGS 64\mbox{}\\ {\tt \#define} MAX\_LINE\_LEN 1024\mbox{}\\ \mbox{}\\ {\bf char} $\ast$$\ast$read\_command( {\bf void} )\mbox{}\\ \{\mbox{}\\ \hspace*{8\indentation}{\bf static} {\bf char} $\ast$args[ MAX\_ARGS + 1 ];\mbox{}\\ \hspace*{8\indentation}{\bf static} {\bf char} line[ MAX\_LINE\_LEN ];\mbox{}\\ \hspace*{8\indentation}{\bf int} i = 0, j = 0, inspace = 1;\mbox{}\\ \hspace*{8\indentation}{\bf if} ( fgets( line, MAX\_LINE\_LEN, stdin ) == NULL ) exit( 1 );\mbox{}\\ \hspace*{8\indentation}{\bf while} ( line[ i ] $\neq$ '\0' \&\& j $<$ MAX\_ARGS ) \{\mbox{}\\ \hspace*{16\indentation}{\bf if} ( isspace( line[ i ] ) ) \{\mbox{}\\ \hspace*{24\indentation}{\bf if} ( ! inspace ) line[ i ] = '\0';\mbox{}\\ \hspace*{24\indentation}++i;\mbox{}\\ \hspace*{24\indentation}inspace = 1;\mbox{}\\ \hspace*{24\indentation}{\bf continue};\mbox{}\\ \hspace*{16\indentation}\}\mbox{}\\ \hspace*{16\indentation}{\bf if} ( inspace ) \{\mbox{}\\ \hspace*{24\indentation}args[ j++ ] = \&line[ i ];\mbox{}\\ \hspace*{24\indentation}inspace = 0;\mbox{}\\ \hspace*{16\indentation}\}\mbox{}\\ \hspace*{16\indentation}{\bf else} ++i;\mbox{}\\ \hspace*{8\indentation}\}\mbox{}\\ \hspace*{8\indentation}args[ j ] = NULL;\mbox{}\\ \hspace*{8\indentation}built\_in\_commands( args );\mbox{}\\ \hspace*{8\indentation}{\bf return} args;\mbox{}\\ \}\mbox{}\\ \mbox{}\\ {\bf int} main( {\bf int} argc, {\bf char} $\ast$$\ast$argv )\mbox{}\\ \{\mbox{}\\ \hspace*{8\indentation}{\bf char} $\ast$prog\_name = basename( $\ast$argv );\mbox{}\\ \hspace*{8\indentation}{\bf char} $\ast$$\ast$args;\mbox{}\\ \hspace*{8\indentation}print\_prompt( prog\_name );\mbox{}\\ \hspace*{8\indentation}args = read\_command();\mbox{}\\ \hspace*{8\indentation}{\bf for} ( ;; ) \{\mbox{}\\ \hspace*{16\indentation}{\bf int} pid = fork();\mbox{}\\ \hspace*{16\indentation}{\bf if} ( pid $<$ 0 ) \{\mbox{}\\ \hspace*{24\indentation}perror( prog\_name );\mbox{}\\ \hspace*{24\indentation}exit( 2 );\mbox{}\\ \hspace*{16\indentation}\}\mbox{}\\ \hspace*{16\indentation}{\bf if} ( pid == 0 ) \{\mbox{}\\ \hspace*{24\indentation}{\bf int} rv = execvp( args[ 0 ], args );\mbox{}\\ \hspace*{24\indentation}{\bf if} ( rv == $-$1 ) perror( prog\_name );\mbox{}\\ \hspace*{24\indentation}exit( 1 ); \mbox{}\\ \hspace*{16\indentation}\}\mbox{}\\ \hspace*{16\indentation}wait( NULL );\mbox{}\\ \hspace*{16\indentation}print\_prompt( prog\_name );\mbox{}\\ \hspace*{16\indentation}args = read\_command();\mbox{}\\ \hspace*{8\indentation}\}\mbox{}\\ \}\mbox{}\\ \end{flushleft} \end{document}