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

📄 except.c

📁 早期freebsd实现
💻 C
字号:
#include <setjmp.h>#include <signal.h>#include "rc.h"#include "jbwrap.h"/*   A return goes back stack frames to the last return. A break does   not. A signal goes to the last interactive level. (see below)*/bool nl_on_intr = TRUE;static Estack *estack;/* add an exception to the input stack. */extern void except(ecodes e, Edata data, Estack *ex) {	ex->prev = estack;	estack = ex;	estack->e = e;	estack->data = data;	if (e == eError || e == eBreak || e == eReturn)		estack->interactive = interactive;}/* remove an exception, restore last interactive value */extern void unexcept() {	switch (estack->e) {	default:		break;	case eError:		interactive = estack->interactive;		break;	case eArena:		restoreblock(estack->data.b);		break;	case eFifo:		unlink(estack->data.name);		break;	case eFd:		close(estack->data.fd);		break;	}	estack = estack->prev;}/*   Raise an exception. The rules are pretty complicated: you can return   from a loop inside a function, but you can't break from a function   inside of a loop. On errors, rc_raise() goes back to the LAST   INTERACTIVE stack frame. If no such frame exists, then rc_raise()   exits the shell.  This is what happens, say, when there is a syntax   error in a noninteractive shell script. While traversing the   exception stack backwards, rc_raise() also removes input sources   (closing file-descriptors, etc.) and pops instances of variables   that have been pushed onto the variable stack (e.g., for a function   call (for $*) or a local assignment).*/extern void rc_raise(ecodes e) {	if (e == eError && rc_pid != getpid())		exit(1); /* child processes exit on an error/signal */	for (; estack != NULL; estack = estack->prev)		if (estack->e != e) {			if (e == eBreak && estack->e != eArena)				rc_error("break outside of loop");			else if (e == eReturn && estack->e == eError) /* can return from loops inside functions */				rc_error("return outside of function");			switch (estack->e) {			default:				break;			case eVarstack:				varrm(estack->data.name, TRUE);				break;			case eArena:				restoreblock(estack->data.b);				break;			case eFifo:				unlink(estack->data.name);				break;			case eFd:				close(estack->data.fd);				break;			}		} else {			if (e == eError && !estack->interactive) {				popinput();			} else {				Jbwrap *j = estack->data.jb;				interactive = estack->interactive;				estack = estack->prev;				longjmp(j->j, 1);			}		}	rc_exit(1); /* top of exception stack */}extern bool outstanding_cmdarg() {	return estack->e == eFifo || estack->e == eFd;}extern void pop_cmdarg(bool remove) {	for (; estack != NULL; estack = estack->prev)		switch (estack->e) {		case eFifo:			if (remove)				unlink(estack->data.name);			break;		case eFd:			if (remove)				close(estack->data.fd);			break;		default:			return;		}}/* exception handlers */extern void rc_error(char *s) {	pr_error(s);	set(FALSE);	redirq = NULL;	cond = FALSE; /* no longer inside conditional */	rc_raise(eError);}extern void sigint(int s) {	if (s != SIGINT)		panic("s != SIGINT in sigint catcher");	/* this is the newline you see when you hit ^C while typing a command */	if (nl_on_intr)		fprint(2, "\n");	nl_on_intr = TRUE;	redirq = NULL;	cond = FALSE;	rc_raise(eError);}

⌨️ 快捷键说明

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