Quizzer

 view release on metacpan or  search on metacpan

exercises/compile-tcsh/tcsh-6.10.00/sh.c  view on Meta::CPAN

	struct sigaction act;
        act.sa_handler=pchild;
	(void) sigemptyset(&(act.sa_mask));	/* Don't block any extra sigs
						 * when the handler is called
						 */
        act.sa_flags=0;	           /* want behaviour of sigset() without
                                    * SA_NOCLDSTOP
				    */

        if ((sigaction(SIGCHLD,&act,(struct sigaction *)NULL)) == -1)
	    stderror(ERR_SYSTEM, "sigaction", strerror(errno));
    }
#else /* SYSVREL <= 3 */
    (void) sigset(SIGCHLD, pchild);	/* while signals not ready */
#endif /* SYSVREL <= 3 */


    if (intty && !arginp) 	
	(void) ed_Setup(editing);/* Get the tty state, and set defaults */
				 /* Only alter the tty state if editing */
    
    /*
     * Set an exit here in case of an interrupt or error reading the shell
     * start-up scripts.
     */
    reenter = setexit();	/* PWP */
    exitset++;
    haderr = 0;			/* In case second time through */
    if (!fast && reenter == 0) {
	/* Will have varval(STRhome) here because set fast if don't */
	{
	    int     osetintr = setintr;
	    signalfun_t oparintr = parintr;

#ifdef BSDSIGS
	    sigmask_t omask = sigblock(sigmask(SIGINT));
#else
	    (void) sighold(SIGINT);
#endif
	    setintr = 0;
	    parintr = SIG_IGN;	/* onintr in /etc/ files has no effect */
#ifdef LOGINFIRST
#ifdef _PATH_DOTLOGIN
	    if (loginsh)
	      (void) srcfile(_PATH_DOTLOGIN, 0, 0, NULL);
#endif
#endif

#ifdef _PATH_DOTCSHRC
	    (void) srcfile(_PATH_DOTCSHRC, 0, 0, NULL);
#endif
	    if (!arginp && !onelflg && !havhash)
		dohash(NULL,NULL);
#ifndef LOGINFIRST
#ifdef _PATH_DOTLOGIN
	    if (loginsh)
		(void) srcfile(_PATH_DOTLOGIN, 0, 0, NULL);
#endif
#endif
#ifdef BSDSIGS
	    (void) sigsetmask(omask);
#else
	    (void) sigrelse(SIGINT);
#endif
	    setintr = osetintr;
	    parintr = oparintr;
	}
#ifdef LOGINFIRST
	if (loginsh)
	    (void) srccat(varval(STRhome), STRsldotlogin);
#endif
	/* upward compat. */
	if (!srccat(varval(STRhome), STRsldottcshrc))
	    (void) srccat(varval(STRhome), STRsldotcshrc);

	if (!fast && !arginp && !onelflg && !havhash)
	    dohash(NULL,NULL);

	/*
	 * Source history before .login so that it is available in .login
	 */
	loadhist(NULL, 0);
#ifndef LOGINFIRST
	if (loginsh)
	    (void) srccat(varval(STRhome), STRsldotlogin);
#endif
	if (!fast && (loginsh || rdirs))
	    loaddirs(NULL);
    }
    /* Initing AFTER .cshrc is the Right Way */
    if (intty && !arginp) {	/* PWP setup stuff */
	ed_Init();		/* init the new line editor */
#ifdef SIG_WINDOW
	check_window_size(1);	/* mung environment */
#endif				/* SIG_WINDOW */
    }

    /*
     * 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) {
	    xprintf("logout\n");
	    (void) close(SHIN);
	    child = 1;

exercises/compile-tcsh/tcsh-6.10.00/sh.c  view on Meta::CPAN

    whyles	= st->whyles;
    gointr	= st->gointr;
    if (st->HIST != '\0')
	HIST	= st->HIST;
    enterhist	= st->enterhist;
    cantell	= st->cantell;

    if (st->argv != NULL)
	setq(STRargv, st->argv, &shvhed, VAR_READWRITE);
    else if (av != NULL  && *av != NULL && adrof(STRargv) != NULL)
	unsetv(STRargv);
}

/*
 * 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.
 */
