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

📄 c_sh.c

📁 一个开放源代码的 AT&T 的 Korn Shell 的复制品, 支持大多数 ksh89 的特性。
💻 C
📖 第 1 页 / 共 2 页
字号:
		 *	eval shall return an exit status of zero.		 */		exstat = subst_exstat;	}	return shell(s, FALSE);}intc_trap(wp)	char **wp;{	int i;	char *s;	register Trap *p;	if (ksh_getopt(wp, &builtin_opt, null) == '?')		return 1;	wp += builtin_opt.optind;	if (*wp == NULL) {		int anydfl = 0;		for (p = sigtraps, i = SIGNALS+1; --i >= 0; p++) {			if (p->trap == NULL)				anydfl = 1;			else {				shprintf("trap -- ");				print_value_quoted(p->trap);				shprintf(" %s\n", p->name);			}		}#if 0 /* this is ugly and not clear POSIX needs it */		/* POSIX may need this so output of trap can be saved and		 * used to restore trap conditions		 */		if (anydfl) {			shprintf("trap -- -");			for (p = sigtraps, i = SIGNALS+1; --i >= 0; p++)				if (p->trap == NULL && p->name)					shprintf(" %s", p->name);			shprintf(newline);		}#endif		return 0;	}	/*	 * Use case sensitive lookup for first arg so the	 * command 'exit' isn't confused with the pseudo-signal	 * 'EXIT'.	 */	s = (gettrap(*wp, FALSE) == NULL) ? *wp++ : NULL; /* get command */	if (s != NULL && s[0] == '-' && s[1] == '\0')		s = NULL;	/* set/clear traps */	while (*wp != NULL) {		p = gettrap(*wp++, TRUE);		if (p == NULL) {			bi_errorf("bad signal %s", wp[-1]);			return 1;		}		settrap(p, s);	}	return 0;}intc_exitreturn(wp)	char **wp;{	int how = LEXIT;	int n;	char *arg;	if (ksh_getopt(wp, &builtin_opt, null) == '?')		return 1;	arg = wp[builtin_opt.optind];	if (arg) {	    if (!getn(arg, &n)) {		    exstat = 1;		    warningf(TRUE, "%s: bad number", arg);	    } else		    exstat = n;	}	if (wp[0][0] == 'r') { /* return */		struct env *ep;		/* need to tell if this is exit or return so trap exit will		 * work right (POSIX)		 */		for (ep = e; ep; ep = ep->oenv)			if (STOP_RETURN(ep->type)) {				how = LRETURN;				break;			}	}	if (how == LEXIT && !really_exit && j_stopped_running()) {		really_exit = 1;		how = LSHELL;	}	quitenv();	/* get rid of any i/o redirections */	unwind(how);	/*NOTREACHED*/	return 0;}intc_brkcont(wp)	char **wp;{	int n, quit;	struct env *ep, *last_ep = (struct env *) 0;	char *arg;	if (ksh_getopt(wp, &builtin_opt, null) == '?')		return 1;	arg = wp[builtin_opt.optind];	if (!arg)		n = 1;	else if (!bi_getn(arg, &n))		return 1;	quit = n;	if (quit <= 0) {		/* at&t ksh does this for non-interactive shells only - weird */		bi_errorf("%s: bad value", arg);		return 1;	}	/* Stop at E_NONE, E_PARSE, E_FUNC, or E_INCL */	for (ep = e; ep && !STOP_BRKCONT(ep->type); ep = ep->oenv)		if (ep->type == E_LOOP) {			if (--quit == 0)				break;			ep->flags |= EF_BRKCONT_PASS;			last_ep = ep;		}	if (quit) {		/* at&t ksh doesn't print a message - just does what it		 * can.  We print a message 'cause it helps in debugging		 * scripts, but don't generate an error (ie, keep going).		 */		if (n == quit) {			warningf(TRUE, "%s: cannot %s", wp[0], wp[0]);			return 0; 		}		/* POSIX says if n is too big, the last enclosing loop		 * shall be used.  Doesn't say to print an error but we		 * do anyway 'cause the user messed up.		 */		last_ep->flags &= ~EF_BRKCONT_PASS;		warningf(TRUE, "%s: can only %s %d level(s)",			wp[0], wp[0], n - quit);	}	unwind(*wp[0] == 'b' ? LBREAK : LCONTIN);	/*NOTREACHED*/}intc_set(wp)	char **wp;{	int argi, setargs;	struct block *l = e->loc;	register char **owp = wp;	if (wp[1] == NULL) {		static const char *const args [] = { "set", "-", NULL };		return c_typeset((char **) args);	}	argi = parse_args(wp, OF_SET, &setargs);	if (argi < 0)		return 1;	/* set $# and $* */	if (setargs) {		owp = wp += argi - 1;		wp[0] = l->argv[0]; /* save $0 */		while (*++wp != NULL)			*wp = str_save(*wp, &l->area);		l->argc = wp - owp - 1;		l->argv = (char **) alloc(sizeofN(char *, l->argc+2), &l->area);		for (wp = l->argv; (*wp++ = *owp++) != NULL; )			;	}	/* POSIX says set exit status is 0, but old scripts that use	 * getopt(1), use the construct: set -- `getopt ab:c "$@"`	 * which assumes the exit value set will be that of the ``	 * (subst_exstat is cleared in execute() so that it will be 0	 * if there are no command substitutions).	 */	return Flag(FPOSIX) ? 0 : subst_exstat;}intc_unset(wp)	char **wp;{	register char *id;	int optc, unset_var = 1;	int ret = 0;	while ((optc = ksh_getopt(wp, &builtin_opt, "fv")) != EOF)		switch (optc) {		  case 'f':			unset_var = 0;			break;		  case 'v':			unset_var = 1;			break;		  case '?':			return 1;		}	wp += builtin_opt.optind;	for (; (id = *wp) != NULL; wp++)		if (unset_var) {	/* unset variable */			struct tbl *vp = global(id);			if (!(vp->flag & ISSET))			    ret = 1;			if ((vp->flag&RDONLY)) {				bi_errorf("%s is read only", vp->name);				return 1;			}			unset(vp, strchr(id, '[') ? 1 : 0);		} else {		/* unset function */			if (define(id, (struct op *) NULL))				ret = 1;		}	return ret;}intc_times(wp)	char **wp;{	struct tms all;	(void) ksh_times(&all);	shprintf("Shell: %8ss user ", clocktos(all.tms_utime));	shprintf("%8ss system\n", clocktos(all.tms_stime));	shprintf("Kids:  %8ss user ", clocktos(all.tms_cutime));	shprintf("%8ss system\n", clocktos(all.tms_cstime));	return 0;}/* * time pipeline (really a statement, not a built-in command) */inttimex(t, f)	struct op *t;	int f;{#define TF_NOARGS	BIT(0)#define TF_NOREAL	BIT(1)		/* don't report real time */#define TF_POSIX	BIT(2)		/* report in posix format */	int rv = 0;	struct tms t0, t1, tms;	clock_t t0t, t1t = 0;	int tf = 0;	extern clock_t j_usrtime, j_systime; /* computed by j_wait */	char opts[1];	t0t = ksh_times(&t0);	if (t->left) {		/*		 * Two ways of getting cpu usage of a command: just use t0		 * and t1 (which will get cpu usage from other jobs that		 * finish while we are executing t->left), or get the		 * cpu usage of t->left. at&t ksh does the former, while		 * pdksh tries to do the later (the j_usrtime hack doesn't		 * really work as it only counts the last job).		 */		j_usrtime = j_systime = 0;		if (t->left->type == TCOM)			t->left->str = opts;		opts[0] = 0;		rv = execute(t->left, f | XTIME);		tf |= opts[0];		t1t = ksh_times(&t1);	} else		tf = TF_NOARGS;	if (tf & TF_NOARGS) { /* ksh93 - report shell times (shell+kids) */		tf |= TF_NOREAL;		tms.tms_utime = t0.tms_utime + t0.tms_cutime;		tms.tms_stime = t0.tms_stime + t0.tms_cstime;	} else {		tms.tms_utime = t1.tms_utime - t0.tms_utime + j_usrtime;		tms.tms_stime = t1.tms_stime - t0.tms_stime + j_systime;	}	if (!(tf & TF_NOREAL))		shf_fprintf(shl_out,			tf & TF_POSIX ? "real %8s\n" : "%8ss real ",			clocktos(t1t - t0t));	shf_fprintf(shl_out, tf & TF_POSIX ? "user %8s\n" : "%8ss user ",		clocktos(tms.tms_utime));	shf_fprintf(shl_out, tf & TF_POSIX ? "sys  %8s\n" : "%8ss system\n",		clocktos(tms.tms_stime));	shf_flush(shl_out);	return rv;}voidtimex_hook(t, app)	struct op *t;	char ** volatile *app;{	char **wp = *app;	int optc;	int i, j;	Getopt opt;	ksh_getopt_reset(&opt, 0);	opt.optind = 0;	/* start at the start */	while ((optc = ksh_getopt(wp, &opt, ":p")) != EOF)		switch (optc) {		  case 'p':			t->str[0] |= TF_POSIX;			break;		  case '?':			errorf("time: -%s unknown option", opt.optarg);		  case ':':			errorf("time: -%s requires an argument",				opt.optarg);		}	/* Copy command words down over options. */	if (opt.optind != 0) {		for (i = 0; i < opt.optind; i++)			afree(wp[i], ATEMP);		for (i = 0, j = opt.optind; (wp[i] = wp[j]); i++, j++)			;	}	if (!wp[0])		t->str[0] |= TF_NOARGS;	*app = wp;}static char *clocktos(t)	clock_t t;{	static char temp[22]; /* enough for 64 bit clock_t */	register int i;	register char *cp = temp + sizeof(temp);	/* note: posix says must use max precision, ie, if clk_tck is	 * 1000, must print 3 places after decimal (if non-zero, else 1).	 */	if (CLK_TCK != 100)	/* convert to 1/100'ths */	    t = (t < 1000000000/CLK_TCK) ?		    (t * 100) / CLK_TCK : (t / CLK_TCK) * 100;	*--cp = '\0';	for (i = -2; i <= 0 || t > 0; i++) {		if (i == 0)			*--cp = '.';		*--cp = '0' + (char)(t%10);		t /= 10;	}	return cp;}/* exec with no args - args case is taken care of in comexec() */intc_exec(wp)	char ** wp;{	int i;	/* make sure redirects stay in place */	if (e->savefd != NULL) {		for (i = 0; i < NUFILE; i++) {			if (e->savefd[i] > 0)				close(e->savefd[i]);			/*			 * For ksh keep anything > 2 private,			 * for sh, let them be (POSIX says what			 * happens is unspecified and the bourne shell			 * keeps them open).			 */#ifdef KSH			if (i > 2 && e->savefd[i])				fd_clexec(i);#endif /* KSH */		}		e->savefd = NULL; 	}	return 0;}/* dummy function, special case in comexec() */intc_builtin(wp)	char ** wp;{	return 0;}extern	int c_test ARGS((char **wp));		/* in c_test.c */extern	int c_ulimit ARGS((char **wp));		/* in c_ulimit.c *//* A leading = means assignments before command are kept; * a leading * means a POSIX special builtin; * a leading + means a POSIX regular builtin * (* and + should not be combined). */const struct builtin shbuiltins [] = {	{"*=.", c_dot},	{"*=:", c_label},	{"[", c_test},	{"*=break", c_brkcont},	{"=builtin", c_builtin},	{"*=continue", c_brkcont},	{"*=eval", c_eval},	{"*=exec", c_exec},	{"*=exit", c_exitreturn},	{"+false", c_label},	{"*=return", c_exitreturn},	{"*=set", c_set},	{"*=shift", c_shift},	{"=times", c_times},	{"*=trap", c_trap},	{"+=wait", c_wait},	{"+read", c_read},	{"test", c_test},	{"+true", c_label},	{"ulimit", c_ulimit},	{"+umask", c_umask},	{"*=unset", c_unset},#ifdef OS2	/* In OS2, the first line of a file can be "extproc name", which	 * tells the command interpreter (cmd.exe) to use name to execute	 * the file.  For this to be useful, ksh must ignore commands	 * starting with extproc and this does the trick...	 */	{"extproc", c_label},#endif /* OS2 */	{NULL, NULL}};

⌨️ 快捷键说明

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