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 + -
显示快捷键?