📄 func.c
字号:
c = ' '; if (c == '\'' || c == '"') if (d == 0) d = c; else if (d == c) d = 0; if (c < 0) goto past; if (wp) { *wp++ = c; *wp = 0; /* end the string b4 test */ } } while ((d || (!(kwd = keyword(owp)) && c != ' ' && c != '\t')) && c != '\n'); } while (wp == 0); /* * if we have read a keyword ( "if", "switch" or "while" ) then we do not * need to unreadc the look-ahead char */ if (!kwd) { unreadc(c); if (found) *--wp = 0; } return (found);past: switch (Stype) { case T_IF: stderror(ERR_NAME | ERR_NOTFOUND, "then/endif"); case T_ELSE: stderror(ERR_NAME | ERR_NOTFOUND, "endif"); case T_BRKSW: case T_SWITCH: stderror(ERR_NAME | ERR_NOTFOUND, "endsw"); case T_BREAK: stderror(ERR_NAME | ERR_NOTFOUND, "end"); case T_GOTO: setname(vis_str(Sgoal)); stderror(ERR_NAME | ERR_NOTFOUND, "label"); } /* NOTREACHED */ return (0);}/* * keyword(wp) determines if wp is one of the built-n functions if, * switch or while. It seems that when an if statement looks like * "if(" then getword above sucks in the '(' and so the search routine * never finds what it is scanning for. Rather than rewrite doword, I hack * in a test to see if the string forms a keyword. Then doword stops * and returns the word "if" -strike */static intkeyword(wp) Char *wp;{ static Char STRif[] = {'i', 'f', '\0'}; static Char STRwhile[] = {'w', 'h', 'i', 'l', 'e', '\0'}; static Char STRswitch[] = {'s', 'w', 'i', 't', 'c', 'h', '\0'}; if (!wp) return (0); if ((Strcmp(wp, STRif) == 0) || (Strcmp(wp, STRwhile) == 0) || (Strcmp(wp, STRswitch) == 0)) return (1); return (0);}static voidtoend(){ if (whyles->w_end.type == F_SEEK && whyles->w_end.f_seek == 0) { search(T_BREAK, 0, NULL); btell(&whyles->w_end); whyles->w_end.f_seek--; } else bseek(&whyles->w_end); wfree();}voidwfree(){ struct Ain o; struct whyle *nwp; btell(&o); for (; whyles; whyles = nwp) { register struct whyle *wp = whyles; nwp = wp->w_next; /* * We free loops that have different seek types. */ if (wp->w_end.type != I_SEEK && wp->w_start.type == wp->w_end.type && wp->w_start.type == o.type) { if (wp->w_end.type == F_SEEK) { if (o.f_seek >= wp->w_start.f_seek && (wp->w_end.f_seek == 0 || o.f_seek < wp->w_end.f_seek)) break; } else { if (o.a_seek >= wp->w_start.a_seek && (wp->w_end.a_seek == 0 || o.a_seek < wp->w_end.a_seek)) break; } } if (wp->w_fe0) blkfree(wp->w_fe0); if (wp->w_fename) xfree((ptr_t) wp->w_fename); xfree((ptr_t) wp); }}void/*ARGSUSED*/doecho(v, t) Char **v; struct command *t;{ xecho(' ', v);}void/*ARGSUSED*/doglob(v, t) Char **v; struct command *t;{ xecho(0, v); (void) fflush(cshout);}static voidxecho(sep, v) int sep; register Char **v;{ register Char *cp; int nonl = 0; if (setintr) (void) sigsetmask(sigblock((sigset_t) 0) & ~sigmask(SIGINT)); v++; if (*v == 0) return; gflag = 0, tglob(v); if (gflag) { v = globall(v); if (v == 0) stderror(ERR_NAME | ERR_NOMATCH); } else { v = gargv = saveblk(v); trim(v); } if (sep == ' ' && *v && eq(*v, STRmn)) nonl++, v++; while ((cp = *v++) != NULL) { register int c; while ((c = *cp++) != '\0') (void) vis_fputc(c | QUOTE, cshout); if (*v) (void) vis_fputc(sep | QUOTE, cshout); } if (sep && nonl == 0) (void) fputc('\n', cshout); else (void) fflush(cshout); if (setintr) (void) sigblock(sigmask(SIGINT)); if (gargv) blkfree(gargv), gargv = 0;}void/*ARGSUSED*/dosetenv(v, t) Char **v; struct command *t;{ Char *vp, *lp; v++; if ((vp = *v++) == 0) { register Char **ep; if (setintr) (void) sigsetmask(sigblock((sigset_t) 0) & ~sigmask(SIGINT)); for (ep = STR_environ; *ep; ep++) (void) fprintf(cshout, "%s\n", vis_str(*ep)); return; } if ((lp = *v++) == 0) lp = STRNULL; Setenv(vp, lp = globone(lp, G_APPEND)); if (eq(vp, STRPATH)) { importpath(lp); dohash(NULL, NULL); } else if (eq(vp, STRLANG) || eq(vp, STRLC_CTYPE)) {#ifdef NLS int k; (void) setlocale(LC_ALL, ""); for (k = 0200; k <= 0377 && !Isprint(k); k++) continue; AsciiOnly = k > 0377;#else AsciiOnly = 0;#endif /* NLS */ } xfree((ptr_t) lp);}void/*ARGSUSED*/dounsetenv(v, t) Char **v; struct command *t;{ Char **ep, *p, *n; int i, maxi; static Char *name = NULL; if (name) xfree((ptr_t) name); /* * Find the longest environment variable */ for (maxi = 0, ep = STR_environ; *ep; ep++) { for (i = 0, p = *ep; *p && *p != '='; p++, i++) continue; if (i > maxi) maxi = i; } name = (Char *) xmalloc((size_t) (maxi + 1) * sizeof(Char)); while (++v && *v) for (maxi = 1; maxi;) for (maxi = 0, ep = STR_environ; *ep; ep++) { for (n = name, p = *ep; *p && *p != '='; *n++ = *p++) continue; *n = '\0'; if (!Gmatch(name, *v)) continue; maxi = 1; if (eq(name, STRLANG) || eq(name, STRLC_CTYPE)) {#ifdef NLS int k; (void) setlocale(LC_ALL, ""); for (k = 0200; k <= 0377 && !Isprint(k); k++) continue; AsciiOnly = k > 0377;#else AsciiOnly = getenv("LANG") == NULL && getenv("LC_CTYPE") == NULL;#endif /* NLS */ } /* * Delete name, and start again cause the environment changes */ Unsetenv(name); break; } xfree((ptr_t) name); name = NULL;}voidSetenv(name, val) Char *name, *val;{ register Char **ep = STR_environ; register Char *cp, *dp; Char *blk[2]; Char **oep = ep; for (; *ep; ep++) { for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++) continue; if (*cp != 0 || *dp != '=') continue; cp = Strspl(STRequal, val); xfree((ptr_t) * ep); *ep = strip(Strspl(name, cp)); xfree((ptr_t) cp); blkfree((Char **) environ); environ = short2blk(STR_environ); return; } cp = Strspl(name, STRequal); blk[0] = strip(Strspl(cp, val)); xfree((ptr_t) cp); blk[1] = 0; STR_environ = blkspl(STR_environ, blk); blkfree((Char **) environ); environ = short2blk(STR_environ); xfree((ptr_t) oep);}static voidUnsetenv(name) Char *name;{ register Char **ep = STR_environ; register Char *cp, *dp; Char **oep = ep; for (; *ep; ep++) { for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++) continue; if (*cp != 0 || *dp != '=') continue; cp = *ep; *ep = 0; STR_environ = blkspl(STR_environ, ep + 1); environ = short2blk(STR_environ); *ep = cp; xfree((ptr_t) cp); xfree((ptr_t) oep); return; }}void/*ARGSUSED*/doumask(v, t) Char **v; struct command *t;{ register Char *cp = v[1]; register int i; if (cp == 0) { i = umask(0); (void) umask(i); (void) fprintf(cshout, "%o\n", i); return; } i = 0; while (Isdigit(*cp) && *cp != '8' && *cp != '9') i = i * 8 + *cp++ - '0'; if (*cp || i < 0 || i > 0777) stderror(ERR_NAME | ERR_MASK); (void) umask(i);}typedef quad_t RLIM_TYPE;static struct limits { int limconst; char *limname; int limdiv; char *limscale;} limits[] = { { RLIMIT_CPU, "cputime", 1, "seconds" }, { RLIMIT_FSIZE, "filesize", 1024, "kbytes" }, { RLIMIT_DATA, "datasize", 1024, "kbytes" }, { RLIMIT_STACK, "stacksize", 1024, "kbytes" }, { RLIMIT_CORE, "coredumpsize", 1024, "kbytes" }, { RLIMIT_RSS, "memoryuse", 1024, "kbytes" }, { RLIMIT_MEMLOCK, "memorylocked", 1024, "kbytes" }, { RLIMIT_NPROC, "maxproc", 1, "" }, { RLIMIT_NOFILE, "openfiles", 1, "" }, { -1, NULL, 0, NULL }};static struct limits *findlim();static RLIM_TYPE getval();static void limtail();static void plim();static int setlim();static struct limits *findlim(cp) Char *cp;{ register struct limits *lp, *res; res = (struct limits *) NULL; for (lp = limits; lp->limconst >= 0; lp++) if (prefix(cp, str2short(lp->limname))) { if (res) stderror(ERR_NAME | ERR_AMBIG); res = lp; } if (res) return (res); stderror(ERR_NAME | ERR_LIMIT); /* NOTREACHED */ return (0);}void/*ARGSUSED*/dolimit(v, t) Char **v; struct command *t;{ register struct limits *lp; register RLIM_TYPE limit; char hard = 0; v++; if (*v && eq(*v, STRmh)) { hard = 1; v++; } if (*v == 0) { for (lp = limits; lp->limconst >= 0; lp++) plim(lp, hard); return; } lp = findlim(v[0]); if (v[1] == 0) { plim(lp, hard); return; } limit = getval(lp, v + 1); if (setlim(lp, hard, limit) < 0) stderror(ERR_SILENT);}static RLIM_TYPEgetval(lp, v) register struct limits *lp; Char **v;{ register float f; double atof(); Char *cp = *v++; f = atof(short2str(cp)); while (Isdigit(*cp) || *cp == '.' || *cp == 'e' || *cp == 'E') cp++; if (*cp == 0) { if (*v == 0) return ((RLIM_TYPE) ((f + 0.5) * lp->limdiv)); cp = *v; } switch (*cp) { case ':': if (lp->limconst != RLIMIT_CPU) goto badscal; return ((RLIM_TYPE) (f * 60.0 + atof(short2str(cp + 1)))); case 'h': if (lp->limconst != RLIMIT_CPU) goto badscal; limtail(cp, "hours"); f *= 3600.0; break; case 'm': if (lp->limconst == RLIMIT_CPU) { limtail(cp, "minutes"); f *= 60.0; break; } *cp = 'm'; limtail(cp, "megabytes"); f *= 1024.0 * 1024.0; break; case 's': if (lp->limconst != RLIMIT_CPU) goto badscal; limtail(cp, "seconds"); break; case 'M': if (lp->limconst == RLIMIT_CPU) goto badscal; *cp = 'm'; limtail(cp, "megabytes"); f *= 1024.0 * 1024.0; break; case 'k': if (lp->limconst == RLIMIT_CPU) goto badscal; limtail(cp, "kbytes"); f *= 1024.0; break; case 'u': limtail(cp, "unlimited"); return (RLIM_INFINITY); default:badscal: stderror(ERR_NAME | ERR_SCALEF); } f += 0.5; if (f > (float) RLIM_INFINITY) return RLIM_INFINITY; else return ((RLIM_TYPE) f);}static voidlimtail(cp, str) Char *cp; char *str;{ while (*cp && *cp == *str) cp++, str++; if (*cp) stderror(ERR_BADSCALE, str);}/*ARGSUSED*/static voidplim(lp, hard) register struct limits *lp; Char hard;{ struct rlimit rlim; RLIM_TYPE limit; (void) fprintf(cshout, "%s \t", lp->limname); (void) getrlimit(lp->limconst, &rlim); limit = hard ? rlim.rlim_max : rlim.rlim_cur; if (limit == RLIM_INFINITY) (void) fprintf(cshout, "unlimited"); else if (lp->limconst == RLIMIT_CPU) psecs((long) limit); else (void) fprintf(cshout, "%ld %s", (long) (limit / lp->limdiv), lp->limscale); (void) fputc('\n', cshout);}void/*ARGSUSED*/dounlimit(v, t) Char **v; struct command *t;{ register struct limits *lp; int lerr = 0; Char hard = 0; v++; if (*v && eq(*v, STRmh)) { hard = 1; v++; } if (*v == 0) { for (lp = limits; lp->limconst >= 0; lp++) if (setlim(lp, hard, (RLIM_TYPE) RLIM_INFINITY) < 0) lerr++; if (lerr) stderror(ERR_SILENT); return; } while (*v) { lp = findlim(*v++); if (setlim(lp, hard, (RLIM_TYPE) RLIM_INFINITY) < 0) stderror(ERR_SILENT); }}static intsetlim(lp, hard, limit) register struct limits *lp; Char hard; RLIM_TYPE limit;{ struct rlimit rlim; (void) getrlimit(lp->limconst, &rlim); if (hard) rlim.rlim_max = limit; else if (limit == RLIM_INFINITY && geteuid() != 0) rlim.rlim_cur = rlim.rlim_max; else rlim.rlim_cur = limit; if (setrlimit(lp->limconst, &rlim) < 0) { (void) fprintf(csherr, "%s: %s: Can't %s%s limit\n", bname, lp->limname, limit == RLIM_INFINITY ? "remove" : "set", hard ? " hard" : ""); return (-1); } return (0);}void/*ARGSUSED*/dosuspend(v, t) Char **v; struct command *t;{ int ctpgrp; void (*old) (); if (loginsh) stderror(ERR_SUSPLOG); untty(); old = signal(SIGTSTP, SIG_DFL); (void) kill(0, SIGTSTP); /* the shell stops here */ (void) signal(SIGTSTP, old); if (tpgrp != -1) { ctpgrp = tcgetpgrp(FSHTTY); while (ctpgrp != opgrp) { old = signal(SIGTTIN, SIG_DFL); (void) kill(0, SIGTTIN); (void) signal(SIGTTIN, old); } (void) setpgid(0, shpgrp); (void) tcsetpgrp(FSHTTY, shpgrp); }}/* This is the dreaded EVAL built-in. * If you don't fiddle with file descriptors, and reset didfds, * this command will either ignore redirection inside or outside * its aguments, e.g. eval "date >x" vs. eval "date" >x * The stuff here seems to work, but I did it by trial and error rather * than really knowing what was going on. If tpgrp is zero, we are * probably a background eval, e.g. "eval date &", and we want to * make sure that any processes we start stay in our pgrp. * This is also the case for "time eval date" -- stay in same pgrp. * Otherwise, under stty tostop, processes will stop in the wrong * pgrp, with no way for the shell to get them going again. -IAN! */static Char **gv = NULL;void/*ARGSUSED*/doeval(v, t) Char **v; struct command *t;{ Char **oevalvec; Char *oevalp; int odidfds; jmp_buf osetexit; int my_reenter; Char **savegv = gv; int saveIN; int saveOUT; int saveERR; int oSHIN; int oSHOUT; int oSHERR; UNREGISTER(v); oevalvec = evalvec; oevalp = evalp; odidfds = didfds; oSHIN = SHIN; oSHOUT = SHOUT; oSHERR = SHERR; v++; if (*v == 0) return; gflag = 0, tglob(v); if (gflag) { gv = v = globall(v); gargv = 0; if (v == 0) stderror(ERR_NOMATCH); v = copyblk(v); } else { gv = NULL; v = copyblk(v); trim(v); } saveIN = dcopy(SHIN, -1); saveOUT = dcopy(SHOUT, -1); saveERR = dcopy(SHERR, -1); getexit(osetexit); if ((my_reenter = setexit()) == 0) { evalvec = v; evalp = 0; SHIN = dcopy(0, -1); SHOUT = dcopy(1, -1); SHERR = dcopy(2, -1); didfds = 0; process(0); } evalvec = oevalvec; evalp = oevalp; doneinp = 0; didfds = odidfds; (void) close(SHIN); (void) close(SHOUT); (void) close(SHERR); SHIN = dmove(saveIN, oSHIN); SHOUT = dmove(saveOUT, oSHOUT); SHERR = dmove(saveERR, oSHERR); if (gv) blkfree(gv), gv = NULL; resexit(osetexit); gv = savegv; if (my_reenter) stderror(ERR_SILENT);}void/*ARGSUSED*/doprintf(v, t) Char **v; struct command *t;{ char **c; extern int progprintf __P((int, char **)); int ret; ret = progprintf(blklen(v), c = short2blk(v)); (void) fflush(cshout); (void) fflush(csherr); blkfree((Char **) c); if (ret) stderror(ERR_SILENT);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -