PSARC/2014/162 ksh93 update to 2012-08-01
17533968 ksh93 uprev to latest community version
17817727 ksh93: Right shift arithmetic substitution error for shifts of 64 bits or more
17699248 ksh93 double associative array handling bugs
17777549 "kill %%" with no background jobs , coredumps
18119738 ksh93 crashes in sfio area
18229654 ksh93 read not reentrant in alarm context dumps core
16169978 ksh93 memory corruption with redirection
18302723 ksh93 segv in sh_setmatch
16507675 external command in double-nested here-document hangs ksh93
18920300 remove pkglint Warnings in ksh93 build
18355790 /usr/bin/sh and /usr/sbin/sh should point to /usr/bin/ksh93
19907453 Session drop can cause ksh93 to become a fork bomb
18426052 SPARC /usr/bin/ksh is not an XPG6 executable
20808157 attpackagemake.mk test target needs the same environment as the build
20948390 ksh93 should have some master test results to compare against
20948350 attpackagemake.mk tested-and-compared target has mis-matched parentheses
# This patch has been developed inhouse. This fixes a Solaris specific
# issue and has not been submitted to the community.
--- INIT.2012-08-01.old/src/cmd/ksh93/include/io.h 2015-02-24 13:25:19.331558350 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/include/io.h 2015-03-04 13:27:49.205782578 -0800
@@ -23,6 +23,9 @@
* David Korn
*
*/
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
#include <ast.h>
#include <sfio.h>
@@ -87,6 +90,12 @@ extern int sh_devtofd(const char*);
extern int sh_isdevfd(const char*);
extern int sh_source(Shell_t*, Sfio_t*, const char*);
+extern int VALIDATE_FD(Shell_t *, int);
+
+#define VALIDATE_FD(shp, fd) \
+ (((fd) >= (shp)->gd->lim.open_max) ? sh_iovalidfd(shp, fd) : 1)
+
+
/* the following are readonly */
extern const char e_pexists[];
extern const char e_query[];
@@ -126,4 +135,5 @@ extern const char e_bash_profile[];
extern const char e_stdprompt[];
extern const char e_supprompt[];
extern const char e_ambiguous[];
+
#endif /* KSHELL */
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/io.c 2015-02-24 13:25:19.362427732 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/io.c 2015-03-04 14:04:54.981280201 -0800
@@ -605,8 +605,10 @@ static void io_preserve(Shell_t* shp, re
((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT;
errormsg(SH_DICT,ERROR_system(1),e_toomany);
}
- if(f2 >= shp->gd->lim.open_max)
- sh_iovalidfd(shp,f2);
+
+ VALIDATE_FD(shp, fd);
+ VALIDATE_FD(shp, f2);
+
if(shp->fdptrs[fd]=shp->fdptrs[f2])
{
if(f2==job.fd)
@@ -632,7 +634,12 @@ static void io_preserve(Shell_t* shp, re
*/
int sh_iorenumber(Shell_t *shp, register int f1,register int f2)
{
- register Sfio_t *sp = shp->sftable[f2];
+ register Sfio_t *sp;
+
+ VALIDATE_FD(shp, f1);
+ VALIDATE_FD(shp, f2);
+
+ sp = shp->sftable[f2];
if(f1!=f2)
{
/* see whether file descriptor is in use */
@@ -672,8 +679,7 @@ int sh_iorenumber(Shell_t *shp, register
if(f2<=2)
sfset(sp,SF_SHARE|SF_PUBLIC,1);
}
- if(f2>=shp->gd->lim.open_max)
- sh_iovalidfd(shp,f2);
+ VALIDATE_FD(shp, f2);
return(f2);
}
@@ -687,8 +693,9 @@ int sh_close(register int fd)
register int r = 0;
if(fd<0)
return(-1);
- if(fd >= shp->gd->lim.open_max)
- sh_iovalidfd(shp,fd);
+
+ VALIDATE_FD(shp, fd);
+
if(!(sp=shp->sftable[fd]) || sfclose(sp) < 0)
{
int err=errno;
@@ -846,8 +853,7 @@ int sh_open(register const char *path, i
mode = (IOREAD|IOWRITE);
else
mode = IOREAD;
- if(fd >= shp->gd->lim.open_max)
- sh_iovalidfd(shp,fd);
+ VALIDATE_FD(shp, fd);
shp->fdstatus[fd] = mode;
return(fd);
}
@@ -876,6 +882,8 @@ int sh_iomovefd(register int fdold)
if(fdold<0 || fdold>2)
return(fdold);
fdnew = sh_iomovefd(dup(fdold));
+ VALIDATE_FD(shp, fdold);
+ VALIDATE_FD(shp, fdnew);
shp->fdstatus[fdnew] = (shp->fdstatus[fdold]&~IOCLEX);
close(fdold);
shp->fdstatus[fdold] = IOCLOSE;
@@ -936,6 +944,9 @@ int sh_pipe(register int pv[])
sh_close(fd);
else
pv[out] = sh_iomovefd(fd);
+
+ VALIDATE_FD(shp, pv[out]);
+
if(fcntl(pv[out],F_SETFD,FD_CLOEXEC) >=0)
shp->fdstatus[pv[out]] |= IOCLEX;
shp->fdstatus[pv[out]] = (out?IOWRITE:IOREAD);
@@ -968,6 +979,9 @@ int sh_pipe(register int pv[])
errormsg(SH_DICT,ERROR_system(1),e_pipe);
}
fcntl(pv[out],F_SETFD,FD_CLOEXEC);
+
+ VALIDATE_FD(shp, pv[out]);
+
shp->fdstatus[pv[out]] |= IOCLEX;
pv[1-out] = -1;
pv[2] = port;
@@ -997,9 +1011,13 @@ static int pat_line(const regex_t* rp, c
static int io_patseek(Shell_t *shp, regex_t *rp, Sfio_t* sp, int flags)
{
char *cp, *match;
- int r, fd=sffileno(sp), close_exec = shp->fdstatus[fd]&IOCLEX;
+ int r, fd, close_exec;
int was_share,s=(PIPE_BUF>SF_BUFSIZE?SF_BUFSIZE:PIPE_BUF);
size_t n,m;
+
+ fd = sffileno(sp);
+ VALIDATE_FD(shp, fd);
+ close_exec = shp->fdstatus[fd]&IOCLEX;
shp->fdstatus[sffileno(sp)] |= IOCLEX;
if(fd==0)
was_share = sfset(sp,SF_SHARE,1);
@@ -1033,12 +1051,17 @@ static int io_patseek(Shell_t *shp, rege
static Sfoff_t file_offset(Shell_t *shp, int fn, char *fname)
{
- Sfio_t *sp = shp->sftable[fn];
+ Sfio_t *sp;
char *cp;
Sfoff_t off;
struct Eof endf;
Namval_t *mp = nv_open("EOF",shp->var_tree,0);
Namval_t *pp = nv_open("CUR",shp->var_tree,0);
+
+ VALIDATE_FD(shp, fn);
+
+ sp = shp->sftable[fn];
+
memset(&endf,0,sizeof(struct Eof));
endf.fd = fn;
endf.hdr.disc = &EOF_disc;
@@ -1216,7 +1239,7 @@ int sh_redirect(Shell_t *shp,struct iono
if((iof&IOLSEEK) || ((iof&IOMOV) && *fname=='-'))
fn = nv_getnum(np);
}
- if(fn>=shp->gd->lim.open_max && !sh_iovalidfd(shp,fn))
+ if (!VALIDATE_FD(shp, fn))
errormsg(SH_DICT,ERROR_system(1),e_file+4);
if(iof&IOLSEEK)
{
@@ -1259,6 +1282,7 @@ int sh_redirect(Shell_t *shp,struct iono
message = e_file;
goto fail;
}
+ VALIDATE_FD(shp, dupfd);
if(shp->subshell && dupfd==1)
{
if(sfset(sfstdout,0,0)&SF_STRING)
@@ -1295,8 +1319,7 @@ int sh_redirect(Shell_t *shp,struct iono
goto traceit;
if((fd=sh_fcntl(dupfd,F_DUPFD,3))<0)
goto fail;
- if(fd>= shp->gd->lim.open_max)
- sh_iovalidfd(shp,fd);
+ VALIDATE_FD(shp, fd);
sh_iocheckfd(shp,dupfd);
shp->fdstatus[fd] = (shp->fdstatus[dupfd]&~IOCLEX);
if(toclose<0 && shp->fdstatus[fd]&IOREAD)
@@ -1410,7 +1433,11 @@ int sh_redirect(Shell_t *shp,struct iono
}
if(iof&IOLSEEK)
{
- Sfio_t *sp = shp->sftable[fn];
+ Sfio_t *sp;
+
+ VALIDATE_FD(shp, fn);
+
+ sp = shp->sftable[fn];
r = shp->fdstatus[fn];
if(!(r&(IOSEEK|IONOSEEK)))
r = sh_iocheckfd(shp,fn);
@@ -1491,6 +1518,7 @@ int sh_redirect(Shell_t *shp,struct iono
}
if(fd<0)
{
+ VALIDATE_FD(shp, fn);
if(sh_inuse(shp,fn) || (fn && fn==shp->infd))
{
if(fn>9 || !(shp->inuse_bits&(1<<fn)))
@@ -1510,7 +1538,7 @@ int sh_redirect(Shell_t *shp,struct iono
{
if((fn=fcntl(fd,F_DUPFD,10)) < 0)
goto fail;
- if(fn>=shp->gd->lim.open_max && !sh_iovalidfd(shp,fn))
+ if (!VALIDATE_FD(shp, fn))
goto fail;
if(flag!=2 || shp->subshell)
sh_iosave(shp,fn,indx|0x10000,tname?fname:(trunc?Empty:0));
@@ -1701,7 +1729,12 @@ void sh_iosave(Shell_t *shp, register in
filemap[shp->topfd++].save_fd = savefd;
if(savefd >=0)
{
- register Sfio_t* sp = shp->sftable[origfd];
+ register Sfio_t* sp;
+
+ VALIDATE_FD(shp, origfd);
+ VALIDATE_FD(shp, savefd);
+
+ sp = shp->sftable[origfd];
/* make saved file close-on-exec */
sh_fcntl(savefd,F_SETFD,FD_CLOEXEC);
if(origfd==job.fd)
@@ -1734,6 +1767,7 @@ void sh_iounsave(Shell_t* shp)
filemap[newfd++] = filemap[fd];
else
{
+ VALIDATE_FD(shp, savefd);
shp->sftable[savefd] = 0;
sh_close(savefd);
}
@@ -1757,16 +1791,19 @@ void sh_iorestore(Shell_t *shp, int last
{
if ((savefd = filemap[fd].save_fd) >= 0)
{
+ VALIDATE_FD(shp, savefd);
shp->sftable[savefd] = 0;
sh_close(savefd);
}
continue;
}
origfd = filemap[fd].orig_fd;
+ VALIDATE_FD(shp, origfd);
if(origfd<0)
{
/* this should never happen */
savefd = filemap[fd].save_fd;
+ VALIDATE_FD(shp, savefd);
shp->sftable[savefd] = 0;
sh_close(savefd);
return;
@@ -1778,6 +1815,7 @@ void sh_iorestore(Shell_t *shp, int last
sh_close(origfd);
if ((savefd = filemap[fd].save_fd) >= 0)
{
+ VALIDATE_FD(shp, savefd);
sh_fcntl(savefd, F_DUPFD, origfd);
if(savefd==job.fd)
job.fd=origfd;
@@ -2035,6 +2073,9 @@ static ssize_t slowread(Sfio_t *iop,void
int sh_iocheckfd(Shell_t *shp, register int fd)
{
register int flags, n;
+
+ VALIDATE_FD(shp, fd);
+
if((n=shp->fdstatus[fd])&IOCLOSE)
return(n);
if(!(n&(IOREAD|IOWRITE)))
@@ -2226,7 +2267,7 @@ static void sftrack(Sfio_t* sp, int flag
return;
}
#endif
- if(fd<0 || fd==PSEUDOFD || (fd>=shp->gd->lim.open_max && !sh_iovalidfd(shp,fd)))
+ if(fd<0 || fd==PSEUDOFD || !VALIDATE_FD(shp, fd))
return;
if(sh_isstate(SH_NOTRACK))
return;
@@ -2495,6 +2536,8 @@ ssize_t sh_read(register int fd, void* b
{
Shell_t *shp = sh_getinterp();
register Sfio_t *sp;
+
+ VALIDATE_FD(shp, fd);
if(sp=shp->sftable[fd])
return(sfread(sp,buff,n));
else
@@ -2509,6 +2552,8 @@ ssize_t sh_write(register int fd, const
{
Shell_t *shp = sh_getinterp();
register Sfio_t *sp;
+
+ VALIDATE_FD(shp, fd);
if(sp=shp->sftable[fd])
return(sfwrite(sp,buff,n));
else
@@ -2523,6 +2568,8 @@ off_t sh_seek(register int fd, off_t off
{
Shell_t *shp = sh_getinterp();
register Sfio_t *sp;
+
+ VALIDATE_FD(shp, fd);
if((sp=shp->sftable[fd]) && (sfset(sp,0,0)&(SF_READ|SF_WRITE)))
return(sfseek(sp,offset,whence));
else
@@ -2534,6 +2581,9 @@ int sh_dup(register int old)
{
Shell_t *shp = sh_getinterp();
register int fd = dup(old);
+
+ VALIDATE_FD(shp, old);
+ VALIDATE_FD(shp, fd);
if(fd>=0)
{
if(shp->fdstatus[old] == IOCLOSE)
@@ -2555,13 +2605,15 @@ int sh_fcntl(register int fd, int op, ..
arg = va_arg(ap, int) ;
va_end(ap);
newfd = fcntl(fd,op,arg);
+
+ VALIDATE_FD(shp, fd);
+ VALIDATE_FD(shp, newfd);
+
if(newfd>=0) switch(op)
{
case F_DUPFD:
if(shp->fdstatus[fd] == IOCLOSE)
shp->fdstatus[fd] = 0;
- if(newfd>=shp->gd->lim.open_max)
- sh_iovalidfd(shp,newfd);
shp->fdstatus[newfd] = (shp->fdstatus[fd]&~IOCLEX);
if(fdnotify)
(*fdnotify)(fd,newfd);
@@ -2630,6 +2682,7 @@ Sfio_t *sh_iogetiop(int fd, int mode)
return(iop);
if(mode==SF_READ && !(n&IOREAD))
return(iop);
+ VALIDATE_FD(shp, fd);
if(!(iop = shp->sftable[fd]))
iop=sh_iostream(shp,fd);
return(iop);
@@ -2649,7 +2702,10 @@ Sfio_t *sh_fd2sfio(int fd)
{
Shell_t *shp = sh_getinterp();
register int status;
- Sfio_t *sp = shp->sftable[fd];
+ Sfio_t *sp;
+
+ VALIDATE_FD(shp, fd);
+ sp = shp->sftable[fd];
if(!sp && (status = sh_iocheckfd(shp,fd))!=IOCLOSE)
{
register int flags=0;
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/lex.c 2015-02-24 13:25:19.370183959 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/lex.c 2015-03-04 13:27:49.211457345 -0800
@@ -25,6 +25,9 @@
* AT&T Labs
*
*/
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
#include <ast.h>
#include <stak.h>
@@ -2122,6 +2125,7 @@ void sh_syntax(Lex_t *lp)
else
lp->lastline = shp->inlineno;
tokstr = fmttoken(lp,tok,tokbuf);
+ VALIDATE_FD(shp, shp->infd);
if((sp=fcfile()) || (shp->infd>=0 && (sp=shp->sftable[shp->infd])))
{
/* clear out any pending input */
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/macro.c 2015-02-24 13:25:19.363200741 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/macro.c 2015-03-04 13:27:49.212566247 -0800
@@ -2121,6 +2121,7 @@ static void comsubst(Mac_t *mp,register
sh_popcontext(mp->shp,&buff);
if(r==0 && ip && (ip->iofile&IOLSEEK))
{
+ VALIDATE_FD(mp->shp, fd);
if(sp=mp->shp->sftable[fd])
num = sftell(sp);
else
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/main.c 2015-02-24 13:25:19.364162232 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/main.c 2015-03-04 13:27:49.213386462 -0800
@@ -26,6 +26,9 @@
* AT&T Labs
*
*/
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
#include <ast.h>
#include <sfio.h>
@@ -376,8 +379,10 @@ static void exfile(register Shell_t *shp
if(fno > 0)
{
int r;
+ VALIDATE_FD(shp, fno);
if(fno < 10 && ((r=sh_fcntl(fno,F_DUPFD,10))>=10))
{
+ VALIDATE_FD(shp, r);
shp->fdstatus[r] = shp->fdstatus[fno];
sh_close(fno);
fno = r;
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/path.c 2015-02-24 13:25:19.360898415 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/path.c 2015-03-04 13:27:49.214381188 -0800
@@ -23,6 +23,9 @@
* AT&T Labs
*
*/
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ */
#include "defs.h"
#include <fcin.h>
@@ -1272,6 +1275,7 @@ static void exscript(Shell_t *shp,regist
if(sp=fcfile())
while(sfstack(sp,SF_POPSTACK));
job_clear();
+ VALIDATE_FD(shp, shp->infd);
if(shp->infd>0 && (shp->fdstatus[shp->infd]&IOCLEX))
sh_close(shp->infd);
sh_setstate(sh_state(SH_FORKED));
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/subshell.c 2015-02-24 13:25:19.363479570 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/subshell.c 2015-03-04 14:05:03.665801329 -0800
@@ -125,6 +125,7 @@ void sh_subtmpfile(Shell_t *shp)
if((sp->tmpfd = fd = fcntl(1,F_DUPFD,10)) >= 0)
{
fcntl(fd,F_SETFD,FD_CLOEXEC);
+ VALIDATE_FD(shp, fd);
shp->fdstatus[fd] = shp->fdstatus[1]|IOCLEX;
close(1);
}
@@ -151,6 +152,7 @@ void sh_subtmpfile(Shell_t *shp)
}
else
{
+ VALIDATE_FD(shp, fd);
shp->fdstatus[fd] = IOREAD|IOWRITE;
sfsync(sfstdout);
if(fd==1)
@@ -679,8 +681,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT;
errormsg(SH_DICT,ERROR_system(1),e_toomany);
}
- if(fd >= shp->gd->lim.open_max)
- sh_iovalidfd(shp,fd);
+ VALIDATE_FD(shp, fd);
shp->sftable[fd] = iop;
fcntl(fd,F_SETFD,FD_CLOEXEC);
shp->fdstatus[fd] = (shp->fdstatus[1]|IOCLEX);
--- INIT.2012-08-01.old/src/cmd/ksh93/sh/xec.c 2015-02-24 13:25:19.365424099 -0800
+++ INIT.2012-08-01/src/cmd/ksh93/sh/xec.c 2015-03-04 14:05:12.823587666 -0800
@@ -117,6 +117,8 @@ static int iousepipe(Shell_t *shp)
usepipe++;
fcntl(subpipe[0],F_SETFD,FD_CLOEXEC);
subpipe[2] = fcntl(1,F_DUPFD,10);
+ VALIDATE_FD(shp, subpipe[1]);
+ VALIDATE_FD(shp, subpipe[2]);
fcntl(subpipe[2],F_SETFD,FD_CLOEXEC);
shp->fdstatus[subpipe[2]] = shp->fdstatus[1];
close(1);
@@ -141,6 +143,7 @@ static void iounpipe(Shell_t *shp)
char buff[SF_BUFSIZE];
close(1);
fcntl(subpipe[2], F_DUPFD, 1);
+ VALIDATE_FD(shp, subpipe[2]);
shp->fdstatus[1] = shp->fdstatus[subpipe[2]];
--usepipe;
if(subdup) for(n=0; n < 10; n++)
@@ -886,6 +889,7 @@ static int sh_coexec(Shell_t *shp,const
if(filt > 2)
{
shp->coutpipe = shp->inpipe[1];
+ VALIDATE_FD(shp, shp->coutpipe);
shp->fdptrs[shp->coutpipe] = &shp->coutpipe;
}
}
@@ -1646,6 +1650,7 @@ int sh_exec(register const Shnode_t *t,
if(shp->cpipe[0]<0 || shp->cpipe[1] < 0)
{
sh_copipe(shp,shp->outpipe=shp->cpipe,0);
+ VALIDATE_FD(shp, shp->cpipe[0]);
shp->fdptrs[shp->cpipe[0]] = shp->cpipe;
}
sh_copipe(shp,shp->inpipe=pipes,0);
@@ -3623,6 +3628,8 @@ static void coproc_init(Shell_t *shp, in
if((outfd=shp->cpipe[1]) < 10)
{
int fd=fcntl(shp->cpipe[1],F_DUPFD,10);
+ VALIDATE_FD(shp, outfd);
+ VALIDATE_FD(shp, fd);
if(fd>=10)
{
shp->fdstatus[fd] = (shp->fdstatus[outfd]&~IOCLEX);
@@ -3631,6 +3638,9 @@ static void coproc_init(Shell_t *shp, in
shp->cpipe[1] = fd;
}
}
+ VALIDATE_FD(shp, shp->cpipe[0]);
+ VALIDATE_FD(shp, shp->cpipe[1]);
+
if(fcntl(*shp->cpipe,F_SETFD,FD_CLOEXEC)>=0)
shp->fdstatus[shp->cpipe[0]] |= IOCLEX;
shp->fdptrs[shp->cpipe[0]] = shp->cpipe;
@@ -3641,7 +3651,9 @@ static void coproc_init(Shell_t *shp, in
shp->outpipe = shp->cpipe;
sh_pipe(shp->inpipe=pipes);
shp->coutpipe = shp->inpipe[1];
+ VALIDATE_FD(shp, shp->coutpipe);
shp->fdptrs[shp->coutpipe] = &shp->coutpipe;
+ VALIDATE_FD(shp, shp->outpipe[0]);
if(fcntl(shp->outpipe[0],F_SETFD,FD_CLOEXEC)>=0)
shp->fdstatus[shp->outpipe[0]] |= IOCLEX;
}
@@ -3812,6 +3824,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons
int fd = shp->inpipe[1];
sh_iosave(shp,0,buffp->topfd,(char*)0);
sh_iorenumber(shp,shp->inpipe[0],0);
+ VALIDATE_FD(shp, fd);
if(fd>=0 && (!(otype&FPOU) || (otype&FCOOP)) && fcntl(fd,F_SETFD,FD_CLOEXEC)>=0)
shp->fdstatus[fd] |= IOCLEX;
}
@@ -3823,6 +3836,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons
#endif /* SHOPT_COSHELL */
sh_iosave(shp,1,buffp->topfd,(char*)0);
sh_iorenumber(shp,sh_dup(shp->outpipe[1]),1);
+ VALIDATE_FD(shp, shp->outpipe[0]);
if(fcntl(shp->outpipe[0],F_SETFD,FD_CLOEXEC)>=0)
shp->fdstatus[shp->outpipe[0]] |= IOCLEX;
}
@@ -3862,6 +3876,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons
signal(SIGQUIT,sh_fault);
signal(SIGINT,sh_fault);
}
+ VALIDATE_FD(shp, shp->inpipe[1]);
if((otype&FPIN) && (!(otype&FPOU) || (otype&FCOOP)) && fcntl(shp->inpipe[1],F_SETFD,FD_CLOEXEC)>=0)
shp->fdstatus[shp->inpipe[1]] &= ~IOCLEX;
if(t->fork.forkio || otype)