コード例 #1
0
ファイル: c_sh.c プロジェクト: tomgrean/kash
int
c_exitreturn(char **wp)
{
	int how = LEXIT;
	int n;
	char *arg;

	if (!Flag(FPOSIX) 			// not posix
	    && *wp && *(wp + 1) && !*(wp + 2))  // only one argument passed
		arg=*(wp + 1);		        // code regardless of starting with '-' or not
	else {
		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;
}
コード例 #2
0
ファイル: c_sh.c プロジェクト: Bluerise/bitrig
int
c_exitreturn(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(NULL);	/* get rid of any i/o redirections */
	unwind(how);
	/* NOTREACHED */
	return 0;
}
コード例 #3
0
ファイル: main.c プロジェクト: MIPS/external-mksh
/*
 * run the commands from the input source, returning status.
 */
int
shell(Source * volatile s, volatile int level)
{
	struct op *t;
	volatile bool wastty = tobool(s->flags & SF_TTY);
	volatile uint8_t attempts = 13;
	volatile bool interactive = (level == 0) && Flag(FTALKING);
	volatile bool sfirst = true;
	Source *volatile old_source = source;
	int i;

	newenv(level == 2 ? E_EVAL : E_PARSE);
	if (interactive)
		really_exit = false;
	switch ((i = kshsetjmp(e->jbuf))) {
	case 0:
		break;
	case LBREAK:
	case LCONTIN:
		if (level != 2) {
			source = old_source;
			quitenv(NULL);
			internal_errorf(Tf_cant_s, Tshell,
			    i == LBREAK ? Tbreak : Tcontinue);
			/* NOTREACHED */
		}
		/* assert: interactive == false */
		/* FALLTHROUGH */
	case LINTR:
		/* we get here if SIGINT not caught or ignored */
	case LERROR:
	case LSHELL:
		if (interactive) {
			if (i == LINTR)
				shellf("\n");
			/*
			 * Reset any eof that was read as part of a
			 * multiline command.
			 */
			if (Flag(FIGNOREEOF) && s->type == SEOF && wastty)
				s->type = SSTDIN;
			/*
			 * Used by exit command to get back to
			 * top level shell. Kind of strange since
			 * interactive is set if we are reading from
			 * a tty, but to have stopped jobs, one only
			 * needs FMONITOR set (not FTALKING/SF_TTY)...
			 */
			/* toss any input we have so far */
			yyrecursive_pop(true);
			s->start = s->str = null;
			retrace_info = NULL;
			herep = heres;
			break;
		}
		/* FALLTHROUGH */
	case LEXIT:
	case LLEAVE:
	case LRETURN:
		source = old_source;
		quitenv(NULL);
		/* keep on going */
		unwind(i);
		/* NOTREACHED */
	default:
		source = old_source;
		quitenv(NULL);
		internal_errorf(Tunexpected_type, Tunwind, Tshell, i);
		/* NOTREACHED */
	}
	while (/* CONSTCOND */ 1) {
		if (trap)
			runtraps(0);

		if (s->next == NULL) {
			if (Flag(FVERBOSE))
				s->flags |= SF_ECHO;
			else
				s->flags &= ~SF_ECHO;
		}
		if (interactive) {
			j_notify();
			set_prompt(PS1, s);
		}
		t = compile(s, sfirst, true);
		if (interactive)
			histsave(&s->line, NULL, HIST_FLUSH, true);
		sfirst = false;
		if (!t)
			goto source_no_tree;
		if (t->type == TEOF) {
			if (wastty && Flag(FIGNOREEOF) && --attempts > 0) {
				shellf("Use 'exit' to leave mksh\n");
				s->type = SSTDIN;
			} else if (wastty && !really_exit &&
			    j_stopped_running()) {
				really_exit = true;
				s->type = SSTDIN;
			} else {
				/*
				 * this for POSIX which says EXIT traps
				 * shall be taken in the environment
				 * immediately after the last command
				 * executed.
				 */
				if (level == 0)
					unwind(LEXIT);
				break;
			}
		} else if ((s->flags & SF_MAYEXEC) && t->type == TCOM)
			t->u.evalflags |= DOTCOMEXEC;
		if (!Flag(FNOEXEC) || (s->flags & SF_TTY))
			exstat = execute(t, 0, NULL) & 0xFF;

		if (t->type != TEOF && interactive && really_exit)
			really_exit = false;

 source_no_tree:
		reclaim();
	}
	quitenv(NULL);
	source = old_source;
	return (exstat & 0xFF);
}