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 != ¶ml)
freelex(¶ml);
paraml.next = paraml.prev = ¶ml;
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(¶ml);
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 )