00001
00002
00003
00004
00005
00006 #include "shell.h"
00007
00008 #define MAXARG 20
00009 #define MAXFNAME 500
00010 #define MAXWORD 100
00011 #define BADFD -2
00012
00013 main()
00014 {
00015 char *prompt;
00016 int pid, fd;
00017 TOKEN term;
00018 static TOKEN command();
00019 static void waitfor();
00020
00021 ignoresig();
00022 if(!EVinit())
00023 fatal ("can't initialize environment");
00024 if( (prompt = EVget("PS2")) == NULL)
00025 prompt = ">";
00026 printf("%s", prompt);
00027
00028 while(1){
00029 term = command(&pid, FALSE, NULL);
00030 if ( term != T_AMP && pid != 0)
00031 waitfor(pid);
00032 if ( term == T_NL)
00033 printf("%s", prompt);
00034 for(fd = 3; fd< 20; fd++)
00035 (void)close(fd);
00036 }
00037 }
00038
00039 static TOKEN
00040 command(int *waitpid, BOOLEAN makepipe, int *pipefdp)
00041 {
00042
00043 TOKEN token, term ;
00044 int argc, srcfd, dstfd, pid, pfd[2];
00045 char *argv[MAXARG + 1], srcfile[MAXFNAME],dstfile[MAXFNAME];
00046 char word[MAXWORD], *malloc();
00047 BOOLEAN append;
00048 static int invoke( );
00049
00050 argc = 0;
00051 srcfd = 0;
00052 dstfd = 1;
00053 while (1) {
00054 switch ( token = gettoken(word)) {
00055 case T_WORD:
00056 if (argc == MAXARG){
00057 fprintf(stderr, "Too many args\n");
00058 break;
00059 }
00060 if (( argv[argc] = malloc(strlen(word) +1)) == NULL) {
00061 fprintf(stderr, "Out of argmemory\n");
00062 break;
00063 }
00064 strcpy(argv[argc], word);
00065 argc ++;
00066 continue;
00067 case T_LT:
00068 if(makepipe){
00069 fprintf(stderr, "Extra<\n");
00070 break;
00071 }
00072 if (gettoken(srcfile) != T_WORD){
00073 fprintf(stderr, "Illegal <\n");
00074 break;
00075 }
00076 srcfd = BADFD;
00077 continue;
00078 case T_GT:
00079 if (dstfd !=1) {
00080 fprintf(stderr, "Extra > or >> \n");
00081 break;
00082 }
00083 if (gettoken(dstfile) != T_WORD) {
00084 fprintf(stderr, "Illegal > or >> \n");
00085 break;
00086 }
00087 dstfd = BADFD;
00088 append = FALSE;
00089 continue;
00090 case T_GTGT:
00091 if (dstfd != 1) {
00092 fprintf(stderr, "Extra > or >>\n");
00093 break;
00094 }
00095 if (gettoken(dstfile) != T_WORD){
00096 fprintf(stderr, "Illegal >or >>\n");
00097 break;
00098 }
00099 dstfd = BADFD;
00100 append = TRUE;
00101 continue;
00102 case T_BAR:
00103 case T_AMP:
00104 case T_SEMI:
00105 case T_NL:
00106 argv[argc] = NULL;
00107 if ( token == T_BAR) {
00108 if ( dstfd !=1) {
00109 fprintf(stderr, "> or >> conflicts with |\n");
00110 break;
00111 }
00112 term = command ( waitpid, TRUE, &dstfd);
00113 }
00114 else
00115 term = token;
00116
00117 if ( makepipe ){
00118 if ( pipe(pfd) == -1)
00119 syserr("pipe");
00120 *pipefdp = pfd[1];
00121 srcfd = pfd[0];
00122 }
00123 if(term == T_AMP)pid = invoke(argc, argv, srcfd,
00124 srcfile, dstfd, dstfile, append, TRUE);
00125 else pid=invoke(argc,argv,srcfd, srcfile,dstfd, dstfile,
00126 append, FALSE);
00127
00128 if (token != T_BAR)
00129 *waitpid = pid;
00130 if (argc == 0 && (token != T_NL || srcfd >1))
00131 fprintf(stderr, "Missing command\n");
00132 while (--argc >= 0)
00133 free(argv[argc]);
00134 return(term);
00135 case T_EOF:
00136 exit(0);
00137 }
00138 }
00139 }
00140
00141 static int invoke(int argc,char *argv[],int srcfd, char *srcfile,
00142 int dstfd,char *dstfile,BOOLEAN append, BOOLEAN bckgrnd)
00143
00144 {
00145
00146 static void redirect();
00147 int pid;
00148 static BOOLEAN builtin();
00149
00150 if (argc == 0 || builtin(argc, argv, srcfd, dstfd))
00151 return(0);
00152 switch (pid = fork()) {
00153 case -1:
00154 fprintf(stderr, "Can't create new process\n");
00155 return(0);
00156 case 0:
00157 if (!bckgrnd)
00158 entrysig();
00159 if (!EVupdate())
00160 fatal("can't update environment");
00161 redirect(srcfd, srcfile, dstfd, dstfile, append, bckgrnd);
00162 execvp(argv[0], argv);
00163 fprintf(stderr, "Can't execute %s\n", argv[0]);
00164 exit(0);
00165 default:
00166 if (srcfd > 0 && close(srcfd) == -1)
00167 syserr("close src");
00168 if (dstfd > 1 && close(dstfd) == -1)
00169 syserr("close dst");
00170 if (bckgrnd)
00171 printf("%d\n", pid);
00172 return(pid);
00173 }
00174 }
00175
00176
00177
00178 {
00179 int flags, fd;
00180 long lseek();
00181
00182 if (srcfd == 0 && bckgrnd) {
00183 strcpy(srcfile, "/dev/null");
00184 srcfd = BADFD;
00185 }
00186
00187 if (srcfd !=0 ) {
00188 if ( close(0) == -1)
00189 syserr("close");
00190 if (srcfd > 0) {
00191 if ( dup(srcfd) !=0)
00192 fatal("dup");
00193 }
00194 else if (open (srcfile, O_RDONLY, 0) == -1){
00195 fprintf(stderr, "Can't open %s\n", srcfile);
00196 exit(0);
00197 }
00198 }
00199
00200 if (dstfd !=1) {
00201 if (close(1) == -1)
00202 syserr("close");
00203 if (dstfd > 1){
00204 if (dup(dstfd) != 1)
00205 fatal("dup");
00206 }
00207 else {
00208 flags = O_WRONLY | O_CREAT;
00209 if(!append)
00210 flags |= O_TRUNC;
00211 if (open(dstfile, flags, 0666) == -1) {
00212 fprintf(stderr, "Can't create %s\n", dstfile);
00213 exit(0);
00214 }
00215 if(append)
00216 if(lseek(1, 0L,2) == -1)
00217 syserr("lseek");
00218 }
00219 }
00220 for (fd =3; fd<20; fd++)
00221 (void)close(fd);
00222 }
00223 */
00224 static void waitfor(int pid)
00225 {
00226
00227 int wpid, status;
00228
00229 while( (wpid = wait(&status)) != pid && wpid !=-1 )
00230 statusprt(wpid, status);
00231 if (wpid == pid )
00232 statusprt(0, status);
00233 }
00234
00235 static BOOLEAN builtin(int argc, char *argv[], int srcfd, int dstfd)
00236
00237 {
00238 char *path;
00239
00240 if (strchr(argv[0], '=') !=NULL)
00241 asg(argc, argv);
00242 else if (strcmp(argv[0], "export") == 0 )
00243 export(argc, argv);
00244 else if (strcmp(argv[0], "set") == 0 )
00245 set(argc, argv);
00246 else if (strcmp(argv[0], "cd") == 0 ){
00247 if ( argc >1)
00248 path = argv[1];
00249 else
00250 if (( path = EVget("HOME")) ==NULL)
00251 path = ".";
00252 if (chdir(path) ==-1)
00253 fprintf(stderr, "%s: bad directory\n", path);
00254 }
00255 else
00256 return( FALSE);
00257 if (srcfd !=0 || dstfd !=1)
00258 fprintf(stderr, "Illegal redirection or pipeline\n");
00259 }