Quizzer
view release on metacpan or search on metacpan
exercises/compile-tcsh/tcsh-6.10.00/sh.proc.c view on Meta::CPAN
#ifdef SHORT_STRINGS
xputchar('\r' | QUOTE), xputchar('\n');
#else /* !SHORT_STRINGS */
xprintf("\215\n"); /* \215 is a quoted ^M */
#endif /* !SHORT_STRINGS */
(void) pprint(pp, NUMBER | NAME | REASON);
if ((jobflags & PSTOPPED) == 0)
pflush(pp);
{
extern Char GettingInput;
if (GettingInput) {
errno = 0;
(void) Rawmode();
#ifdef notdef
/*
* don't really want to do that, because it
* will erase our message in case of multi-line
* input
*/
ClearLines();
#endif /* notdef */
ClearDisp();
Refresh();
}
}
}
else {
fp->p_flags |= PNEEDNOTE;
neednote++;
}
}
}
#if defined(BSDJOBS) || defined(HAVEwait3)
goto loop;
#endif /* BSDJOBS || HAVEwait3 */
}
void
pnote()
{
register struct process *pp;
int flags;
#ifdef BSDSIGS
sigmask_t omask;
#endif /* BSDSIGS */
neednote = 0;
for (pp = proclist.p_next; pp != NULL; pp = pp->p_next) {
if (pp->p_flags & PNEEDNOTE) {
#ifdef BSDSIGS
omask = sigblock(sigmask(SIGCHLD));
#else /* !BSDSIGS */
(void) sighold(SIGCHLD);
#endif /* !BSDSIGS */
pp->p_flags &= ~PNEEDNOTE;
flags = pprint(pp, NUMBER | NAME | REASON);
if ((flags & (PRUNNING | PSTOPPED)) == 0)
pflush(pp);
#ifdef BSDSIGS
(void) sigsetmask(omask);
#else /* !BSDSIGS */
(void) sigrelse(SIGCHLD);
#endif /* !BSDSIGS */
}
}
}
static void
pfree(pp)
struct process *pp;
{
xfree((ptr_t) pp->p_command);
if (pp->p_cwd && --pp->p_cwd->di_count == 0)
if (pp->p_cwd->di_next == 0)
dfree(pp->p_cwd);
xfree((ptr_t) pp);
}
/*
* pwait - wait for current job to terminate, maintaining integrity
* of current and previous job indicators.
*/
void
pwait()
{
register struct process *fp, *pp;
#ifdef BSDSIGS
sigmask_t omask;
#endif /* BSDSIGS */
/*
* Here's where dead procs get flushed.
*/
#ifdef BSDSIGS
omask = sigblock(sigmask(SIGCHLD));
#else /* !BSDSIGS */
(void) sighold(SIGCHLD);
#endif /* !BSDSIGS */
for (pp = (fp = &proclist)->p_next; pp != NULL; pp = (fp = pp)->p_next)
if (pp->p_procid == 0) {
fp->p_next = pp->p_next;
pfree(pp);
pp = fp;
}
#ifdef BSDSIGS
(void) sigsetmask(omask);
#else /* !BSDSIGS */
(void) sigrelse(SIGCHLD);
# ifdef notdef
if (setintr)
sigignore(SIGINT);
# endif /* notdef */
#endif /* !BSDSIGS */
pjwait(pcurrjob);
}
/*
* pjwait - wait for a job to finish or become stopped
* It is assumed to be in the foreground state (PFOREGND)
*/
void
pjwait(pp)
register struct process *pp;
{
register struct process *fp;
int jobflags, reason;
#ifdef BSDSIGS
sigmask_t omask;
#endif /* BSDSIGS */
#ifdef UNRELSIGS
signalfun_t inthandler;
#endif /* UNRELSIGS */
while (pp->p_procid != pp->p_jobid)
pp = pp->p_friends;
fp = pp;
do {
if ((fp->p_flags & (PFOREGND | PRUNNING)) == PRUNNING)
xprintf(CGETS(17, 1, "BUG: waiting for background job!\n"));
} while ((fp = fp->p_friends) != pp);
/*
* Now keep pausing as long as we are not interrupted (SIGINT), and the
* target process, or any of its friends, are running
*/
fp = pp;
#ifdef BSDSIGS
omask = sigblock(sigmask(SIGCHLD));
#endif /* BSDSIGS */
#ifdef UNRELSIGS
if (setintr)
inthandler = signal(SIGINT, SIG_IGN);
#endif /* UNRELSIGS */
for (;;) {
#ifndef BSDSIGS
(void) sighold(SIGCHLD);
#endif /* !BSDSIGS */
jobflags = 0;
do
jobflags |= fp->p_flags;
while ((fp = (fp->p_friends)) != pp);
if ((jobflags & PRUNNING) == 0)
break;
#ifdef JOBDEBUG
xprintf("%d starting to sigpause for SIGCHLD on %d\n",
getpid(), fp->p_procid);
#endif /* JOBDEBUG */
#ifdef BSDSIGS
/* (void) sigpause(sigblock((sigmask_t) 0) &~ sigmask(SIGCHLD)); */
(void) sigpause(omask & ~sigmask(SIGCHLD));
#else /* !BSDSIGS */
(void) sigpause(SIGCHLD);
#endif /* !BSDSIGS */
}
#ifdef JOBDEBUG
xprintf("%d returned from sigpause loop\n", getpid());
#endif /* JOBDEBUG */
#ifdef BSDSIGS
(void) sigsetmask(omask);
#else /* !BSDSIGS */
(void) sigrelse(SIGCHLD);
#endif /* !BSDSIGS */
#ifdef UNRELSIGS
if (setintr)
(void) signal(SIGINT, inthandler);
#endif /* UNRELSIGS */
#ifdef BSDJOBS
if (tpgrp > 0) /* get tty back */
(void) tcsetpgrp(FSHTTY, tpgrp);
#endif /* BSDJOBS */
if ((jobflags & (PSIGNALED | PSTOPPED | PTIME)) ||
!eq(dcwd->di_name, fp->p_cwd->di_name)) {
if (jobflags & PSTOPPED) {
xputchar('\n');
if (adrof(STRlistjobs)) {
Char *jobcommand[3];
jobcommand[0] = STRjobs;
if (eq(varval(STRlistjobs), STRlong))
jobcommand[1] = STRml;
else
jobcommand[1] = NULL;
jobcommand[2] = NULL;
dojobs(jobcommand, NULL);
(void) pprint(pp, SHELLDIR);
}
else
(void) pprint(pp, AREASON | SHELLDIR);
}
else
(void) pprint(pp, AREASON | SHELLDIR);
}
if ((jobflags & (PINTERRUPTED | PSTOPPED)) && setintr &&
(!gointr || !eq(gointr, STRminus))) {
if ((jobflags & PSTOPPED) == 0)
pflush(pp);
pintr1(0);
/* NOTREACHED */
}
reason = 0;
fp = pp;
do {
if (fp->p_reason)
reason = fp->p_flags & (PSIGNALED | PINTERRUPTED) ?
fp->p_reason | META : fp->p_reason;
} while ((fp = fp->p_friends) != pp);
/*
* Don't report on backquoted jobs, cause it will mess up
* their output.
*/
if ((reason != 0) && (adrof(STRprintexitvalue)) &&
(pp->p_flags & PBACKQ) == 0)
xprintf(CGETS(17, 2, "Exit %d\n"), reason);
set(STRstatus, putn(reason), VAR_READWRITE);
if (reason && exiterr)
exitstat();
pflush(pp);
}
/*
* dowait - wait for all processes to finish
*/
/*ARGSUSED*/
void
dowait(v, c)
Char **v;
struct command *c;
{
register struct process *pp;
#ifdef BSDSIGS
sigmask_t omask;
#endif /* BSDSIGS */
USE(c);
USE(v);
pjobs++;
#ifdef BSDSIGS
omask = sigblock(sigmask(SIGCHLD));
loop:
#else /* !BSDSIGS */
if (setintr)
(void) sigrelse(SIGINT);
loop:
(void) sighold(SIGCHLD);
#endif /* !BSDSIGS */
for (pp = proclist.p_next; pp; pp = pp->p_next)
if (pp->p_procid && /* pp->p_procid == pp->p_jobid && */
pp->p_flags & PRUNNING) {
#ifdef BSDSIGS
(void) sigpause((sigmask_t) 0);
#else /* !BSDSIGS */
(void) sigpause(SIGCHLD);
#endif /* !BSDSIGS */
goto loop;
}
#ifdef BSDSIGS
(void) sigsetmask(omask);
#else /* !BSDSIGS */
(void) sigrelse(SIGCHLD);
#endif /* !BSDSIGS */
pjobs = 0;
}
/*
* pflushall - flush all jobs from list (e.g. at fork())
*/
static void
pflushall()
{
register struct process *pp;
for (pp = proclist.p_next; pp != NULL; pp = pp->p_next)
if (pp->p_procid)
pflush(pp);
}
/*
* pflush - flag all process structures in the same job as the
* the argument process for deletion. The actual free of the
* space is not done here since pflush is called at interrupt level.
*/
static void
pflush(pp)
register struct process *pp;
{
register struct process *np;
register int idx;
if (pp->p_procid == 0) {
xprintf(CGETS(17, 3, "BUG: process flushed twice"));
return;
}
while (pp->p_procid != pp->p_jobid)
pp = pp->p_friends;
pclrcurr(pp);
if (pp == pcurrjob)
pcurrjob = 0;
idx = pp->p_index;
np = pp;
do {
np->p_index = np->p_procid = 0;
np->p_flags &= ~PNEEDNOTE;
} while ((np = np->p_friends) != pp);
if (idx == pmaxindex) {
for (np = proclist.p_next, idx = 0; np; np = np->p_next)
if (np->p_index > idx)
idx = np->p_index;
pmaxindex = idx;
}
}
/*
* pclrcurr - make sure the given job is not the current or previous job;
* pp MUST be the job leader
*/
static void
pclrcurr(pp)
exercises/compile-tcsh/tcsh-6.10.00/sh.proc.c view on Meta::CPAN
case SIGTTIN:
case SIGTTOU:
if ((jobflags & PRUNNING) == 0) {
# ifdef SUSPENDED
xprintf(CGETS(17, 12, "%S: Already suspended\n"), cp);
# else /* !SUSPENDED */
xprintf(CGETS(17, 13, "%S: Already stopped\n"), cp);
# endif /* !SUSPENDED */
err1++;
goto cont;
}
break;
/*
* suspend a process, kill -CONT %, then type jobs; the shell
* says it is suspended, but it is running; thanks jaap..
*/
case SIGCONT:
if (!pstart(pp, 0)) {
pp->p_procid = 0;
stderror(ERR_NAME|ERR_BADJOB, pp->p_command,
strerror(errno));
}
goto cont;
default:
break;
}
#endif /* BSDJOBS */
if (killpg(pp->p_jobid, signum) < 0) {
xprintf("%S: %s\n", cp, strerror(errno));
err1++;
}
#ifdef BSDJOBS
if (signum == SIGTERM || signum == SIGHUP)
(void) killpg(pp->p_jobid, SIGCONT);
#endif /* BSDJOBS */
}
else if (!(Isdigit(*cp) || *cp == '-'))
stderror(ERR_NAME | ERR_JOBARGS);
else {
#ifndef WINNT_NATIVE
pid = atoi(short2str(cp));
#else
pid = strtoul(short2str(cp),NULL,0);
#endif /* WINNT_NATIVE */
if (kill(pid, signum) < 0) {
xprintf("%d: %s\n", pid, strerror(errno));
err1++;
goto cont;
}
#ifdef BSDJOBS
if (signum == SIGTERM || signum == SIGHUP)
(void) kill(pid, SIGCONT);
#endif /* BSDJOBS */
}
cont:
v++;
}
if (gargv)
blkfree(gargv), gargv = 0;
#ifdef BSDSIGS
(void) sigsetmask(omask);
#else /* !BSDSIGS */
(void) sigrelse(SIGCHLD);
if (setintr)
(void) sigrelse(SIGINT);
#endif /* !BSDSIGS */
if (err1)
stderror(ERR_SILENT);
}
/*
* pstart - start the job in foreground/background
*/
int
pstart(pp, foregnd)
register struct process *pp;
int foregnd;
{
int rv = 0;
register struct process *np;
#ifdef BSDSIGS
sigmask_t omask;
#endif /* BSDSIGS */
/* We don't use jobflags in this function right now (see below) */
/* long jobflags = 0; */
#ifdef BSDSIGS
omask = sigblock(sigmask(SIGCHLD));
#else /* !BSDSIGS */
(void) sighold(SIGCHLD);
#endif
np = pp;
do {
/* We don't use jobflags in this function right now (see below) */
/* jobflags |= np->p_flags; */
if (np->p_flags & (PRUNNING | PSTOPPED)) {
np->p_flags |= PRUNNING;
np->p_flags &= ~PSTOPPED;
if (foregnd)
np->p_flags |= PFOREGND;
else
np->p_flags &= ~PFOREGND;
}
} while ((np = np->p_friends) != pp);
if (!foregnd)
pclrcurr(pp);
(void) pprint(pp, foregnd ? NAME | JOBDIR : NUMBER | NAME | AMPERSAND);
#ifdef BSDJOBS
if (foregnd) {
rv = tcsetpgrp(FSHTTY, pp->p_jobid);
}
/*
* 1. child process of csh (shell script) receives SIGTTIN/SIGTTOU
* 2. parent process (csh) receives SIGCHLD
* 3. The "csh" signal handling function pchild() is invoked
* with a SIGCHLD signal.
* 4. pchild() calls wait3(WNOHANG) which returns 0.
* The child process is NOT ready to be waited for at this time.
* pchild() returns without picking-up the correct status
* for the child process which generated the SIGCHILD.
* 5. CONSEQUENCE : csh is UNaware that the process is stopped
* 6. THIS LINE HAS BEEN COMMENTED OUT : if (jobflags&PSTOPPED)
* (beto@aixwiz.austin.ibm.com - aug/03/91)
* 7. I removed the line completely and added extra checks for
* pstart, so that if a job gets attached to and dies inside
* a debugger it does not confuse the shell. [christos]
* 8. on the nec sx-4 there seems to be a problem, which requires
* a syscall(151, getpid(), getpid()) in osinit. Don't ask me
* what this is doing. [schott@rzg.mpg.de]
*/
if (rv != -1)
rv = killpg(pp->p_jobid, SIGCONT);
#endif /* BSDJOBS */
#ifdef BSDSIGS
(void) sigsetmask(omask);
#else /* !BSDSIGS */
(void) sigrelse(SIGCHLD);
#endif /* !BSDSIGS */
return rv != -1;
}
void
panystop(neednl)
bool neednl;
{
register struct process *pp;
chkstop = 2;
for (pp = proclist.p_next; pp; pp = pp->p_next)
if (pp->p_flags & PSTOPPED)
stderror(ERR_STOPPED, neednl ? "\n" : "");
}
struct process *
pfind(cp)
Char *cp;
{
register struct process *pp, *np;
if (cp == 0 || cp[1] == 0 || eq(cp, STRcent2) || eq(cp, STRcentplus)) {
if (pcurrent == NULL)
stderror(ERR_NAME | ERR_JOBCUR);
return (pcurrent);
}
if (eq(cp, STRcentminus) || eq(cp, STRcenthash)) {
if (pprevious == NULL)
stderror(ERR_NAME | ERR_JOBPREV);
return (pprevious);
}
if (Isdigit(cp[1])) {
int idx = atoi(short2str(cp + 1));
for (pp = proclist.p_next; pp; pp = pp->p_next)
if (pp->p_index == idx && pp->p_procid == pp->p_jobid)
return (pp);
stderror(ERR_NAME | ERR_NOSUCHJOB);
}
np = NULL;
for (pp = proclist.p_next; pp; pp = pp->p_next)
if (pp->p_procid == pp->p_jobid) {
if (cp[1] == '?') {
register Char *dp;
for (dp = pp->p_command; *dp; dp++) {
if (*dp != cp[2])
continue;
if (prefix(cp + 2, dp))
goto match;
}
}
else if (prefix(cp + 1, pp->p_command)) {
match:
if (np)
stderror(ERR_NAME | ERR_AMBIG);
np = pp;
exercises/compile-tcsh/tcsh-6.10.00/sh.proc.c view on Meta::CPAN
* It is usually just the value of tpgrp.
*/
int
pfork(t, wanttty)
struct command *t; /* command we are forking for */
int wanttty;
{
register int pid;
bool ignint = 0;
int pgrp;
#ifdef BSDSIGS
sigmask_t omask = 0;
#endif /* BSDSIGS */
#ifdef SIGSYNCH
sigvec_t osv;
static sigvec_t nsv = {synch_handler, (sigset_t) ~0, 0};
#endif /* SIGSYNCH */
/*
* A child will be uninterruptible only under very special conditions.
* Remember that the semantics of '&' is implemented by disconnecting the
* process from the tty so signals do not need to ignored just for '&'.
* Thus signals are set to default action for children unless: we have had
* an "onintr -" (then specifically ignored) we are not playing with
* signals (inherit action)
*/
if (setintr)
ignint = (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT))
|| (gointr && eq(gointr, STRminus));
#ifdef COHERENT
ignint |= gointr && eq(gointr, STRminus);
#endif /* COHERENT */
/*
* Check for maximum nesting of 16 processes to avoid Forking loops
*/
if (child == 16)
stderror(ERR_NESTING, 16);
#ifdef SIGSYNCH
if (mysigvec(SIGSYNCH, &nsv, &osv))
stderror(ERR_SYSTEM, "pfork: sigvec set", strerror(errno));
#endif /* SIGSYNCH */
/*
* Hold SIGCHLD until we have the process installed in our table.
*/
if (wanttty < 0) {
#ifdef BSDSIGS
omask = sigblock(sigmask(SIGCHLD));
#else /* !BSDSIGS */
(void) sighold(SIGCHLD);
#endif /* !BSDSIGS */
}
while ((pid = fork()) == -1)
if (setintr == 0)
(void) sleep(FORKSLEEP);
else {
if (wanttty < 0)
#ifdef BSDSIGS
(void) sigsetmask(omask);
#else /* !BSDSIGS */
(void) sigrelse(SIGCHLD);
(void) sigrelse(SIGINT);
#endif /* !BSDSIGS */
stderror(ERR_NOPROC);
}
if (pid == 0) {
settimes();
pgrp = pcurrjob ? pcurrjob->p_jobid : getpid();
pflushall();
pcurrjob = NULL;
#if !defined(BSDTIMES) && !defined(_SEQUENT_)
timesdone = 0;
#endif /* !defined(BSDTIMES) && !defined(_SEQUENT_) */
child++;
if (setintr) {
setintr = 0; /* until I think otherwise */
#ifndef BSDSIGS
if (wanttty < 0)
(void) sigrelse(SIGCHLD);
#endif /* !BSDSIGS */
/*
* Children just get blown away on SIGINT, SIGQUIT unless "onintr
* -" seen.
*/
(void) signal(SIGINT, ignint ? SIG_IGN : SIG_DFL);
(void) signal(SIGQUIT, ignint ? SIG_IGN : SIG_DFL);
#ifdef BSDJOBS
if (wanttty >= 0) {
/* make stoppable */
(void) signal(SIGTSTP, SIG_DFL);
(void) signal(SIGTTIN, SIG_DFL);
(void) signal(SIGTTOU, SIG_DFL);
}
#endif /* BSDJOBS */
(void) signal(SIGTERM, parterm);
}
else if (tpgrp == -1 && (t->t_dflg & F_NOINTERRUPT)) {
(void) signal(SIGINT, SIG_IGN);
(void) signal(SIGQUIT, SIG_IGN);
}
#ifdef OREO
sigignore(SIGIO); /* ignore SIGIO in child too */
#endif /* OREO */
pgetty(wanttty, pgrp);
/*
* Nohup and nice apply only to NODE_COMMAND's but it would be nice
* (?!?) if you could say "nohup (foo;bar)" Then the parser would have
* to know about nice/nohup/time
*/
if (t->t_dflg & F_NOHUP)
(void) signal(SIGHUP, SIG_IGN);
if (t->t_dflg & F_NICE) {
int nval = SIGN_EXTEND_CHAR(t->t_nice);
#ifdef BSDNICE
(void) setpriority(PRIO_PROCESS, 0, nval);
#else /* !BSDNICE */
(void) nice(nval);
#endif /* !BSDNICE */
}
#ifdef F_VER
if (t->t_dflg & F_VER) {
tsetenv(STRSYSTYPE, t->t_systype ? STRbsd43 : STRsys53);
dohash(NULL, NULL);
}
#endif /* F_VER */
#ifdef SIGSYNCH
/* rfw 8/89 now parent can continue */
if (kill(getppid(), SIGSYNCH))
stderror(ERR_SYSTEM, "pfork child: kill", strerror(errno));
#endif /* SIGSYNCH */
}
else {
#ifdef POSIXJOBS
if (wanttty >= 0) {
/*
* `Walking' process group fix from Beto Appleton.
* (beto@aixwiz.austin.ibm.com)
* If setpgid fails at this point that means that
* our process leader has died. We flush the current
* job and become the process leader ourselves.
* The parent will figure that out later.
*/
pgrp = pcurrjob ? pcurrjob->p_jobid : pid;
if (setpgid(pid, pgrp) == -1 && errno == EPERM) {
pcurrjob = NULL;
/*
* We don't care if this causes an error here;
* then we are already in the right process group
*/
(void) setpgid(pid, pgrp = pid);
}
}
#endif /* POSIXJOBS */
palloc(pid, t);
#ifdef SIGSYNCH
/*
* rfw 8/89 Wait for child to own terminal. Solves half of ugly
* synchronization problem. With this change, we know that the only
* reason setpgrp to a previous process in a pipeline can fail is that
* the previous process has already exited. Without this hack, he may
* either have exited or not yet started to run. Two uglies become
* one.
*/
(void) sigpause(omask & ~SYNCHMASK);
if (mysigvec(SIGSYNCH, &osv, NULL))
stderror(ERR_SYSTEM, "pfork parent: sigvec restore",
strerror(errno));
#endif /* SIGSYNCH */
if (wanttty < 0) {
#ifdef BSDSIGS
(void) sigsetmask(omask);
#else /* !BSDSIGS */
(void) sigrelse(SIGCHLD);
#endif /* !BSDSIGS */
}
}
return (pid);
}
static void
okpcntl()
{
if (tpgrp == -1)
stderror(ERR_JOBCONTROL);
if (tpgrp == 0)
stderror(ERR_JOBCTRLSUB);
}
static void
setttypgrp(pgrp)
int pgrp;
{
/*
* If we are piping out a builtin, eg. 'echo | more' things can go
* out of sequence, i.e. the more can run before the echo. This
* can happen even if we have vfork, since the echo will be forked
* with the regular fork. In this case, we need to set the tty
* pgrp ourselves. If that happens, then the process will be still
* alive. And the tty process group will already be set.
* This should fix the famous sequent problem as a side effect:
* The controlling terminal is lost if all processes in the
* terminal process group are zombies. In this case tcgetpgrp()
* returns 0. If this happens we must set the terminal process
* group again.
*/
if (tcgetpgrp(FSHTTY) != pgrp) {
#ifdef POSIXJOBS
/*
* tcsetpgrp will set SIGTTOU to all the the processes in
* the background according to POSIX... We ignore this here.
*/
signalfun_t old = sigset(SIGTTOU, SIG_IGN);
#endif
(void) tcsetpgrp(FSHTTY, pgrp);
# ifdef POSIXJOBS
(void) sigset(SIGTTOU, old);
# endif
}
}
/*
* if we don't have vfork(), things can still go in the wrong order
* resulting in the famous 'Stopped (tty output)'. But some systems
* don't permit the setpgid() call, (these are more recent secure
* systems such as ibm's aix), when they do. Then we'd rather print
* an error message than hang the shell!
* I am open to suggestions how to fix that.
*/
exercises/compile-tcsh/tcsh-6.10.00/sh.proc.c view on Meta::CPAN
pgetty(wanttty, pgrp)
int wanttty, pgrp;
{
#ifdef BSDJOBS
# if defined(BSDSIGS) && defined(POSIXJOBS)
sigmask_t omask = 0;
# endif /* BSDSIGS && POSIXJOBS */
# ifdef JOBDEBUG
xprintf("wanttty %d pid %d opgrp%d pgrp %d tpgrp %d\n",
wanttty, getpid(), pgrp, mygetpgrp(), tcgetpgrp(FSHTTY));
# endif /* JOBDEBUG */
# ifdef POSIXJOBS
/*
* christos: I am blocking the tty signals till I've set things
* correctly....
*/
if (wanttty > 0)
# ifdef BSDSIGS
omask = sigblock(sigmask(SIGTSTP)|sigmask(SIGTTIN));
# else /* !BSDSIGS */
{
(void) sighold(SIGTSTP);
(void) sighold(SIGTTIN);
}
# endif /* !BSDSIGS */
# endif /* POSIXJOBS */
# ifndef POSIXJOBS
if (wanttty > 0)
setttypgrp(pgrp);
# endif /* !POSIXJOBS */
/*
* From: Michael Schroeder <mlschroe@immd4.informatik.uni-erlangen.de>
* Don't check for tpgrp >= 0 so even non-interactive shells give
* background jobs process groups Same for the comparison in the other part
* of the #ifdef
*/
if (wanttty >= 0) {
if (setpgid(0, pgrp) == -1) {
# ifdef POSIXJOBS
/* Walking process group fix; see above */
if (setpgid(0, pgrp = getpid()) == -1) {
# endif /* POSIXJOBS */
stderror(ERR_SYSTEM, "setpgid child:\n", strerror(errno));
xexit(0);
# ifdef POSIXJOBS
}
wanttty = pgrp; /* Now we really want the tty, since we became the
* the process group leader
*/
# endif /* POSIXJOBS */
}
}
# ifdef POSIXJOBS
if (wanttty > 0)
setttypgrp(pgrp);
# ifdef BSDSIGS
(void) sigsetmask(omask);
# else /* BSDSIGS */
(void) sigrelse(SIGTSTP);
(void) sigrelse(SIGTTIN);
# endif /* !BSDSIGS */
# endif /* POSIXJOBS */
# ifdef JOBDEBUG
xprintf("wanttty %d pid %d pgrp %d tpgrp %d\n",
wanttty, getpid(), mygetpgrp(), tcgetpgrp(FSHTTY));
# endif /* JOBDEBUG */
if (tpgrp > 0)
tpgrp = 0; /* gave tty away */
#endif /* BSDJOBS */
}
( run in 2.053 seconds using v1.01-cache-2.11-cpan-302cb4679cc )