2 This partial code is a modified version of Marc Rochkind's A Real Shell,
3 published in "Advanced UNIX Programming", Prentice Hall, 1985.
13 main() /* real shell */
18 static TOKEN
command();
19 static void waitfor();
23 fatal ("can't initialize environment");
24 if( (prompt
= EVget("PS2")) == NULL
)
29 term
= command(&pid
, FALSE
, NULL
);
30 if ( term
!= T_AMP
&& pid
!= 0)
34 for(fd
= 3; fd
< 20; fd
++)
35 (void)close(fd
); /*ignore error */
40 command(int *waitpid
, BOOLEAN makepipe
, int *pipefdp
) /* do simple cmd */
44 int argc
, srcfd
, dstfd
, pid
, pfd
[2];
45 char *argv
[MAXARG
+ 1], srcfile
[MAXFNAME
],dstfile
[MAXFNAME
];
46 char word
[MAXWORD
], *malloc();
54 switch ( token
= gettoken(word
)) {
57 fprintf(stderr
, "Too many args\n");
60 if (( argv
[argc
] = malloc(strlen(word
) +1)) == NULL
) {
61 fprintf(stderr
, "Out of argmemory\n");
64 strcpy(argv
[argc
], word
);
69 fprintf(stderr
, "Extra<\n");
72 if (gettoken(srcfile
) != T_WORD
){
73 fprintf(stderr
, "Illegal <\n");
80 fprintf(stderr
, "Extra > or >> \n");
83 if (gettoken(dstfile
) != T_WORD
) {
84 fprintf(stderr
, "Illegal > or >> \n");
92 fprintf(stderr
, "Extra > or >>\n");
95 if (gettoken(dstfile
) != T_WORD
){
96 fprintf(stderr
, "Illegal >or >>\n");
107 if ( token
== T_BAR
) {
109 fprintf(stderr
, "> or >> conflicts with |\n");
112 term
= command ( waitpid
, TRUE
, &dstfd
);
118 if ( pipe(pfd
) == -1)
123 if(term
== T_AMP
)pid
= invoke(argc
, argv
, srcfd
,
124 srcfile
, dstfd
, dstfile
, append
, TRUE
);
125 else pid
=invoke(argc
,argv
,srcfd
, srcfile
,dstfd
, dstfile
,
130 if (argc
== 0 && (token
!= T_NL
|| srcfd
>1))
131 fprintf(stderr
, "Missing command\n");
141 static int invoke(int argc
,char *argv
[],int srcfd
, char *srcfile
,
142 int dstfd
,char *dstfile
,BOOLEAN append
, BOOLEAN bckgrnd
)
143 /* invoke simple command */
146 static void redirect();
148 static BOOLEAN
builtin();
150 if (argc
== 0 || builtin(argc
, argv
, srcfd
, dstfd
))
152 switch (pid
= fork()) {
154 fprintf(stderr
, "Can't create new process\n");
160 fatal("can't update environment");
161 redirect(srcfd
, srcfile
, dstfd
, dstfile
, append
, bckgrnd
);
162 execvp(argv
[0], argv
);
163 fprintf(stderr
, "Can't execute %s\n", argv
[0]);
166 if (srcfd
> 0 && close(srcfd
) == -1)
168 if (dstfd
> 1 && close(dstfd
) == -1)
175 /* REDIRECCION ANULADA MOMENTANEAMENTE
176 static void redirect(int srcfd, char *srcfile, int dstfd,char *dstfile,
177 BOOLEAN append, BOOLEAN bckgrnd) /* I/O redirection */
182 if (srcfd
== 0 && bckgrnd
) {
183 strcpy(srcfile
, "/dev/null");
194 else if (open (srcfile
, O_RDONLY
, 0) == -1){
195 fprintf(stderr
, "Can't open %s\n", srcfile
);
208 flags
= O_WRONLY
| O_CREAT
;
211 if (open(dstfile
, flags
, 0666) == -1) {
212 fprintf(stderr
, "Can't create %s\n", dstfile
);
216 if(lseek(1, 0L,2) == -1)
220 for (fd
=3; fd
<20; fd
++)
221 (void)close(fd
); // ignore error
224 static void waitfor(int pid
) /* wait for child */
229 while( (wpid
= wait(&status
)) != pid
&& wpid
!=-1 )
230 statusprt(wpid
, status
);
232 statusprt(0, status
);
235 static BOOLEAN
builtin(int argc
, char *argv
[], int srcfd
, int dstfd
)
240 if (strchr(argv
[0], '=') !=NULL
)
242 else if (strcmp(argv
[0], "export") == 0 )
244 else if (strcmp(argv
[0], "set") == 0 )
246 else if (strcmp(argv
[0], "cd") == 0 ){
250 if (( path
= EVget("HOME")) ==NULL
)
252 if (chdir(path
) ==-1)
253 fprintf(stderr
, "%s: bad directory\n", path
);
257 if (srcfd
!=0 || dstfd
!=1)
258 fprintf(stderr
, "Illegal redirection or pipeline\n");