📄 msh.c
字号:
return(c); case '^': startl = 1; return('|'); case '>': case '<': diag(c); return(c); case '\n': nlseen++; gethere(); startl = 1; if (multiline || cf & CONTIN) { if (interactive && e.iop <= iostack) {#ifdef CONFIG_FEATURE_COMMAND_EDITING current_prompt=cprompt->value;#else prs(cprompt->value);#endif } if (cf & CONTIN) goto loop; } return(c); case '(': case ')': startl = 1; return(c); } unget(c);pack: while ((c = my_getc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n")) if (e.linep >= elinep) err("word too long"); else *e.linep++ = c; unget(c); if(any(c, "\"'`$")) goto loop; *e.linep++ = '\0'; if (atstart && (c = rlookup(line))!=0) { startl = 1; return(c); } yylval.cp = strsave(line, areanum); return(WORD);}static intcollect(c, c1)register int c, c1;{ char s[2]; *e.linep++ = c; while ((c = my_getc(c1)) != c1) { if (c == 0) { unget(c); s[0] = c1; s[1] = 0; prs("no closing "); yyerror(s); return(YYERRCODE); } if (interactive && c == '\n' && e.iop <= iostack) {#ifdef CONFIG_FEATURE_COMMAND_EDITING current_prompt=cprompt->value;#else prs(cprompt->value);#endif } *e.linep++ = c; } *e.linep++ = c; return(0);}static intdual(c)register int c;{ char s[3]; register char *cp = s; *cp++ = c; *cp++ = my_getc(0); *cp = 0; if ((c = rlookup(s)) == 0) unget(*--cp); return(c);}static voiddiag(ec)register int ec;{ register int c; c = my_getc(0); if (c == '>' || c == '<') { if (c != ec) zzerr(); yylval.i = ec == '>'? IOWRITE|IOCAT: IOHERE; c = my_getc(0); } else yylval.i = ec == '>'? IOWRITE: IOREAD; if (c != '&' || yylval.i == IOHERE) unget(c); else yylval.i |= IODUP;}static char *tree(size)unsigned size;{ register char *t; if ((t = getcell(size)) == NULL) { prs("command line too complicated\n"); fail(); /* NOTREACHED */ } return(t);}/* VARARGS1 *//* ARGSUSED *//* -------- exec.c -------- *//* * execute tree */static intexecute(t, pin, pout, act)register struct op *t;int *pin, *pout;int act;{ register struct op *t1; volatile int i, rv, a; char *cp, **wp, **wp2; struct var *vp; struct brkcon bc;#if __GNUC__ /* Avoid longjmp clobbering */ (void) ℘#endif if (t == NULL) return(0); rv = 0; a = areanum++; wp = (wp2 = t->words) != NULL ? eval(wp2, t->type == TCOM ? DOALL : DOALL & ~DOKEY) : NULL; switch(t->type) { case TPAREN: rv = execute(t->left, pin, pout, 0); break; case TCOM: { int child; rv = forkexec(t, pin, pout, act, wp, &child); if (child) { exstat = rv; leave(); } } break; case TPIPE: { int pv[2]; if ((rv = openpipe(pv)) < 0) break; pv[0] = remap(pv[0]); pv[1] = remap(pv[1]); (void) execute(t->left, pin, pv, 0); rv = execute(t->right, pv, pout, 0); } break; case TLIST: (void) execute(t->left, pin, pout, 0); rv = execute(t->right, pin, pout, 0); break; case TASYNC: { int hinteractive = interactive; i = vfork(); if (i != 0) { interactive = hinteractive; if (i != -1) { setval(lookup("!"), putn(i)); if (pin != NULL) closepipe(pin); if (interactive) { prs(putn(i)); prs("\n"); } } else rv = -1; setstatus(rv); } else { signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); if (interactive) signal(SIGTERM, SIG_DFL); interactive = 0; if (pin == NULL) { close(0); open("/dev/null", 0); } exit(execute(t->left, pin, pout, FEXEC)); } } break; case TOR: case TAND: rv = execute(t->left, pin, pout, 0); if ((t1 = t->right)!=NULL && (rv == 0) == (t->type == TAND)) rv = execute(t1, pin, pout, 0); break; case TFOR: if (wp == NULL) { wp = dolv+1; if ((i = dolc) < 0) i = 0; } else { i = -1; while (*wp++ != NULL) ; } vp = lookup(t->str); while (setjmp(bc.brkpt)) if (isbreak) goto broken; brkset(&bc); for (t1 = t->left; i-- && *wp != NULL;) { setval(vp, *wp++); rv = execute(t1, pin, pout, 0); } brklist = brklist->nextlev; break; case TWHILE: case TUNTIL: while (setjmp(bc.brkpt)) if (isbreak) goto broken; brkset(&bc); t1 = t->left; while ((execute(t1, pin, pout, 0) == 0) == (t->type == TWHILE)) rv = execute(t->right, pin, pout, 0); brklist = brklist->nextlev; break; case TIF: case TELIF: if (t->right != NULL) { rv = !execute(t->left, pin, pout, 0) ? execute(t->right->left, pin, pout, 0): execute(t->right->right, pin, pout, 0); } break; case TCASE: if ((cp = evalstr(t->str, DOSUB|DOTRIM)) == 0) cp = ""; if ((t1 = findcase(t->left, cp)) != NULL) rv = execute(t1, pin, pout, 0); break; case TBRACE:/* if (iopp = t->ioact) while (*iopp) if (iosetup(*iopp++, pin!=NULL, pout!=NULL)) { rv = -1; break; }*/ if (rv >= 0 && (t1 = t->left)) rv = execute(t1, pin, pout, 0); break; }broken: t->words = wp2; isbreak = 0; freehere(areanum); freearea(areanum); areanum = a; if (interactive && intr) { closeall(); fail(); } if ((i = trapset) != 0) { trapset = 0; runtrap(i); } return(rv);}static intforkexec( register struct op *t, int *pin, int *pout, int act, char **wp, int *pforked){ int i, rv; int (*shcom)(struct op *) = NULL; register int f; char *cp = NULL; struct ioword **iopp; int resetsig; char **owp; int *hpin = pin; int *hpout = pout; int hforked; char *hwp; int hinteractive; int hintr; struct brkcon * hbrklist; int hexecflg;#if __GNUC__ /* Avoid longjmp clobbering */ (void) &pin; (void) &pout; (void) ℘ (void) &shcom; (void) &cp; (void) &resetsig; (void) &owp;#endif owp = wp; resetsig = 0; *pforked = 0; rv = -1; /* system-detected error */ if (t->type == TCOM) { while ((cp = *wp++) != NULL) ; cp = *wp; /* strip all initial assignments */ /* not correct wrt PATH=yyy command etc */ if (flag['x']) echo (cp ? wp: owp); if (cp == NULL && t->ioact == NULL) { while ((cp = *owp++) != NULL && assign(cp, COPYV)) ; return(setstatus(0)); } else if (cp != NULL) shcom = inbuilt(cp); } t->words = wp; f = act; if (shcom == NULL && (f & FEXEC) == 0) { hpin = pin; hpout = pout; hforked = *pforked; hwp = *wp; hinteractive = interactive; hintr = intr; hbrklist = brklist; hexecflg = execflg; i = vfork(); if (i != 0) { /* who wrote this crappy non vfork safe shit? */ pin = hpin; pout = hpout; *pforked = hforked; *wp = hwp; interactive = hinteractive; intr = hintr; brklist = hbrklist; execflg = hexecflg; *pforked = 0; if (i == -1) return(rv); if (pin != NULL) closepipe(pin); return(pout==NULL? setstatus(waitfor(i,0)): 0); } if (interactive) { signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); resetsig = 1; } interactive = 0; intr = 0; (*pforked)++; brklist = 0; execflg = 0; } if (owp != NULL) while ((cp = *owp++) != NULL && assign(cp, COPYV)) if (shcom == NULL) export(lookup(cp));#ifdef COMPIPE if ((pin != NULL || pout != NULL) && shcom != NULL && shcom != doexec) { err("piping to/from shell builtins not yet done"); return(-1); }#endif if (pin != NULL) { dup2(pin[0], 0); closepipe(pin); } if (pout != NULL) { dup2(pout[1], 1); closepipe(pout); } if ((iopp = t->ioact) != NULL) { if (shcom != NULL && shcom != doexec) { prs(cp); err(": cannot redirect shell command"); return(-1); } while (*iopp) if (iosetup(*iopp++, pin!=NULL, pout!=NULL)) return(rv); } if (shcom) return(setstatus((*shcom)(t))); /* should use FIOCEXCL */ for (i=FDBASE; i<NOFILE; i++) close(i); if (resetsig) { signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); } if (t->type == TPAREN) exit(execute(t->left, NOPIPE, NOPIPE, FEXEC)); if (wp[0] == NULL) exit(0); cp = rexecve(wp[0], wp, makenv()); prs(wp[0]); prs(": "); warn(cp); if (!execflg) trap[0] = NULL; leave(); /* NOTREACHED */ exit(1);}/* * 0< 1> are ignored as required * within pipelines. */static intiosetup(iop, pipein, pipeout)register struct ioword *iop;int pipein, pipeout;{ register int u = -1; char *cp=NULL, *msg; if (iop->io_unit == IODEFAULT) /* take default */ iop->io_unit = iop->io_flag&(IOREAD|IOHERE)? 0: 1; if (pipein && iop->io_unit == 0) return(0); if (pipeout && iop->io_unit == 1) return(0); msg = iop->io_flag&(IOREAD|IOHERE)? "open": "create"; if ((iop->io_flag & IOHERE) == 0) { cp = iop->io_name; if ((cp = evalstr(cp, DOSUB|DOTRIM)) == NULL) return(1); } if (iop->io_flag & IODUP) { if (cp[1] || (!isdigit(*cp) && *cp != '-')) { prs(cp); err(": illegal >& argument"); return(1); } if (*cp == '-') iop->io_flag = IOCLOSE; iop->io_flag &= ~(IOREAD|IOWRITE); } switch (iop->io_flag) { case IOREAD: u = open(cp, 0); break; case IOHERE: case IOHERE|IOXHERE: u = herein(iop->io_name, iop->io_flag&IOXHERE); cp = "here file"; break; case IOWRITE|IOCAT: if ((u = open(cp, 1)) >= 0) { lseek(u, (long)0, 2); break; } case IOWRITE: u = creat(cp, 0666); break; case IODUP: u = dup2(*cp-'0', iop->io_unit); break; case IOCLOSE: close(iop->io_unit); return(0); } if (u < 0) { prs(cp); prs(": cannot "); warn(msg); return(1); } else { if (u != iop->io_unit) { dup2(u, iop->io_unit); close(u); } } return(0);}static voidecho(wp)register char **wp;{ register int i; prs("+"); for (i=0; wp[i]; i++) { if (i) prs(" "); prs(wp[i]); } prs("\n");}static struct op **find1case(t, w)struct op *t;char *w;{ register struct op *t1; struct op **tp; register char **wp, *cp; if (t == NULL) return((struct op **)NULL); if (t->type == TLIST) { if ((tp = find1case(t->left, w)) != NULL) return(tp); t1 = t->right; /* TPAT */ } else t1 = t; for (wp = t1->words; *wp;) if ((cp = evalstr(*wp++, DOSUB)) && gmatch(w, cp)) return(&t1->left); return((struct op **)NULL);}static struct op *findcase(t, w)struct op *t;char *w;{ register struct op **tp; return((tp = find1case(t, w)) != NULL? *tp: (struct op *)NULL);}/* * Enter a new loop level (marked for break/continue). */static voidbrkset(bc)struct brkcon *bc;{ bc->nextlev = brklist; brklist = bc;}/* * Wait for the last process created. * Print a message for each process found * that was killed by a signal. * Ignore interrupt signals while waiting * unless `canintr' is true. */static intwaitfor(lastpid, canintr)register int lastpid;int canintr;{ register int pid, rv; int s; int oheedint = heedint; heedint = 0; rv = 0; do { pid = wait(&s); if (pid == -1) { if (errno != EINTR || canintr) break; } else { if ((rv = WAITSIG(s)) != 0) { if (rv < NSIGNAL) { if (signame[rv] != NULL) { if (pid != lastpid) { prn(pid); prs(": "); } prs(signame[rv]); } } else { if (pid != lastpid) { prn(pid); prs(": "); } prs("Signal "); prn(rv); prs(" "); } if (WAITCORE(s)) prs(" - core dumped"); if (rv >= NSIGNAL || signame[rv]) prs("\n"); rv = -1; } else rv = WAITVAL(s); } } while (pid != lastpid); heedint = oheedint; if (intr) { if (interactive) { if (canintr) intr = 0; } else { if (exstat == 0) exstat = rv; onintr(0); } } return(rv);}static intsetstatus(s)register int s;{ exstat = s; setval(lookup("?"), putn(s)); return(s);}/* * PATH-searching interface to execve. * If getenv("PATH") were kept up-to-date, * execvp might be used. */static char *rexecve(c, v, envp)char *c, **v, **envp;{ register int i; register char *sp, *tp; int eacces = 0, asis = 0;#ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL char *name = c; optind = 1; if (find_applet_by_name(name)) { /* We have to exec here since we vforked. Running * run_applet_by_name() won't work and bad things * will happen. */ execve("/proc/self/exe", v, envp); execve("busybox", v, envp); }#endif sp = any('/', c)? "": path->value; asis = *sp == '\0'; while (asis || *sp != '\0') { asis = 0; tp = e.linep; for (; *sp != '\0'; tp++) if ((*tp = *sp++) == ':') { asis = *sp == '\0'; break; } if (tp != e.linep) *tp++ = '/'; for (i = 0; (*tp++ = c[i++]) != '\0';) ; execve(e.linep, v, envp); switch (errno) { case ENOEXEC: *v = e.linep; tp = *--v;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -