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

📄 csh.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
	(void) signal(SIGINT, pintr);	(void) sigblock(sigmask(SIGINT));	(void) signal(SIGTERM, SIG_IGN);	if (quitit == 0 && arginp == 0) {	    (void) signal(SIGTSTP, SIG_IGN);	    (void) signal(SIGTTIN, SIG_IGN);	    (void) signal(SIGTTOU, SIG_IGN);	    /*	     * Wait till in foreground, in case someone stupidly runs csh &	     * dont want to try to grab away the tty.	     */	    if (isatty(FSHERR))		f = FSHERR;	    else if (isatty(FSHOUT))		f = FSHOUT;	    else if (isatty(OLDSTD))		f = OLDSTD;	    else		f = -1;    retry:	    if ((tpgrp = tcgetpgrp(f)) != -1) {		if (tpgrp != shpgrp) {		    sig_t old = signal(SIGTTIN, SIG_DFL);		    (void) kill(0, SIGTTIN);		    (void) signal(SIGTTIN, old);		    goto retry;		}		opgrp = shpgrp;		shpgrp = getpid();		tpgrp = shpgrp;		/*		 * Setpgid will fail if we are a session leader and		 * mypid == mypgrp (POSIX 4.3.3)		 */		if (opgrp != shpgrp)		    if (setpgid(0, shpgrp) == -1)			goto notty;		/*		 * We do that after we set our process group, to make sure		 * that the process group belongs to a process in the same		 * session as the tty (our process and our group) (POSIX 7.2.4)		 */		if (tcsetpgrp(f, shpgrp) == -1)		    goto notty;		(void) ioctl(dcopy(f, FSHTTY), FIOCLEX, NULL);	    }	    if (tpgrp == -1) {notty:		(void) fprintf(csherr, "Warning: no access to tty (%s).\n",			       strerror(errno));		(void) fprintf(csherr, "Thus no job control in this shell.\n");	    }	}    }    if ((setintr == 0) && (parintr == SIG_DFL))	setintr = 1;    (void) signal(SIGCHLD, pchild);	/* while signals not ready */    /*     * Set an exit here in case of an interrupt or error reading the shell     * start-up scripts.     */    reenter = setexit();	/* PWP */    haderr = 0;			/* In case second time through */    if (!fast && reenter == 0) {	/* Will have value(STRhome) here because set fast if don't */	{	    int     osetintr = setintr;	    sig_t   oparintr = parintr;	    sigset_t omask = sigblock(sigmask(SIGINT));	    setintr = 0;	    parintr = SIG_IGN;	/* Disable onintr */#ifdef _PATH_DOTCSHRC	    (void) srcfile(_PATH_DOTCSHRC, 0, 0);#endif	    if (!fast && !arginp && !onelflg)		dohash(NULL, NULL);#ifdef _PATH_DOTLOGIN	    if (loginsh)		(void) srcfile(_PATH_DOTLOGIN, 0, 0);#endif	    (void) sigsetmask(omask);	    setintr = osetintr;	    parintr = oparintr;	}	(void) srccat(value(STRhome), STRsldotcshrc);	if (!fast && !arginp && !onelflg && !havhash)	    dohash(NULL, NULL);	/*	 * Source history before .login so that it is available in .login	 */	if ((cp = value(STRhistfile)) != STRNULL)	    loadhist[2] = cp;	dosource(loadhist, NULL);        if (loginsh)	      (void) srccat(value(STRhome), STRsldotlogin);    }    /*     * Now are ready for the -v and -x flags     */    if (nverbose)	setNS(STRverbose);    if (nexececho)	setNS(STRecho);    /*     * All the rest of the world is inside this call. The argument to process     * indicates whether it should catch "error unwinds".  Thus if we are a     * interactive shell our call here will never return by being blown past on     * an error.     */    process(setintr);    /*     * Mop-up.     */    if (intty) {	if (loginsh) {	    (void) fprintf(cshout, "logout\n");	    (void) close(SHIN);	    child = 1;	    goodbye();	}	else {	    (void) fprintf(cshout, "exit\n");	}    }    rechist();    exitstat();    return (0);}voiduntty(){    if (tpgrp > 0) {	(void) setpgid(0, opgrp);	(void) tcsetpgrp(FSHTTY, opgrp);    }}voidimportpath(cp)    Char   *cp;{    register int i = 0;    register Char *dp;    register Char **pv;    int     c;    for (dp = cp; *dp; dp++)	if (*dp == ':')	    i++;    /*     * i+2 where i is the number of colons in the path. There are i+1     * directories in the path plus we need room for a zero terminator.     */    pv = (Char **) xcalloc((size_t) (i + 2), sizeof(Char **));    dp = cp;    i = 0;    if (*dp)	for (;;) {	    if ((c = *dp) == ':' || c == 0) {		*dp = 0;		if ((*cp != '/' || *cp == '\0') && (euid == 0 || uid == 0)) 		    (void) fprintf(csherr,	    "Warning: imported path contains relative components\n");		pv[i++] = Strsave(*cp ? cp : STRdot);		if (c) {		    cp = dp + 1;		    *dp = ':';		}		else		    break;	    }	    dp++;	}    pv[i] = 0;    set1(STRpath, pv, &shvhed);}/* * Source to the file which is the catenation of the argument names. */static intsrccat(cp, dp)    Char   *cp, *dp;{    register Char *ep = Strspl(cp, dp);    char   *ptr = short2str(ep);    xfree((ptr_t) ep);    return srcfile(ptr, mflag ? 0 : 1, 0);}/* * Source to a file putting the file descriptor in a safe place (> 2). */static intsrcfile(f, onlyown, flag)    char   *f;    bool    onlyown, flag;{    register int unit;    if ((unit = open(f, O_RDONLY)) == -1)	return 0;    unit = dmove(unit, -1);    (void) ioctl(unit, FIOCLEX, NULL);    srcunit(unit, onlyown, flag);    return 1;}/* * Source to a unit.  If onlyown it must be our file or our group or * we don't chance it.	This occurs on ".cshrc"s and the like. */int     insource;static voidsrcunit(unit, onlyown, hflg)    register int unit;    bool    onlyown, hflg;{    /* We have to push down a lot of state here */    /* All this could go into a structure */    int     oSHIN = -1, oldintty = intty, oinsource = insource;    struct whyle *oldwhyl = whyles;    Char   *ogointr = gointr, *oarginp = arginp;    Char   *oevalp = evalp, **oevalvec = evalvec;    int     oonelflg = onelflg;    bool    oenterhist = enterhist;    char    OHIST = HIST;    bool    otell = cantell;    struct Bin saveB;    volatile sigset_t omask;    jmp_buf oldexit;    /* The (few) real local variables */    int     my_reenter;    if (unit < 0)	return;    if (didfds)	donefds();    if (onlyown) {	struct stat stb;	if (fstat(unit, &stb) < 0) {	    (void) close(unit);	    return;	}    }    /*     * There is a critical section here while we are pushing down the input     * stream since we have stuff in different structures. If we weren't     * careful an interrupt could corrupt SHIN's Bin structure and kill the     * shell.     *     * We could avoid the critical region by grouping all the stuff in a single     * structure and pointing at it to move it all at once.  This is less     * efficient globally on many variable references however.     */    insource = 1;    getexit(oldexit);    omask = 0;    if (setintr)	omask = sigblock(sigmask(SIGINT));    /* Setup the new values of the state stuff saved above */    bcopy((char *) &B, (char *) &(saveB), sizeof(B));    fbuf = NULL;    fseekp = feobp = fblocks = 0;    oSHIN = SHIN, SHIN = unit, arginp = 0, onelflg = 0;    intty = isatty(SHIN), whyles = 0, gointr = 0;    evalvec = 0;    evalp = 0;    enterhist = hflg;    if (enterhist)	HIST = '\0';    /*     * Now if we are allowing commands to be interrupted, we let ourselves be     * interrupted.     */    if (setintr)	(void) sigsetmask(omask);    settell();    if ((my_reenter = setexit()) == 0)	process(0);		/* 0 -> blow away on errors */    if (setintr)	(void) sigsetmask(omask);    if (oSHIN >= 0) {	register int i;	/* We made it to the new state... free up its storage */	/* This code could get run twice but xfree doesn't care */	for (i = 0; i < fblocks; i++)	    xfree((ptr_t) fbuf[i]);	xfree((ptr_t) fbuf);	/* Reset input arena */	bcopy((char *) &(saveB), (char *) &B, sizeof(B));	(void) close(SHIN), SHIN = oSHIN;	arginp = oarginp, onelflg = oonelflg;	evalp = oevalp, evalvec = oevalvec;	intty = oldintty, whyles = oldwhyl, gointr = ogointr;	if (enterhist)	    HIST = OHIST;	enterhist = oenterhist;	cantell = otell;    }    resexit(oldexit);    /*     * If process reset() (effectively an unwind) then we must also unwind.     */    if (my_reenter)	stderror(ERR_SILENT);    insource = oinsource;}voidrechist(){    Char    buf[BUFSIZ], hbuf[BUFSIZ], *hfile;    int     fp, ftmp, oldidfds;    struct  varent *shist;    if (!fast) {	/*	 * If $savehist is just set, we use the value of $history	 * else we use the value in $savehist	 */	if ((shist = adrof(STRsavehist)) != NULL) {	    if (shist->vec[0][0] != '\0')		(void) Strcpy(hbuf, shist->vec[0]);	    else if ((shist = adrof(STRhistory)) && shist->vec[0][0] != '\0')		(void) Strcpy(hbuf, shist->vec[0]);	    else		return;	}	else  	    return;  	if ((hfile = value(STRhistfile)) == STRNULL) {  	    hfile = Strcpy(buf, value(STRhome));  	    (void) Strcat(buf, STRsldthist);  	}  	if ((fp = creat(short2str(hfile), 0600)) == -1)   	    return;	oldidfds = didfds;	didfds = 0;	ftmp = SHOUT;	SHOUT = fp;	dumphist[2] = hbuf;	dohist(dumphist, NULL);	SHOUT = ftmp;	(void) close(fp);	didfds = oldidfds;    }}voidgoodbye(){    rechist();    if (loginsh) {	(void) signal(SIGQUIT, SIG_IGN);	(void) signal(SIGINT, SIG_IGN);	(void) signal(SIGTERM, SIG_IGN);	setintr = 0;		/* No interrupts after "logout" */	if (!(adrof(STRlogout)))	    set(STRlogout, STRnormal);#ifdef _PATH_DOTLOGOUT	(void) srcfile(_PATH_DOTLOGOUT, 0, 0);#endif	if (adrof(STRhome))	    (void) srccat(value(STRhome), STRsldtlogout);    }    exitstat();}voidexitstat(){    Char *s;#ifdef PROF    monitor(0);#endif    /*     * Note that if STATUS is corrupted (i.e. getn bombs) then error will exit     * directly because we poke child here. Otherwise we might continue     * unwarrantedly (sic).     */    child = 1;    s = value(STRstatus);    xexit(s ? getn(s) : 0);}/* * in the event of a HUP we want to save the history */static voidphup(sig)int sig;{    rechist();    /*     * We kill the last foreground process group. It then becomes     * responsible to propagate the SIGHUP to its progeny.      */    {	struct process *pp, *np;	for (pp = proclist.p_next; pp; pp = pp->p_next) {	    np = pp;	    /* 	     * Find if this job is in the foreground. It could be that	     * the process leader has exited and the foreground flag	     * is cleared for it.	     */	    do		/*		 * If a process is in the foreground; we try to kill		 * it's process group. If we succeed, then the 		 * whole job is gone. Otherwise we keep going...		 * But avoid sending HUP to the shell again.		 */		if ((np->p_flags & PFOREGND) != 0 && np->p_jobid != shpgrp &&		    killpg(np->p_jobid, SIGHUP) != -1) {		    /* In case the job was suspended... */		    (void) killpg(np->p_jobid, SIGCONT);		    break;		}	    while ((np = np->p_friends) != pp);	}    }    _exit(sig);

⌨️ 快捷键说明

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