sh.func.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,362 行 · 第 1/2 页
C
1,362 行
break; return (0); } unreadc(c); found = 1; do { c = readc(1); if (c == '\\' && (c = readc(1)) == '\n') c = ' '; if (c == '\'' || c == '"') if (d == 0) d = c; else if (d == c) d = 0; if (c < 0) goto past; if (wp) *wp++ = c; /* GT02: or at opening paren */ } while ((d || c != ' ' && c != '\t' && c != '(') && c != '\n'); } while (wp == 0); unreadc(c); if (found) *--wp = 0; return (found);past: switch (Stype) { case ZIF: bferr("then/endif not found"); case ZELSE: bferr("endif not found"); case ZBRKSW: case ZSWITCH: bferr("endsw not found"); case ZBREAK: bferr("end not found"); case ZGOTO: setname(Sgoal); bferr("label not found"); } /*NOTREACHED*/}toend(){ if (whyles->w_end == 0) { search(ZBREAK, 0); whyles->w_end = btell() - 1; } else bseek(whyles->w_end); wfree();}wfree(){ long o = btell(); while (whyles) { register struct whyle *wp = whyles; register struct whyle *nwp = wp->w_next; if (o >= wp->w_start && (wp->w_end == 0 || o < wp->w_end)) break; if (wp->w_fe0) blkfree(wp->w_fe0); if (wp->w_fename) xfree(wp->w_fename); xfree((char *)wp); whyles = nwp; }}doecho(v) char **v;{ echo(' ', v);}doglob(v) char **v;{ echo(0, v); flush();}echo(sep, v) char sep; register char **v;{ register char *cp; int nonl = 0; if (setintr) (void) sigsetmask(sigblock(0) & ~sigmask(SIGINT)); v++; if (*v == 0) return; gflag = 0, tglob(v); if (gflag) { v = glob(v); if (v == 0) bferr("No match"); } /* * Don't trim quote bit in case we are repeating - rdoty@tek * Repeat by "repeat 3 echo -n '/genvmu* '" * should produce: /genvmu* /genvmu* /genvmu* */ if( sep == ' ' && *v && ( (*v)[0]&TRIM == '-' && (*v)[1]&TRIM == 'n' && (*v)[2]&TRIM == '\0' ) || *v && !strcmp(*v, "-n") ) nonl++, v++; while (cp = *v++) { register int c; while (c = *cp++) { if ((c & TRIM) == QUOTECHAR) { c = *cp++; } putchar(c | QUOTE); } if (*v) putchar(sep | QUOTE); } if (sep && nonl == 0) putchar('\n'); else flush(); if (setintr) (void) sigblock(sigmask(SIGINT)); if (gargv) blkfree(gargv), gargv = 0;}extern char **environ; /* 002 - GAG */dosetenv(v) register char **v;{ char *vp, *lp; v++; if ((vp = *v++) == 0) { register char **ep; if (setintr) (void) sigsetmask(sigblock(0) & ~ sigmask(SIGINT)); for (ep = environ; *ep; ep++) csh_printf("%s\n", *ep); /* 003 RNF */ return; } if ((lp = *v++) == 0) lp = ""; setenv(vp, lp = globone(lp)); if (eq(vp, "PATH")) { importpath(lp); dohash(); } xfree(lp);}dounsetenv(v) register char **v;{ v++; do unsetenv(*v++); while (*v);}setenv(name, val) char *name, *val;{ register char **ep = environ; register char *cp, *dp; char *blk[2], **oep = ep; for (; *ep; ep++) { for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++) continue; if (*cp != 0 || *dp != '=') continue; cp = strspl("=", val); xfree(*ep); *ep = strspl(name, cp); xfree(cp); trim(ep); /* GAG - fix "setenv a $<" */ return; } blk[0] = strspl(name, "="); blk[1] = 0; environ = blkspl(environ, blk); xfree((char *)oep); setenv(name, val);}unsetenv(name) char *name;{ register char **ep = 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; environ = blkspl(environ, ep+1); *ep = cp; xfree(cp); xfree((char *)oep); return; }}doumask(v) register char **v;{ register char *cp = v[1]; register int i; if (cp == 0) { i = umask(0); (void) umask(i); csh_printf("%o\n", i); /* 003 RNF */ return; } i = 0; while (digit(*cp) && *cp != '8' && *cp != '9') i = i * 8 + *cp++ - '0'; if (*cp || i < 0 || i > 0777) bferr("Improper mask"); (void) umask(i);}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", -1, 0,};struct limits *findlim(cp) char *cp;{ register struct limits *lp, *res; res = 0; for (lp = limits; lp->limconst >= 0; lp++) if (prefix(cp, lp->limname)) { if (res) bferr("Ambiguous"); res = lp; } if (res) return (res); bferr("No such limit"); /*NOTREACHED*/}dolimit(v) register char **v;{ register struct limits *lp; register int limit; char hard = 0; v++; if (*v && eq(*v, "-h")) { 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) error(NOSTR);}getval(lp, v) register struct limits *lp; char **v;{ register float f; double atof(); char *cp = *v++; f = atof(cp); while (digit(*cp) || *cp == '.' || *cp == 'e' || *cp == 'E') cp++; if (*cp == 0) { if (*v == 0) return ((int)(f+0.5) * lp->limdiv); cp = *v; } switch (*cp) { case ':': if (lp->limconst != RLIMIT_CPU) goto badscal; return ((int)(f * 60.0 + atof(cp+1))); case 'h': if (lp->limconst != RLIMIT_CPU) goto badscal; limtail(cp, "hours"); f *= 3600.; break; case 'm': if (lp->limconst == RLIMIT_CPU) { limtail(cp, "minutes"); f *= 60.; break; } case 'M': if (lp->limconst == RLIMIT_CPU) goto badscal; *cp = 'm'; limtail(cp, "megabytes"); f *= 1024.*1024.; break; case 's': if (lp->limconst != RLIMIT_CPU) goto badscal; limtail(cp, "seconds"); break; case 'k': if (lp->limconst == RLIMIT_CPU) goto badscal; limtail(cp, "kbytes"); f *= 1024; break; case 'u': limtail(cp, "unlimited"); return (RLIM_INFINITY); default:badscal: bferr("Improper or unknown scale factor"); } return ((int)(f+0.5));}limtail(cp, str0) char *cp, *str0;{ register char *str = str0; while (*cp && *cp == *str) cp++, str++; if (*cp) error("Bad scaling; did you mean ``%s''?", str0);}plim(lp, hard) register struct limits *lp; char hard;{ struct rlimit rlim; int limit; csh_printf("%s \t", lp->limname); /* 003 RNF */ (void) getrlimit(lp->limconst, &rlim); limit = hard ? rlim.rlim_max : rlim.rlim_cur; if (limit == RLIM_INFINITY) csh_printf("unlimited"); /* 003 RNF */ else if (lp->limconst == RLIMIT_CPU) psecs((long)limit); else csh_printf("%d %s", limit / lp->limdiv, lp->limscale);/* 003 RNF */ csh_printf("\n"); /* 003 RNF */}dounlimit(v) register char **v;{ register struct limits *lp; int err = 0; char hard = 0; v++; if (*v && eq(*v, "-h")) { hard = 1; v++; } if (*v == 0) { for (lp = limits; lp->limconst >= 0; lp++) if (setlim(lp, hard, (int)RLIM_INFINITY) < 0) err++; if (err) error(NOSTR); return; } while (*v) { lp = findlim(*v++); if (setlim(lp, hard, (int)RLIM_INFINITY) < 0) error(NOSTR); }}setlim(lp, hard, limit) register struct limits *lp; char hard;{ extern uid_t geteuid(); /* 002 - GAG */ struct rlimit rlim; (void) getrlimit(lp->limconst, &rlim); if (hard) rlim.rlim_max = limit; else if (limit == RLIM_INFINITY && (int) geteuid() != 0) /* 002 - GAG */ rlim.rlim_cur = rlim.rlim_max; else rlim.rlim_cur = limit; if (setrlimit(lp->limconst, &rlim) < 0) { /* 003 RNF */ csh_printf("%s: %s: Can't %s%s limit\n", bname, lp->limname, limit == RLIM_INFINITY ? "remove" : "set", hard ? " hard" : ""); return (-1); } return (0);}dosuspend(){ int ldisc, ctpgrp; void (*old)(); if (loginsh) error("Can't suspend a login shell (yet)"); untty(); old = signal(SIGTSTP, SIG_DFL); (void) kill(0, SIGTSTP); /* the shell stops here */ (void) signal(SIGTSTP, old); if (tpgrp != -1) {retry: if (ioctl(FSHTTY, TIOCGPGRP, (char *)&ctpgrp)) { /* 002 - GAG */ Perror ("ioctl"); } if (ctpgrp != opgrp) { old = signal(SIGTTIN, SIG_DFL); (void) kill(0, SIGTTIN); (void) signal(SIGTTIN, old); goto retry; } (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&shpgrp); (void) setpgrp(0, shpgrp); } (void) ioctl(FSHTTY, TIOCGETD, (char *)&oldisc); if (oldisc != NTTYDISC) { csh_printf("Switching to new tty driver...\n"); /* 003 RNF */ ldisc = NTTYDISC; (void) ioctl(FSHTTY, TIOCSETD, (char *)&ldisc); }}doeval(v) char **v;{ char **oevalvec = evalvec; char *oevalp = evalp; jmp_buf osetexit; int reenter; char **gv = 0; v++; if (*v == 0) return; gflag = 0, tglob(v); if (gflag) { gv = v = glob(v); gargv = 0; if (v == 0) error("No match"); v = copyblk(v); } else trim(v); getexit(osetexit); reenter = 0; setexit(); reenter++; if (reenter == 1) { evalvec = v; evalp = 0; process(0); } evalvec = oevalvec; evalp = oevalp; doneinp = 0; if (gv) blkfree(gv); resexit(osetexit); if (reenter >= 2) error(NOSTR);}/* * After much disucussion, it was decided to have this fast clean internal * version of 'which' produce the same ugly output as it slower counterpart * /usr/ucb/which. A -u (useful) flag was added to allow a user to alias * which to which -u for a cleaner more useful form of the command. * tonyb@tek */dowhich(vec) char **vec;{ register struct biltins *bp; register char *word, **pp; /* GAG - don't need func */ struct varent *vp, *pth; char dir[MAXPATHLEN+1]; int cmp, hit, outty, uflag; /* * Glob it up */ uflag = gflag = 0; tglob(++vec); if(gflag) { /* has globbing chars */ vec = glob(vec); /* glob it */ if(vec == 0) bferr("No match"); } else trim( vec ); pth = adrof("path"); /* * Find out if we're writting to a tty. If not, use "command type" * output, else use "user" type output. * command type output is used to do things like 'echo `which foobar`' */ outty = isatty(1); /* * If no -u, go into useless mode, else provide useable, * coherent output. */ if(eq(*vec,"-u")) { uflag++; vec++; } while(word = *vec++) { /* * check aliases first. */ vp = adrof1(word, &aliases); if(vp) { if(!uflag) { csh_printf("%s: \t aliased to '", word); /* 003 RNF */ blkpr(vp->vec);csh_printf("'\n"); /* 003 RNF */ } else if(outty) { csh_printf("alias/%s '", word); /* 003 RNF */ blkpr(vp->vec); csh_printf("'\n"); /* 003 RNF */ } else csh_printf("%s\n",word); /* 003 RNF */ continue; } /* * If a hard path, just return it if it is executable, else * return nothing. */ if(index(word, '/') ) { if(executable(word)) { csh_printf("%s\n",word); /* 003 RNF */ continue; } else if( !uflag ) { csh_printf("%s not found\n", word); /* 003 RNF */ continue; } } /* * Check builtins * "standard" /usr/ucb/which does not support the concept * of builtin commands. YUK!!! */ if(uflag) { hit = 0;/* * GAG - the list of bfunc->bname is not null terminated */ for (bp = bfunc + nbfunc - 1; bp >= bfunc; bp--) { if ((cmp = strcmp (bp->bname, word)) == 0) { if (outty) csh_printf ("builtin/%s\n",word); /* 003 RNF */ else csh_printf ("%s\n",word); /* 003 RNF */ hit++; } else if (cmp < 0) break; } if(hit) continue; } /* * Check the paths * No need to read 'em, just check if it is executable. */ if(pth) { register char *ep; hit = 0; for(pp = pth->vec; pp && *pp && **pp; pp++) { ep = strcpy(dir,*pp); while(*ep) ep++; *ep++ = '/'; strcpy(ep,word); if(executable(dir)) { csh_printf("%s\n",dir); /* 003 RNF */ hit++; break; } } } /* * If not found and in useless mode */ if(!hit && !uflag) { csh_printf("no %s in ", word); /* 003 RNF */ blkpr(pth->vec); csh_printf("\n"); /* 003 RNF */ } } /* end while */}executable(path) register char *path;{ struct stat st; if(access(path,1) || stat(path, &st) ) st.st_mode = 0; return( (st.st_mode & S_IFMT) == S_IFREG);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?