static void
srcunit(unit, onlyown, hflg, av)
    register int unit;
    bool    onlyown;
    int hflg;
    Char **av;
{
    struct saved_state st;
    st.SHIN = -1;	/* st_restore checks this */

    if (unit < 0)
	return;

    if (didfds)
	donefds();

    if (onlyown) {
	struct stat stb;

	if (fstat(unit, &stb) < 0) {
	    (void) close(unit);
	    return;
	}
    }

    getexit(st.oldexit);

    if (setintr)
#ifdef BSDSIGS
	st.mask = sigblock(sigmask(SIGINT));
#else
	(void) sighold(SIGINT);
#endif

    /* Save the current state and move us to a new state */
    st_save(&st, unit, hflg, NULL, av);

    /*
     * Now if we are allowing commands to be interrupted, we let ourselves be
     * interrupted.
     */
    if (setintr)
#ifdef BSDSIGS
	(void) sigsetmask(st.mask);
#else
	(void) sigrelse(SIGINT);
#endif

    /*
     * Bugfix for running out of memory by: Jak Kirman
     * <jak%cs.brown.edu@RELAY.CS.NET>.  Solution: pay attention to what
     * setexit() is returning because reenter _may_ be in a register, and
     * thus restored to 0 on a longjump(). (PWP: insert flames about
     * compiler-dependant code here) PWP: THANKS LOTS !!!
     *
     * PWP: think of this as like a LISP (unwind-protect ...)
     * thanks to Diana Smetters for pointing out how this _should_ be written
     */
#ifdef cray
    st.reenter = 1;		/* assume non-zero return val */
    if (setexit() == 0) {
	st.reenter = 0;		/* Oh well, we were wrong */
#else
    if ((st.reenter = setexit()) == 0) {
#endif
	process(0);		/* 0 -> blow away on errors */
    }

    if (setintr)
#ifdef BSDSIGS
	(void) sigsetmask(st.mask);
#else
	(void) sigrelse(SIGINT);
#endif

    /* Restore the old state */
    st_restore(&st, av);
    resexit(st.oldexit);
    /*
     * If process reset() (effectively an unwind) then we must also unwind.
     */
    if (st.reenter)
	stderror(ERR_SILENT);
}


/*ARGSUSED*/
void
goodbye(v, c)
    Char **v;
    struct command *c;
{
    USE(c);
    record();

    if (loginsh) {
	(void) sigset(SIGQUIT, SIG_IGN);
	(void) sigset(SIGINT, SIG_IGN);
	(void) sigset(SIGTERM, SIG_IGN);
	(void) sigset(SIGHUP, SIG_IGN);
	setintr = 0;		/* No interrupts after "logout" */
	/* Trap errors inside .logout */
	reenter = setexit();
	if (reenter != 0)
	    exitstat();
	if (!(adrof(STRlogout)))
	    set(STRlogout, Strsave(STRnormal), VAR_READWRITE);
#ifdef _PATH_DOTLOGOUT
	(void) srcfile(_PATH_DOTLOGOUT, 0, 0, NULL);
#endif
	if (adrof(STRhome))
	    (void) srccat(varval(STRhome), STRsldtlogout);
#ifdef TESLA
	do_logout = 1;
#endif /* TESLA */
    }
    exitstat();
}

void
exitstat()
{
#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;

exercises/compile-tcsh/tcsh-6.10.00/sh.c  view on Meta::CPAN

#ifdef SIGCONT
			(void) killpg(np->p_jobid, SIGCONT);
#endif
			break;
		    }
		}
	    while ((np = np->p_friends) != pp);
	}
    }
#endif /* POSIXJOBS */

    xexit(snum);
#ifndef SIGVOID
    return (snum);
#endif
}

static Char   *jobargv[2] = {STRjobs, 0};

/*
 * Catch an interrupt, e.g. during lexical input.
 * If we are an interactive shell, we reset the interrupt catch
 * immediately.  In any case we drain the shell output,
 * and finally go through the normal error mechanism, which
 * gets a chance to make the shell go away.
 */
int     just_signaled;		/* bugfix by Michael Bloom (mg@ttidca.TTI.COM) */

#ifdef SIGVOID
/*ARGSUSED*/
#endif
sigret_t
pintr(snum)
int snum;
{
#ifdef UNRELSIGS
    if (snum)
	(void) sigset(snum, pintr);
#endif /* UNRELSIGS */
    just_signaled = 1;
    pintr1(1);
#ifndef SIGVOID
    return (snum);
#endif
}

