/* Copyright (c) 1979 Regents of the University of California */
execute(t
, pipein
, pipeout
)
register struct command
*t
;
register struct command
*t1
;
int (*savint
)(), vffree();
int ochild
, osetintr
, ohaderr
, otimflg
, odidfds
, odidcch
;
int oSHIN
, oSHOUT
, oSHDIAG
, oOLDSTD
;
if ((cp
[0] & (QUOTE
|TRIM
)) == QUOTE
)
if ((t
->t_dflg
& FREDO
) == 0)
* A child will be interruptible only under very
* we must be monkeying with interrupts
* the child must not be &'ed
* we must not have had an "onintr -"
shudint
= setintr
&& (flags
& FINT
) == 0 && (!gointr
|| !eq(gointr
, "-"));
shudhup
= (flags
& FAND
) == 0;
* Must do << early so parent will know
* where input pointer should be
close(0), heredoc(t
->t_dlef
);
* If not executing commands then
* all we must do is read forward in the input to
* account for << redirection if present.
if (t
->t_dtyp
== TCOM
&& isbfunc(t
->t_dcom
[0])) {
* If output is piped, or running & and we would
* eventually fork for non-builtin commands,
* then do it now, so we won't block.
if ((flags
& (FPOU
|FAND
)) && (flags
& FPAR
) == 0)
pid
= dofork(shudint
, shudhup
), forked
++;
* If the builtin is actually executed (some, e.g.
* time and nice may refuse to execute here)
* then either exit (if we forked) or close i/o
* and continue execution (if we didn't).
doio(t
, pipein
, pipeout
);
close(pipeout
[0]), close(pipeout
[1]);
pipeout
[0] = pipeout
[1] = -1;
signal(SIGINT
, SIG_DFL
), signal(SIGQUIT
, SIG_DFL
);
signal(SIGTERM
, parterm
);
if (func(t
, pipein
, pipeout
)) {
if (didfds
&& !(t
->t_dflg
& FREDO
))
* Now, we must make a new process since either the
* command is non-builtin, a parenthesized list,
* or builtin such as time or nice which really
if (!forked
&& (flags
& FPAR
) == 0)
if (t
->t_dtyp
== TPAR
|| (flags
&FREDO
) ||
eq(t
->t_dcom
[0], "nice") || eq(t
->t_dcom
[0], "nohup"))
pid
= dofork(shudint
, shudhup
);
savint
= signal(SIGINT
, SIG_IGN
);
ochild
= child
; osetintr
= setintr
;
ohaderr
= haderr
; otimflg
= timflg
;
odidfds
= didfds
; odidcch
= didcch
;
oSHIN
= SHIN
; oSHOUT
= SHOUT
;
oSHDIAG
= SHDIAG
; oOLDSTD
= OLDSTD
;
error("No more processes");
signal(SIGINT
, shudint
? SIG_DFL
: savint
);
child
= ochild
; setintr
= osetintr
;
haderr
= ohaderr
; timflg
= otimflg
;
didfds
= odidfds
; didcch
= odidcch
;
SHIN
= oSHIN
; SHOUT
= oSHOUT
;
SHDIAG
= oSHDIAG
; OLDSTD
= oOLDSTD
;
* The parent path (or nobody does this if
* (flags & FPAR), i.e. date in (set;date))
if (didfds
== 0 && (flags
& FPIN
))
close(pipein
[0]), close(pipein
[1]);
if (didfds
&& !(t
->t_dflg
& FREDO
))
printf("%d\n", pid
), set("child", putn(pid
));
* Unless output is piped or command is &
if ((flags
& (FPOU
|FAND
)) == 0)
* Insure that this (child) shell doesn't muck on
* If havent yet, finally set up the file descriptors.
doio(t
, pipein
, pipeout
);
close(pipeout
[0]), close(pipeout
[1]);
* If mucking with interrupts fix interrupt, quit,
* and terminate handling ... in any case set setintr
* to 0 if we are not interruptible so that no further
* interrupt mucking occurs.
signal(SIGQUIT
, SIG_DFL
);
signal(SIGTERM
, parterm
);
* For () commands must put new 0,1,2 in FSH* and recurse
t1
->t_dflg
|= flags
& FINT
;
OLDSTD
= dcopy(0, FOLDSTD
);
SHOUT
= dcopy(1, FSHOUT
);
SHDIAG
= dcopy(2, FSHDIAG
);
if (eq(t
->t_dcom
[0], "nice")) {
nice(getn(cp
)), lshift(t
->t_dcom
, 2);
nice(4), lshift(t
->t_dcom
, 1);
t
->t_dflg
= FPAR
| FREDO
;
if (eq(t
->t_dcom
[0], "nohup")) {
signal(SIGTERM
, SIG_IGN
);
t
->t_dflg
= FPAR
| FREDO
;
t1
->t_dflg
|= FPOU
| (flags
& (FPIN
|FINT
|FPRS
|FDIAG
));
t1
->t_dflg
|= FPIN
| (flags
& (FPOU
|FINT
|FAND
|FPRS
|FPAR
));
execute(t1
, pv
, pipeout
);
flags
= t
->t_dflg
& FINT
;
t1
->t_dflg
|= flags
, execute(t1
);
t1
->t_dflg
|= t
->t_dflg
& (FINT
|FPAR
), execute(t1
);
flags
= t
->t_dflg
& FINT
;
t1
->t_dflg
|= flags
, execute(t1
);
if ((getn(value("status")) == 0) == (t
->t_dtyp
== TAND
))
t1
->t_dflg
|= t
->t_dflg
& (FINT
|FPAR
), execute(t1
);
register struct command
*t
;
register int flags
= t
->t_dflg
;
if (didfds
|| (flags
& FREDO
))
cp
= globone(dp
= Dfix1(cp
));
dup(pipein
[0]), close(pipein
[0]), close(pipein
[1]);
close(0), open("/dev/null", 0);
cp
= globone(dp
= Dfix1(cp
));
if ((flags
& FCAT
) && open(cp
, 1) >= 0)
if (!(flags
& FANY
) && adrof("noclobber")) {
dup((flags
& FPOU
) ? pipeout
[1] : SHOUT
);
dup((flags
& FDIAG
) ? 1 : SHDIAG
);
register int pid
, (*savint
)();
savint
= signal(SIGINT
, SIG_IGN
);
error("No more processes");
signal(SIGINT
, shudint
? SIG_DFL
: savint
);
pv
[0] = dmove(pv
[0], -1);
pv
[1] = dmove(pv
[1], -1);
if (pv
[0] >= 0 && pv
[1] >= 0)
error("Can't make pipe");
if ((stb
.st_mode
& S_IFMT
) == S_IFCHR
)
error("%s: File exists", cp
);