|
|
1.1 ! root 1: /* shell.c - shell */ ! 2: ! 3: #include <conf.h> ! 4: #include <kernel.h> ! 5: #include <proc.h> ! 6: #include <shell.h> ! 7: #include <cmd.h> ! 8: #include <tty.h> ! 9: ! 10: struct shvars Shl; /* globals used by Xinu shell */ ! 11: struct cmdent cmds[] = {CMDS}; /* shell commands */ ! 12: LOCAL char errhd[] = "Syntax error\n";/* global error messages */ ! 13: LOCAL char fmt[] = "Cannot open %s\n"; ! 14: LOCAL char fmt2[] = "[%d]\n"; ! 15: ! 16: /*------------------------------------------------------------------------ ! 17: * shell - Xinu shell with file redirection and background processing ! 18: *------------------------------------------------------------------------ ! 19: */ ! 20: shell(dev) ! 21: int dev; ! 22: { ! 23: int ntokens; ! 24: int i, j, len; ! 25: int com; ! 26: char *outnam, *innam; ! 27: int stdin, stdout, stderr; ! 28: Bool backgnd; ! 29: char ch, mach[SHMLEN]; ! 30: int child; ! 31: ! 32: Shl.shncmds = sizeof(cmds)/sizeof(struct cmdent); ! 33: for (getname(mach) ; TRUE ; ) { ! 34: fprintf(dev, "%s %% ", mach); ! 35: getutim(&Shl.shlast); ! 36: if ( (len = read(dev, Shl.shbuf, SHBUFLEN)) == 0) ! 37: len = read(dev, Shl.shbuf, SHBUFLEN); ! 38: if (len == EOF) ! 39: break; ! 40: Shl.shbuf[len-1] = NULLCH; ! 41: if ( (ntokens=lexan(Shl.shbuf)) == SYSERR) { ! 42: fprintf(dev, errhd); ! 43: continue; ! 44: } else if (ntokens == 0) ! 45: continue; ! 46: outnam = innam = NULL; ! 47: backgnd = FALSE; ! 48: ! 49: /* handle '&' */ ! 50: ! 51: if (Shl.shtktyp[ntokens-1] == '&') { ! 52: ntokens-- ; ! 53: backgnd = TRUE; ! 54: } ! 55: ! 56: /* scan tokens, accumulating length; handling redirect */ ! 57: ! 58: for (len=0,i=0 ; i<ntokens ; ) { ! 59: if ((ch = Shl.shtktyp[i]) == '&') { ! 60: ntokens = -1; ! 61: break; ! 62: } else if (ch == '>') { ! 63: if (outnam != NULL || i >= --ntokens) { ! 64: ntokens = -1; ! 65: break; ! 66: } ! 67: outnam = Shl.shtok[i+1]; ! 68: for (ntokens--,j=i ; j<ntokens ; j++) { ! 69: Shl.shtktyp[j] = Shl.shtktyp[j+2]; ! 70: Shl.shtok [j] = Shl.shtok [j+2]; ! 71: } ! 72: continue; ! 73: } else if (ch == '<') { ! 74: if (innam != NULL || i >= --ntokens) { ! 75: ntokens = -1; ! 76: break; ! 77: } ! 78: innam = Shl.shtok[i+1]; ! 79: for (ntokens--,j=i ; j < ntokens ; j++) { ! 80: Shl.shtktyp[j] = Shl.shtktyp[j+2]; ! 81: Shl.shtok [j] = Shl.shtok [j+2]; ! 82: } ! 83: continue; ! 84: } else { ! 85: len += strlen(Shl.shtok[i++])+1; ! 86: } ! 87: } ! 88: if (ntokens <= 0) { ! 89: fprintf(dev, errhd); ! 90: continue; ! 91: } ! 92: stdin = stdout = stderr = dev; ! 93: ! 94: /* Look up command in table */ ! 95: ! 96: for (com=0 ; com<Shl.shncmds ; com++) { ! 97: if (strcmp(cmds[com].cmdnam,Shl.shtok[0]) == 0) ! 98: break; ! 99: } ! 100: if (com >= Shl.shncmds) { ! 101: fprintf(dev, "%s: not found\n", Shl.shtok[0]); ! 102: continue; ! 103: } ! 104: ! 105: /* handle built-in commands with procedure call */ ! 106: ! 107: if (cmds[com].cbuiltin) { ! 108: if (innam != NULL || outnam != NULL || backgnd) ! 109: fprintf(dev, errhd); ! 110: else if ( (*cmds[com].cproc)(stdin, stdout, ! 111: stderr, ntokens, Shl.shtok) == SHEXIT) ! 112: break; ! 113: continue; ! 114: } ! 115: ! 116: /* Open files and redirect I/O if specified */ ! 117: ! 118: if (innam != NULL && (stdin=open(NAMESPACE,innam,"ro")) ! 119: == SYSERR) { ! 120: fprintf(dev, fmt, innam); ! 121: continue; ! 122: } ! 123: if (outnam != NULL && (stdout=open(NAMESPACE,outnam,"w")) ! 124: == SYSERR) { ! 125: fprintf(dev, fmt, outnam); ! 126: continue; ! 127: } ! 128: ! 129: /* compute space needed for string args. (in bytes) */ ! 130: ! 131: len += (ntokens+2) * sizeof(char *); ! 132: len = (len+sizeof(int)-1)&(~(sizeof(int)-1)); ! 133: control(dev, TCINT, getpid()); ! 134: ! 135: /* create process to execute conventional command */ ! 136: ! 137: if ( (child = create(cmds[com].cproc, SHCMDSTK, SHCMDPRI, ! 138: Shl.shtok[0],(len/sizeof(int)) + 4, ! 139: stdin, stdout, stderr, ntokens)) ! 140: == SYSERR) { ! 141: fprintf(dev, "Cannot create\n"); ! 142: close(stdout); ! 143: close(stdin); ! 144: continue; ! 145: } ! 146: addarg(child, ntokens, len); ! 147: setdev(child, stdin, stdout); ! 148: if (backgnd) { ! 149: fprintf(dev, fmt2, child); ! 150: resume(child); ! 151: } else { ! 152: setnok(getpid(), child); ! 153: recvclr(); ! 154: resume(child); ! 155: if (receive() == INTRMSG) { ! 156: setnok(BADPID, child); ! 157: fprintf(dev, fmt2, child); ! 158: } ! 159: } ! 160: } ! 161: return(OK); ! 162: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.