void
pintr1(wantnl)
    bool    wantnl;
{
    register Char **v;
#ifdef BSDSIGS
    sigmask_t omask;
#endif

#ifdef BSDSIGS
    omask = sigblock((sigmask_t) 0);
#endif
    if (setintr) {
#ifdef BSDSIGS
	(void) sigsetmask(omask & ~sigmask(SIGINT));
#else
	(void) sigrelse(SIGINT);
#endif
	if (pjobs) {
	    pjobs = 0;
	    xputchar('\n');
	    dojobs(jobargv, NULL);
	    stderror(ERR_NAME | ERR_INTR);
	}
    }
    /* MH - handle interrupted completions specially */
    {
	extern int InsideCompletion;

	if (InsideCompletion)
	    stderror(ERR_SILENT);
    }
    /* JV - Make sure we shut off inputl */
    {
	extern Char GettingInput;

	(void) Cookedmode();
	GettingInput = 0;
    }
#ifdef BSDSIGS
    (void) sigsetmask(omask & ~sigmask(SIGCHLD));
#else
    if (setintr)
	(void) sighold(SIGINT);
    (void) sigrelse(SIGCHLD);
#endif
    drainoline();
#if !defined(_VMS_POSIX) && !defined(WINNT_NATIVE)
    (void) endpwent();
#endif /* !_VMS_POSIX && !WINNT_NATIVE */

    /*
     * If we have an active "onintr" then we search for the label. Note that if
     * one does "onintr -" then we shan't be interruptible so we needn't worry
     * about that here.
     */
    if (gointr) {
	gotolab(gointr);
	timflg = 0;
	if ((v = pargv) != 0)
	    pargv = 0, blkfree(v);
	if ((v = gargv) != 0)
	    gargv = 0, blkfree(v);
	reset();
    }
    else if (intty && wantnl) {
	if (editing) {
	    /* 
	     * If we are editing a multi-line input command, and move to
	     * the beginning of the line, we don't want to trash it when
	     * we hit ^C
	     */
	    PastBottom();
	    ClearLines();
	    ClearDisp();
	}
	else {
	    /* xputchar('\n'); *//* Some like this, others don't */
	    (void) putraw('\r');
	    (void) putraw('\n');
	}
    }
    stderror(ERR_SILENT);
}

/*
 * Process is the main driving routine for the shell.
 * It runs all command processing, except for those within { ... }
 * in expressions (which is run by a routine evalav in sh.exp.c which
 * is a stripped down process), and `...` evaluation which is run
 * also by a subset of this code in sh.glob.c in the routine backeval.
 *
 * The code here is a little strange because part of it is interruptible
 * and hence freeing of structures appears to occur when none is necessary
 * if this is ignored.
 *
 * Note that if catch is not set then we will unwind on any error.
 * If an end-of-file occurs, we return.
 */
static struct command *savet = NULL;
void
process(catch)
    bool    catch;
{
    extern char Expand;
    jmp_buf_t osetexit;
    /* PWP: This might get nuked my longjmp so don't make it a register var */
    struct command *t = savet;

    savet = NULL;
    getexit(osetexit);
    for (;;) {

	pendjob();

	/* This was leaking memory badly, particularly when sourcing
	 * files, etc.. For whatever reason we were arriving here with
	 * allocated pointers still active, and the code was simply
	 * overwriting them.  I can't say I fully understand the
	 * control flow here, but according to Purify this particular
	 * leak has been plugged, and I haven't noticed any ill
	 * effects.. (sg)
	 */
	if (paraml.next && paraml.next != &paraml)
	    freelex(&paraml);

	paraml.next = paraml.prev = &paraml;
	paraml.word = STRNULL;
	(void) setexit();
	justpr = enterhist;	/* execute if not entering history */

	/*
	 * Interruptible during interactive reads
	 */
	if (setintr)
#ifdef BSDSIGS
	    (void) sigsetmask(sigblock((sigmask_t) 0) & ~sigmask(SIGINT));
#else
	    (void) sigrelse(SIGINT);
#endif


	/*
	 * For the sake of reset()
	 */
	freelex(&paraml);
	if (savet)
	    freesyn(savet), savet = NULL;

	if (haderr) {
	    if (!catch) {
		/* unwind */
		doneinp = 0;
		savet = t;
		resexit(osetexit);
		reset();
	    }
	    haderr = 0;
	    /*
	     * Every error is eventually caught here or the shell dies.  It is
	     * at this point that we clean up any left-over open files, by
	     * closing all but a fixed number of pre-defined files.  Thus
	     * routines don't have to worry about leaving files open due to
	     * deeper errors... they will get closed here.
	     */
	    closem();
	    continue;
	}
	if (doneinp) {
	    doneinp = 0;
	    break;
	}
	if (chkstop)
	    chkstop--;
	if (neednote)
	    pnote();
	if (intty && prompt && evalvec == 0) {
	    just_signaled = 0;
	    mailchk();
	    /*
	     * Watch for logins/logouts. Next is scheduled commands stored
	     * previously using "sched." Then execute periodic commands.
	     * Following that, the prompt precmd is run.
	     */
#ifndef HAVENOUTMP
	    watch_login(0);
#endif /* !HAVENOUTMP */
	    sched_run(0);
	    period_cmd();
	    precmd();
	    /*
	     * If we are at the end of the input buffer then we are going to
	     * read fresh stuff. Otherwise, we are rereading input and don't
	     * need or want to prompt.
	     */
	    if (fseekp == feobp && aret == TCSH_F_SEEK)
		printprompt(0, NULL);



( run in 1.132 second using v1.01-cache-2.11-cpan-364913b4093 )