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

📄 sem.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1980, 1991, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)sem.c	8.1 (Berkeley) 5/31/93";#endif /* not lint */#include <sys/param.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <errno.h>#include <fcntl.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#if __STDC__# include <stdarg.h>#else# include <varargs.h>#endif#include "csh.h"#include "proc.h"#include "extern.h"static void	 vffree __P((int));static Char	*splicepipe __P((struct command *t, Char *));static void	 doio __P((struct command *t, int *, int *));static void	 chkclob __P((char *));voidexecute(t, wanttty, pipein, pipeout)    register struct command *t;    int     wanttty, *pipein, *pipeout;{    bool    forked = 0;    struct biltins *bifunc;    int     pid = 0;    int     pv[2];    static sigset_t csigmask;    static sigset_t ocsigmask;    static int onosigchld = 0;    static int nosigchld = 0;    UNREGISTER(forked);    UNREGISTER(bifunc);    UNREGISTER(wanttty);    if (t == 0)	return;    if (t->t_dflg & F_AMPERSAND)	wanttty = 0;    switch (t->t_dtyp) {    case NODE_COMMAND:	if ((t->t_dcom[0][0] & (QUOTE | TRIM)) == QUOTE)	    (void) Strcpy(t->t_dcom[0], t->t_dcom[0] + 1);	if ((t->t_dflg & F_REPEAT) == 0)	    Dfix(t);		/* $ " ' \ */	if (t->t_dcom[0] == 0)	    return;	/* fall into... */    case NODE_PAREN:	if (t->t_dflg & F_PIPEOUT)	    mypipe(pipeout);	/*	 * Must do << early so parent will know where input pointer should be.	 * If noexec then this is all we do.	 */	if (t->t_dflg & F_READ) {	    (void) close(0);	    heredoc(t->t_dlef);	    if (noexec)		(void) close(0);	}	set(STRstatus, Strsave(STR0));	/*	 * This mess is the necessary kludge to handle the prefix builtins:	 * nice, nohup, time.  These commands can also be used by themselves,	 * and this is not handled here. This will also work when loops are	 * parsed.	 */	while (t->t_dtyp == NODE_COMMAND)	    if (eq(t->t_dcom[0], STRnice))		if (t->t_dcom[1])		    if (strchr("+-", t->t_dcom[1][0]))			if (t->t_dcom[2]) {			    setname("nice");			    t->t_nice =				getn(t->t_dcom[1]);			    lshift(t->t_dcom, 2);			    t->t_dflg |= F_NICE;			}			else			    break;		    else {			t->t_nice = 4;			lshift(t->t_dcom, 1);			t->t_dflg |= F_NICE;		    }		else		    break;	    else if (eq(t->t_dcom[0], STRnohup))		if (t->t_dcom[1]) {		    t->t_dflg |= F_NOHUP;		    lshift(t->t_dcom, 1);		}		else		    break;	    else if (eq(t->t_dcom[0], STRtime))		if (t->t_dcom[1]) {		    t->t_dflg |= F_TIME;		    lshift(t->t_dcom, 1);		}		else		    break;	    else		break;	/* is it a command */	if (t->t_dtyp == NODE_COMMAND) {	    /*	     * Check if we have a builtin function and remember which one.	     */	    bifunc = isbfunc(t); 	    if (noexec) {		/*		 * Continue for builtins that are part of the scripting language		 */		if (bifunc->bfunct != dobreak   && bifunc->bfunct != docontin &&		    bifunc->bfunct != doelse    && bifunc->bfunct != doend    &&		    bifunc->bfunct != doforeach && bifunc->bfunct != dogoto   &&		    bifunc->bfunct != doif      && bifunc->bfunct != dorepeat &&		    bifunc->bfunct != doswbrk   && bifunc->bfunct != doswitch &&		    bifunc->bfunct != dowhile   && bifunc->bfunct != dozip)		    break;	    }	}	else {			/* not a command */	    bifunc = NULL;	    if (noexec)		break;	}	/*	 * We fork only if we are timed, or are not the end of a parenthesized	 * list and not a simple builtin function. Simple meaning one that is	 * not pipedout, niced, nohupped, or &'d. It would be nice(?) to not	 * fork in some of these cases.	 */	/*	 * Prevent forking cd, pushd, popd, chdir cause this will cause the	 * shell not to change dir!	 */	if (bifunc && (bifunc->bfunct == dochngd ||		       bifunc->bfunct == dopushd ||		       bifunc->bfunct == dopopd))	    t->t_dflg &= ~(F_NICE);	if (((t->t_dflg & F_TIME) || ((t->t_dflg & F_NOFORK) == 0 &&	     (!bifunc || t->t_dflg &	      (F_PIPEOUT | F_AMPERSAND | F_NICE | F_NOHUP)))) ||	/*	 * We have to fork for eval too.	 */	    (bifunc && (t->t_dflg & (F_PIPEIN | F_PIPEOUT)) != 0 &&	     bifunc->bfunct == doeval))	    if (t->t_dtyp == NODE_PAREN ||		t->t_dflg & (F_REPEAT | F_AMPERSAND) || bifunc) {		forked++;		/*		 * We need to block SIGCHLD here, so that if the process does		 * not die before we can set the process group		 */		if (wanttty >= 0 && !nosigchld) {		    csigmask = sigblock(sigmask(SIGCHLD));		    nosigchld = 1;		}		pid = pfork(t, wanttty);		if (pid == 0 && nosigchld) {		    (void) sigsetmask(csigmask);		    nosigchld = 0;		}		else if (pid != 0 && (t->t_dflg & F_AMPERSAND))		    backpid = pid;	    }	    else {		int     ochild, osetintr, ohaderr, odidfds;		int     oSHIN, oSHOUT, oSHERR, oOLDSTD, otpgrp;		sigset_t omask;		/*		 * Prepare for the vfork by saving everything that the child		 * corrupts before it exec's. Note that in some signal		 * implementations which keep the signal info in user space		 * (e.g. Sun's) it will also be necessary to save and restore		 * the current sigvec's for the signals the child touches		 * before it exec's.		 */		if (wanttty >= 0 && !nosigchld && !noexec) {		    csigmask = sigblock(sigmask(SIGCHLD));		    nosigchld = 1;		}		omask = sigblock(sigmask(SIGCHLD) | sigmask(SIGINT));		ochild = child;		osetintr = setintr;		ohaderr = haderr;		odidfds = didfds;		oSHIN = SHIN;		oSHOUT = SHOUT;		oSHERR = SHERR;		oOLDSTD = OLDSTD;		otpgrp = tpgrp;		ocsigmask = csigmask;		onosigchld = nosigchld;		Vsav = Vdp = 0;		Vexpath = 0;		Vt = 0;		pid = vfork();		if (pid < 0) {		    (void) sigsetmask(omask);		    stderror(ERR_NOPROC);		}		forked++;		if (pid) {	/* parent */		    child = ochild;		    setintr = osetintr;		    haderr = ohaderr;		    didfds = odidfds;		    SHIN = oSHIN;		    SHOUT = oSHOUT;		    SHERR = oSHERR;		    OLDSTD = oOLDSTD;		    tpgrp = otpgrp;		    csigmask = ocsigmask;		    nosigchld = onosigchld;		    xfree((ptr_t) Vsav);		    Vsav = 0;		    xfree((ptr_t) Vdp);		    Vdp = 0;		    xfree((ptr_t) Vexpath);		    Vexpath = 0;		    blkfree((Char **) Vt);		    Vt = 0;		    /* this is from pfork() */		    palloc(pid, t);		    (void) sigsetmask(omask);		}		else {		/* child */		    /* this is from pfork() */		    int     pgrp;		    bool    ignint = 0;		    if (nosigchld) {			(void) sigsetmask(csigmask);			nosigchld = 0;		    }		    if (setintr)			ignint =			    (tpgrp == -1 &&			     (t->t_dflg & F_NOINTERRUPT))			    || (gointr && eq(gointr, STRminus));		    pgrp = pcurrjob ? pcurrjob->p_jobid : getpid();		    child++;		    if (setintr) {			setintr = 0;			if (ignint) {			    (void) signal(SIGINT, SIG_IGN);			    (void) signal(SIGQUIT, SIG_IGN);			}			else {			    (void) signal(SIGINT, vffree);			    (void) signal(SIGQUIT, SIG_DFL);			}			if (wanttty >= 0) {			    (void) signal(SIGTSTP, SIG_DFL);			    (void) signal(SIGTTIN, SIG_DFL);			    (void) signal(SIGTTOU, SIG_DFL);			}			(void) signal(SIGTERM, parterm);		    }

⌨️ 快捷键说明

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