OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / user / msh / msh.c
1 /* Minimal shell C source - (c) 1999, Spock (Oscar Portela Arjona) */
2
3 #include <sys/wait.h>
4 #include <unistd.h>
5 #include <fcntl.h>
6 #include <stdlib.h>
7 #include <signal.h>
8 #include <string.h>
9
10 #define chkerr(c,msg) if (c < 0) {perror("ERROR (" msg ")"); exit(-1);}
11 #define mvdesc(d1,d2) {close(d1); dup(d2); close(d2);}
12 #define redir(n,f)    {close(n); chkerr(open(fv[n],f,0666),"open");}
13 #define size(v,s,u,n) {(v = realloc(v,s))[u] = n;}
14 #define l2            l1[vc]
15 #define l3            l2[p[0]]
16
17 int main(void) {
18   char ***l1 = NULL, *fv[3] ,dir[50] ,c;
19   int vc, bg, id, p[2], d;
20
21   signal(SIGINT, SIG_IGN);      signal(SIGQUIT,SIG_IGN);
22
23   while (1) {
24     getcwd(dir,50); write(1,dir,strlen(dir)); write(1," $ ",d = bg = 3);
25     for (;bg; fv[bg] = NULL) realloc(fv[--bg],0); size(l1,4,0,NULL);
26     for (vc = p[0] = 0; read(0,&c,1) && (c != '\n');)
27     switch(c) {
28      case '<': d = 0; break;
29      case '>': d = 1; break;
30      case '|': if (l2) {vc++; p[0] = 0;} d = 3; break;
31      case '&': if (d < 3) d++; else bg = 1; break;
32      case ' ': if (d < 3) {if (fv[d]) d = 3;} else if (l2 && l3) p[0]++; break;
33      default:  if (d < 3) {if (!fv[d]) size(fv[d],1,0,'\0');
34                   size(fv[d],(id=strlen(fv[d]))+2,id,c); fv[d][id+1]='\0';}
35                else { if (!l2) {size(l1,vc*4+8,vc+1,NULL); size(l2,4,0,NULL);}
36                   if (!l3) {size(l2,p[0]*4+8,p[0]+1,NULL); size(l3,1,0,'\0');}
37                   size(l3,(id=strlen(l3))+2,id,c); l3[id+1] = '\0';}}
38
39     for (vc = 0; l2;) {
40       if (!vc) d = dup(0);
41       if (l1[vc+1]) chkerr(pipe(p),"pipe");
42       if (!strcmp(l2[0],"exit")) exit(0);
43       if (!strcmp(l2[0],"cd")) {if (chdir(l2[1]) < 0) chdir(getenv("HOME"));}
44       else {if (!(id = fork())) {
45                if (fv[0] && !vc) redir(0,O_RDONLY) else mvdesc(0,d);
46                if (fv[1]) redir(1,O_CREAT|O_WRONLY|O_TRUNC);
47                if (fv[2]) redir(2,O_CREAT|O_WRONLY|O_TRUNC);
48                if (l1[vc+1]) {mvdesc(1,p[1]); close(p[0]);}
49                if (!bg) {signal(SIGINT,SIG_DFL); signal(SIGQUIT,SIG_DFL);}
50                chkerr(execvp(l2[0],l2),"exec");}
51             if (!l1[vc+1] && !bg) while (wait(NULL) != id);}
52       for (id = 0; l2[id]; realloc(l2[id++],0)); realloc(l2,0);
53       close(d); if (l1[++vc]) {d = dup(p[0]); close(p[0]); close(p[1]);}}}}