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

📄 c_ksh.c

📁 一个开放源代码的 AT&T 的 Korn Shell 的复制品, 支持大多数 ksh89 的特性。
💻 C
📖 第 1 页 / 共 3 页
字号:
		ap = tenter(t, alias, h);		ap->type = tflag ? CTALIAS : CALIAS;		/* Are we setting the value or just some flags? */		if ((val && !tflag) || (!val && tflag && !Uflag)) {			if (ap->flag&ALLOC) {				ap->flag &= ~(ALLOC|ISSET);				afree((void*)ap->val.s, APERM);			}			/* ignore values for -t (at&t ksh does this) */			newval = tflag ? search(alias, path, X_OK, (int *) 0)					: val;			if (newval) {				ap->val.s = str_save(newval, APERM);				ap->flag |= ALLOC|ISSET;			} else				ap->flag &= ~ISSET;		}		ap->flag |= DEFINED;		if (prefix == '+')			ap->flag &= ~xflag;		else			ap->flag |= xflag;		if (val)			afree(alias, ATEMP);	}	return rv;}intc_unalias(wp)	char **wp;{	register struct table *t = &aliases;	register struct tbl *ap;	int rv = 0, all = 0;	int optc;	while ((optc = ksh_getopt(wp, &builtin_opt, "adt")) != EOF)		switch (optc) {		  case 'a':			all = 1;			break;		  case 'd':			t = &homedirs;			break;		  case 't':			t = &taliases;			break;		  case '?':			return 1;		}	wp += builtin_opt.optind;	for (; *wp != NULL; wp++) {		ap = tsearch(t, *wp, hash(*wp));		if (ap == NULL) {			rv = 1;	/* POSIX */			continue;		}		if (ap->flag&ALLOC) {			ap->flag &= ~(ALLOC|ISSET);			afree((void*)ap->val.s, APERM);		}		ap->flag &= ~(DEFINED|ISSET|EXPORT);	}	if (all) {		struct tstate ts;		for (twalk(&ts, t); (ap = tnext(&ts)); ) {			if (ap->flag&ALLOC) {				ap->flag &= ~(ALLOC|ISSET);				afree((void*)ap->val.s, APERM);			}			ap->flag &= ~(DEFINED|ISSET|EXPORT);		}	}	return rv;}#ifdef KSHintc_let(wp)	char **wp;{	int rv = 1;	long val;	if (wp[1] == (char *) 0) /* at&t ksh does this */		bi_errorf("no arguments");	else		for (wp++; *wp; wp++)			if (!evaluate(*wp, &val, KSH_RETURN_ERROR)) {				rv = 2;	/* distinguish error from zero result */				break;			} else				rv = val == 0;	return rv;}#endif /* KSH */intc_jobs(wp)	char **wp;{	int optc;	int flag = 0;	int nflag = 0;	int rv = 0;	while ((optc = ksh_getopt(wp, &builtin_opt, "lpnz")) != EOF)		switch (optc) {		  case 'l':			flag = 1;			break;		  case 'p':			flag = 2;			break;		  case 'n':			nflag = 1;			break;		  case 'z':	/* debugging: print zombies */			nflag = -1;			break;		  case '?':			return 1;		}	wp += builtin_opt.optind;	if (!*wp)		if (j_jobs((char *) 0, flag, nflag))			rv = 1;	else		for (; *wp; wp++)			if (j_jobs(*wp, flag, nflag))				rv = 1;	return rv;}#ifdef JOBSintc_fgbg(wp)	char **wp;{	int bg = strcmp(*wp, "bg") == 0;	int UNINITIALIZED(rv);	if (!Flag(FMONITOR)) {		bi_errorf("job control not enabled");		return 1;	}	if (ksh_getopt(wp, &builtin_opt, null) == '?')		return 1;	wp += builtin_opt.optind;	if (*wp)		for (; *wp; wp++)			rv = j_resume(*wp, bg);	else		rv = j_resume("%%", bg);	/* POSIX says fg shall return 0 (unless an error occurs).	 * at&t ksh returns the exit value of the job...	 */	return (bg || Flag(FPOSIX)) ? 0 : rv;}#endifstruct kill_info {	int num_width;	int name_width;};static char *kill_fmt_entry ARGS((void *arg, int i, char *buf, int buflen));/* format a single kill item */static char *kill_fmt_entry(arg, i, buf, buflen)	void *arg;	int i;	char *buf;	int buflen;{	struct kill_info *ki = (struct kill_info *) arg;	i++;	if (sigtraps[i].name)		shf_snprintf(buf, buflen, "%*d %*s %s",			ki->num_width, i,			ki->name_width, sigtraps[i].name,			sigtraps[i].mess);	else		shf_snprintf(buf, buflen, "%*d %*d %s",			ki->num_width, i,			ki->name_width, sigtraps[i].signal,			sigtraps[i].mess);	return buf;}intc_kill(wp)	char **wp;{	Trap *t = (Trap *) 0;	char *p;	int lflag = 0;	int i, n, rv, sig;	/* assume old style options if -digits or -UPPERCASE */	if ((p = wp[1]) && *p == '-' && (digit(p[1]) || isupper(p[1]))) {		if (!(t = gettrap(p + 1, TRUE))) {			bi_errorf("bad signal `%s'", p + 1);			return 1;		}		i = (wp[2] && strcmp(wp[2], "--") == 0) ? 3 : 2;	} else {		int optc;		while ((optc = ksh_getopt(wp, &builtin_opt, "ls:")) != EOF)			switch (optc) {			  case 'l':				lflag = 1;				break;			  case 's':				if (!(t = gettrap(builtin_opt.optarg, TRUE))) {					bi_errorf("bad signal `%s'",						builtin_opt.optarg);					return 1;				}			  case '?':				return 1;			}		i = builtin_opt.optind;	}	if ((lflag && t) || (!wp[i] && !lflag)) {		shf_fprintf(shl_out,"Usage: kill [ -s signame | -signum | -signame ] {pid|job}...\n\       kill -l [exit_status]\n"			);		bi_errorf(null);		return 1;	}	if (lflag) {		if (wp[i]) {			for (; wp[i]; i++) {				if (!bi_getn(wp[i], &n))					return 1;				if (n > 128 && n < 128 + SIGNALS)					n -= 128;				if (n > 0 && n < SIGNALS && sigtraps[n].name)					shprintf("%s\n", sigtraps[n].name);				else					shprintf("%d\n", n);			}		} else if (Flag(FPOSIX)) {			p = null;			for (i = 1; i < SIGNALS; i++, p = space)				if (sigtraps[i].name)					shprintf("%s%s", p, sigtraps[i].name);			shprintf(newline);		} else {			int w, i;			int mess_width;			struct kill_info ki;			for (i = SIGNALS, ki.num_width = 1; i >= 10; i /= 10)				ki.num_width++;			ki.name_width = mess_width = 0;			for (i = 0; i < SIGNALS; i++) {				w = sigtraps[i].name ? strlen(sigtraps[i].name)						     : ki.num_width;				if (w > ki.name_width)					ki.name_width = w;				w = strlen(sigtraps[i].mess);				if (w > mess_width)					mess_width = w;			}			print_columns(shl_stdout, SIGNALS - 1,				kill_fmt_entry, (void *) &ki,				ki.num_width + ki.name_width + mess_width + 3);		}		return 0;	}	rv = 0;	sig = t ? t->signal : SIGTERM;	for (; (p = wp[i]); i++) {		if (*p == '%') {			if (j_kill(p, sig))				rv = 1;		} else if (!getn(p, &n)) {			bi_errorf("%s: arguments must be jobs or process ids",				p);			rv = 1;		} else {			/* use killpg if < -1 since -1 does special things for			 * some non-killpg-endowed kills			 */			if ((n < -1 ? killpg(-n, sig) : kill(n, sig)) < 0) {				bi_errorf("%s: %s", p, strerror(errno));				rv = 1;			}		}	}	return rv;}voidgetopts_reset(val)	int val;{	if (val >= 1) {		ksh_getopt_reset(&user_opt,			GF_NONAME | (Flag(FPOSIX) ? 0 : GF_PLUSOPT));		user_opt.optind = user_opt.uoptind = val;	}}intc_getopts(wp)	char **wp;{	int	argc;	const char *options;	const char *var;	int	optc;	int	ret;	char	buf[3];	struct tbl *vq, *voptarg;	if (ksh_getopt(wp, &builtin_opt, null) == '?')		return 1;	wp += builtin_opt.optind;	options = *wp++;	if (!options) {		bi_errorf("missing options argument");		return 1;	}	var = *wp++;	if (!var) {		bi_errorf("missing name argument");		return 1;	}	if (!*var || *skip_varname(var, TRUE)) {		bi_errorf("%s: is not an identifier", var);		return 1;	}	if (e->loc->next == (struct block *) 0) {		internal_errorf(0, "c_getopts: no argv");		return 1;	}	/* Which arguments are we parsing... */	if (*wp == (char *) 0)		wp = e->loc->next->argv;	else		*--wp = e->loc->next->argv[0];	/* Check that our saved state won't cause a core dump... */	for (argc = 0; wp[argc]; argc++)		;	if (user_opt.optind > argc	    || (user_opt.p != 0		&& user_opt.p > strlen(wp[user_opt.optind - 1])))	{	      bi_errorf("arguments changed since last call");	      return 1;	}	user_opt.optarg = (char *) 0;	optc = ksh_getopt(wp, &user_opt, options);	if (optc >= 0 && optc != '?' && (user_opt.info & GI_PLUS)) {		buf[0] = '+';		buf[1] = optc;		buf[2] = '\0';	} else {		/* POSIX says var is set to ? at end-of-options, at&t ksh		 * sets it to null - we go with POSIX...		 */		buf[0] = optc < 0 ? '?' : optc;		buf[1] = '\0';	}	/* at&t ksh does not change OPTIND if it was an unknown option.	 * Scripts counting on this are prone to break... (ie, don't count	 * on this staying).	 */	if (optc != '?') {		user_opt.uoptind = user_opt.optind;	}	voptarg = global("OPTARG");	voptarg->flag &= ~RDONLY;	/* at&t ksh clears ro and int */	/* Paranoia: ensure no bizarre results. */	if (voptarg->flag & INTEGER)	    typeset("OPTARG", 0, INTEGER, 0, 0);	if (user_opt.optarg == (char *) 0)		unset(voptarg, 0);	else		/* This can't fail (have cleared readonly/integer) */		setstr(voptarg, user_opt.optarg, KSH_RETURN_ERROR);	ret = 0;	vq = global(var);	/* Error message already printed (integer, readonly) */	if (!setstr(vq, buf, KSH_RETURN_ERROR))	    ret = 1;	if (Flag(FEXPORT))		typeset(var, EXPORT, 0, 0, 0);	return optc < 0 ? 1 : ret;}#ifdef EMACSintc_bind(wp)	char **wp;{	int rv = 0, macro = 0, list = 0;	register char *cp;	int optc;	while ((optc = ksh_getopt(wp, &builtin_opt, "lm")) != EOF)		switch (optc) {		  case 'l':			list = 1;			break;		  case 'm':			macro = 1;			break;		  case '?':			return 1;		}	wp += builtin_opt.optind;	if (*wp == NULL)	/* list all */		rv = x_bind((char*)NULL, (char*)NULL, 0, list);	for (; *wp != NULL; wp++) {		cp = strchr(*wp, '=');		if (cp != NULL)			*cp++ = '\0';		if (x_bind(*wp, cp, macro, 0))			rv = 1;	}	return rv;}#endif/* 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 kshbuiltins [] = {	{"+alias", c_alias},	/* no =: at&t manual wrong */	{"+cd", c_cd},	{"+command", c_command},	{"echo", c_print}, 	{"*=export", c_typeset},#ifdef HISTORY	{"+fc", c_fc},#endif /* HISTORY */	{"+getopts", c_getopts},	{"+jobs", c_jobs},	{"+kill", c_kill},#ifdef KSH	{"let", c_let},#endif /* KSH */	{"print", c_print},	{"pwd", c_pwd}, 	{"*=readonly", c_typeset},	{"=typeset", c_typeset},	{"+unalias", c_unalias},	{"whence", c_whence},#ifdef JOBS	{"+bg", c_fgbg},	{"+fg", c_fgbg},#endif#ifdef EMACS	{"bind", c_bind},#endif	{NULL, NULL}};

⌨️ 快捷键说明

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