⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c_sh.c

📁 一个开放源代码的 AT&T 的 Korn Shell 的复制品, 支持大多数 ksh89 的特性。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * built-in Bourne commands */#include "sh.h"#include "ksh_stat.h" 	/* umask() */#include "ksh_time.h"#include "ksh_times.h"static	char *clocktos ARGS((clock_t t));/* :, false and true */intc_label(wp)	char **wp;{	return wp[0][0] == 'f' ? 1 : 0;}intc_shift(wp)	char **wp;{	register struct block *l = e->loc;	register int n;	long val;	char *arg;	if (ksh_getopt(wp, &builtin_opt, null) == '?')		return 1;	arg = wp[builtin_opt.optind];	if (arg) {		evaluate(arg, &val, KSH_UNWIND_ERROR);		n = val;	} else		n = 1;	if (n < 0) {		bi_errorf("%s: bad number", arg);		return (1);	}	if (l->argc < n) {		bi_errorf("nothing to shift");		return (1);	}	l->argv[n] = l->argv[0];	l->argv += n;	l->argc -= n;	return 0;}intc_umask(wp)	char **wp;{	register int i;	register char *cp;	int symbolic = 0;	int old_umask;	int optc;	while ((optc = ksh_getopt(wp, &builtin_opt, "S")) != EOF)		switch (optc) {		  case 'S':			symbolic = 1;			break;		  case '?':			return 1;		}	cp = wp[builtin_opt.optind];	if (cp == NULL) {		old_umask = umask(0);		umask(old_umask);		if (symbolic) {			char buf[18];			int j;			old_umask = ~old_umask;			cp = buf;			for (i = 0; i < 3; i++) {				*cp++ = "ugo"[i];				*cp++ = '=';				for (j = 0; j < 3; j++)					if (old_umask & (1 << (8 - (3*i + j))))						*cp++ = "rwx"[j];				*cp++ = ',';			}			cp[-1] = '\0';			shprintf("%s\n", buf);		} else			shprintf("%#3.3o\n", old_umask);	} else {		int new_umask;		if (digit(*cp)) {			for (new_umask = 0; *cp >= '0' && *cp <= '7'; cp++)				new_umask = new_umask * 8 + (*cp - '0');			if (*cp) {				bi_errorf("bad number");				return 1;			}		} else {			/* symbolic format */			int positions, new_val;			char op;			old_umask = umask(0);			umask(old_umask); /* in case of error */			old_umask = ~old_umask;			new_umask = old_umask;			positions = 0;			while (*cp) {				while (*cp && strchr("augo", *cp))					switch (*cp++) {					case 'a': positions |= 0111; break;					case 'u': positions |= 0100; break;					case 'g': positions |= 0010; break;					case 'o': positions |= 0001; break;					}				if (!positions)					positions = 0111; /* default is a */				if (!strchr("=+-", op = *cp))					break;				cp++;				new_val = 0;				while (*cp && strchr("rwxugoXs", *cp))					switch (*cp++) {					case 'r': new_val |= 04; break;					case 'w': new_val |= 02; break;					case 'x': new_val |= 01; break;					case 'u': new_val |= old_umask >> 6;						  break;					case 'g': new_val |= old_umask >> 3;						  break;					case 'o': new_val |= old_umask >> 0;						  break;					case 'X': if (old_umask & 0111)							new_val |= 01;						  break;					case 's': /* ignored */						  break;					}				new_val = (new_val & 07) * positions;				switch (op) {				case '-':					new_umask &= ~new_val;					break;				case '=':					new_umask = new_val					    | (new_umask & ~(positions * 07));					break;				case '+':					new_umask |= new_val;				}				if (*cp == ',') {					positions = 0;					cp++;				} else if (!strchr("=+-", *cp))					break;			}			if (*cp) {				bi_errorf("bad mask");				return 1;			}			new_umask = ~new_umask;		}		umask(new_umask);	}	return 0;}intc_dot(wp)	char **wp;{	char *file, *cp;	char **argv;	int argc;	int i;	int err;	if (ksh_getopt(wp, &builtin_opt, null) == '?')		return 1;	if ((cp = wp[builtin_opt.optind]) == NULL)		return 0;	file = search(cp, path, R_OK, &err);	if (file == NULL) {		bi_errorf("%s: %s", cp, err ? strerror(err) : "not found");		return 1;	}	/* Set positional parameters? */	if (wp[builtin_opt.optind + 1]) {		argv = wp + builtin_opt.optind;		argv[0] = e->loc->argv[0]; /* preserve $0 */		for (argc = 0; argv[argc + 1]; argc++)			;	} else {		argc = 0;		argv = (char **) 0;	}	i = include(file, argc, argv, 0);	if (i < 0) { /* should not happen */		bi_errorf("%s: %s", cp, strerror(errno));		return 1;	}	return i;}intc_wait(wp)	char **wp;{	int UNINITIALIZED(rv);	int sig;	if (ksh_getopt(wp, &builtin_opt, null) == '?')		return 1;	wp += builtin_opt.optind;	if (*wp == (char *) 0) {		while (waitfor((char *) 0, &sig) >= 0)			;		rv = sig;	} else {		for (; *wp; wp++)			rv = waitfor(*wp, &sig);		if (rv < 0)			rv = sig ? sig : 127; /* magic exit code: bad job-id */	}	return rv;}intc_read(wp)	char **wp;{	register int c = 0;	int expand = 1, history = 0;	int expanding;	int ecode = 0;	register char *cp;	int fd = 0;	struct shf *shf;	int optc;	const char *emsg;	XString cs, xs;	struct tbl *vp;	char UNINITIALIZED(*xp);	while ((optc = ksh_getopt(wp, &builtin_opt, "prsu,")) != EOF)		switch (optc) {#ifdef KSH		  case 'p':			if ((fd = coproc_getfd(R_OK, &emsg)) < 0) {				bi_errorf("-p: %s", emsg);				return 1;			}			break;#endif /* KSH */		  case 'r':			expand = 0;			break;		  case 's':			history = 1;			break;		  case 'u':			if (!*(cp = builtin_opt.optarg))				fd = 0;			else if ((fd = check_fd(cp, R_OK, &emsg)) < 0) {				bi_errorf("-u: %s: %s", cp, emsg);				return 1;			}			break;		  case '?':			return 1;		}	wp += builtin_opt.optind;	if (*wp == NULL)		*--wp = "REPLY";	/* Since we can't necessarily seek backwards on non-regular files,	 * don't buffer them so we can't read too much.	 */	shf = shf_reopen(fd, SHF_RD | SHF_INTERRUPT | can_seek(fd), shl_spare);	if ((cp = strchr(*wp, '?')) != NULL) {		*cp = 0;		if (isatty(fd)) {			/* at&t ksh says it prints prompt on fd if it's open			 * for writing and is a tty, but it doesn't do it			 * (it also doesn't check the interactive flag,			 * as is indicated in the Kornshell book).			 */			shellf("%s", cp+1);		}	}#ifdef KSH	/* If we are reading from the co-process for the first time,	 * make sure the other side of the pipe is closed first.  This allows	 * the detection of eof.	 *	 * This is not compatiable with at&t ksh... the fd is kept so another	 * coproc can be started with same ouput, however, this means eof	 * can't be detected...  This is why it is closed here.	 * If this call is removed, remove the eof check below, too.	* coproc_readw_close(fd);	 */#endif /* KSH */	if (history)		Xinit(xs, xp, 128, ATEMP);	expanding = 0;	Xinit(cs, cp, 128, ATEMP);	for (; *wp != NULL; wp++) {		for (cp = Xstring(cs, cp); ; ) {			if (c == '\n' || c == EOF)				break;			while (1) {				c = shf_getc(shf);				if (c == '\0'#ifdef OS2				    || c == '\r'#endif /* OS2 */				    )					continue;				if (c == EOF && shf_error(shf)				    && shf_errno(shf) == EINTR)				{					/* Was the offending signal one that					 * would normally kill a process?					 * If so, pretend the read was killed.					 */					ecode = fatal_trap_check();					/* non fatal (eg, CHLD), carry on */					if (!ecode) {						shf_clearerr(shf);						continue;					}				}				break;			}			if (history) {				Xcheck(xs, xp);				Xput(xs, xp, c);			}			Xcheck(cs, cp);			if (expanding) {				expanding = 0;				if (c == '\n') {					c = 0;					if (Flag(FTALKING_I) && isatty(fd)) {						/* set prompt in case this is						 * called from .profile or $ENV						 */						set_prompt(PS2, (Source *) 0);						pprompt(prompt, 0);					}				} else if (c != EOF)					Xput(cs, cp, c);				continue;			}			if (expand && c == '\\') {				expanding = 1;				continue;			}			if (c == '\n' || c == EOF)				break;			if (ctype(c, C_IFS)) {				if (Xlength(cs, cp) == 0 && ctype(c, C_IFSWS))					continue;				if (wp[1])					break;			}			Xput(cs, cp, c);		}		/* strip trailing IFS white space from last variable */		if (!wp[1])			while (Xlength(cs, cp) && ctype(cp[-1], C_IFS)			       && ctype(cp[-1], C_IFSWS))				cp--;		Xput(cs, cp, '\0');		vp = global(*wp);		/* Must be done before setting export. */		if (vp->flag & RDONLY) {			shf_flush(shf);			bi_errorf("%s is read only", *wp);			return 1;		}		if (Flag(FEXPORT))			typeset(*wp, EXPORT, 0, 0, 0);		if (!setstr(vp, Xstring(cs, cp), KSH_RETURN_ERROR)) {		    shf_flush(shf);		    return 1;		}	}	shf_flush(shf);	if (history) {		Xput(xs, xp, '\0');		source->line++;		histsave(source->line, Xstring(xs, xp), 1);		Xfree(xs, xp);	}#ifdef KSH	/* if this is the co-process fd, close the file descriptor	 * (can get eof if and only if all processes are have died, ie,	 * coproc.njobs is 0 and the pipe is closed).	 */	if (c == EOF && !ecode)		coproc_read_close(fd);#endif /* KSH */	return ecode ? ecode : c == EOF;}intc_eval(wp)	char **wp;{	register struct source *s;	if (ksh_getopt(wp, &builtin_opt, null) == '?')		return 1;	s = pushs(SWORDS, ATEMP);	s->u.strv = wp + builtin_opt.optind;	if (!Flag(FPOSIX)) {		/*		 * Handle case where the command is empty due to failed		 * command substitution, eg, eval "$(false)".		 * In this case, shell() will not set/change exstat (because		 * compiled tree is empty), so will use this value.		 * subst_exstat is cleared in execute(), so should be 0 if		 * there were no substitutions.		 *		 * A strict reading of POSIX says we don't do this (though		 * it is traditionally done). [from 1003.2-1992]		 *    3.9.1: Simple Commands		 *	... If there is a command name, execution shall		 *	continue as described in 3.9.1.1.  If there		 *	is no command name, but the command contained a command		 *	substitution, the command shall complete with the exit		 *	status of the last command substitution		 *    3.9.1.1: Command Search and Execution		 *	...(1)...(a) If the command name matches the name of		 *	a special built-in utility, that special built-in		 *	utility shall be invoked.		 * 3.14.5: Eval		 *	... If there are no arguments, or only null arguments,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -