ksh/ksh93-fdstatus.dif
2013-04-23 12:38:14 +00:00

269 lines
7.5 KiB
Plaintext

| Fix for bnc#814135 and bnc#808449
| - crash in bestreclaim() after traversing a memory block with a very large size (ksh)
| - set -k does not work properly with ksh-93t-13.17 and higher
| This is a backport from the alpha version ksh93v-2013-04-22.
--- src/cmd/ksh93/include/io.h
+++ src/cmd/ksh93/include/io.h 2013-04-23 09:27:07.997439763 +0000
@@ -81,6 +81,7 @@ extern void sh_iosave(Shell_t *, int,in
extern int sh_iovalidfd(Shell_t*, int);
extern int sh_inuse(Shell_t*, int);
extern void sh_iounsave(Shell_t*);
+extern void sh_iounpipe(Shell_t*);
extern int sh_chkopen(const char*);
extern int sh_ioaccess(int,int);
extern int sh_devtofd(const char*);
--- src/cmd/ksh93/sh/subshell.c
+++ src/cmd/ksh93/sh/subshell.c 2013-04-23 09:40:16.089940758 +0000
@@ -122,11 +122,13 @@ void sh_subtmpfile(Shell_t *shp)
register struct checkpt *pp = (struct checkpt*)shp->jmplist;
register struct subshell *sp = subshell_data->pipe;
/* save file descriptor 1 if open */
- if((sp->tmpfd = fd = fcntl(1,F_DUPFD,10)) >= 0)
+ if((sp->tmpfd = fd = sh_fcntl(1,F_DUPFD,10)) >= 0)
{
+ int err=errno;
fcntl(fd,F_SETFD,FD_CLOEXEC);
shp->fdstatus[fd] = shp->fdstatus[1]|IOCLEX;
- close(1);
+ while(close(1)<0 && errno==EINTR)
+ errno = err;
}
else if(errno!=EBADF)
errormsg(SH_DICT,ERROR_system(1),e_toomany);
@@ -138,7 +140,7 @@ void sh_subtmpfile(Shell_t *shp)
int fds[3];
Sfoff_t off;
fds[2] = 0;
- sh_pipe(fds);
+ sh_rpipe(fds);
sp->pipefd = fds[0];
sh_fcntl(sp->pipefd,F_SETFD,FD_CLOEXEC);
/* write the data to the pipe */
@@ -180,7 +182,7 @@ void sh_subfork(void)
{
register struct subshell *sp = subshell_data;
Shell_t *shp = sp->shp;
- int curenv = shp->curenv;
+ int curenv = shp->curenv, comsub=shp->comsub;
pid_t pid;
char *trap = shp->st.trapcom[0];
if(trap)
@@ -213,7 +215,7 @@ void sh_subfork(void)
shp->comsub = 0;
SH_SUBSHELLNOD->nvalue.s = 0;
sp->subpid=0;
- shp->st.trapcom[0] = trap;
+ shp->st.trapcom[0] = (comsub==2?NULL:trap);
shp->savesig = 0;
}
}
@@ -528,7 +530,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
job.curpgid = 0;
sp->subshare = shp->subshare;
sp->comsub = shp->comsub;
- shp->subshare = comsub==2 || (comsub==1 && sh_isoption(SH_SUBSHARE));
+ shp->subshare = comsub==2 || (comsub && sh_isoption(SH_SUBSHARE));
if(comsub)
shp->comsub = comsub;
if(!comsub || !shp->subshare)
@@ -602,7 +604,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
sp->tmpfd = -1;
sp->pipefd = -1;
/* use sftmp() file for standard output */
- if(!(iop = sftmp(PIPE_BUF)))
+ if(!(iop = sftmp(comsub==1?PIPE_BUF:IOBSIZE)))
{
sfswap(sp->saveout,sfstdout);
errormsg(SH_DICT,ERROR_system(1),e_tmpcreate);
@@ -688,11 +690,16 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
}
sfset(iop,SF_READ,1);
}
- sfswap(sp->saveout,sfstdout);
+ if(sp->saveout)
+ sfswap(sp->saveout,sfstdout);
+ else
+ sfstdout = &_Sfstdout;
/* check if standard output was preserved */
if(sp->tmpfd>=0)
{
- close(1);
+ int err=errno;
+ while(close(1)<0 && errno==EINTR)
+ errno = err;
if (fcntl(sp->tmpfd,F_DUPFD,1) != 1)
duped++;
sh_close(sp->tmpfd);
@@ -776,7 +783,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
shp->coutpipe = sp->coutpipe;
}
shp->subshare = sp->subshare;
- shp->comsub = sp->comsub;
shp->subdup = sp->subdup;
#if SHOPT_COSHELL
shp->coshell = sp->coshell;
@@ -806,7 +812,12 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
if(nsig>0)
kill(getpid(),nsig);
if(sp->subpid)
+ {
job_wait(sp->subpid);
+ if(comsub>1)
+ sh_iounpipe(shp);
+ }
+ shp->comsub = sp->comsub;
if(comsub && iop && sp->pipefd<0)
sfseek(iop,(off_t)0,SEEK_SET);
if(shp->trapnote)
--- src/cmd/ksh93/sh/xec.c
+++ src/cmd/ksh93/sh/xec.c 2013-04-23 10:39:02.725439216 +0000
@@ -102,26 +102,30 @@ struct funenv
* temp file.
*/
static int subpipe[3],subdup,tsetio,usepipe;
-static void iounpipe(Shell_t*);
static int iousepipe(Shell_t *shp)
{
- int i;
+ int fd=sffileno(sfstdout),i,err=errno;
if(usepipe)
{
usepipe++;
- iounpipe(shp);
+ sh_iounpipe(shp);
}
if(sh_rpipe(subpipe) < 0)
return(0);
usepipe++;
- fcntl(subpipe[0],F_SETFD,FD_CLOEXEC);
- subpipe[2] = fcntl(1,F_DUPFD,10);
- fcntl(subpipe[2],F_SETFD,FD_CLOEXEC);
+ if(shp->comsub!=1)
+ {
+ subpipe[2] = sh_fcntl(subpipe[1],F_DUPFD,10);
+ sh_close(subpipe[1]);
+ return(1);
+ }
+ subpipe[2] = sh_fcntl(fd,F_dupfd_cloexec,10);
shp->fdstatus[subpipe[2]] = shp->fdstatus[1];
- close(1);
- fcntl(subpipe[1],F_DUPFD,1);
- shp->fdstatus[1] = shp->fdstatus[subpipe[1]];
+ while(close(fd)<0 && errno==EINTR)
+ errno = err;
+ fcntl(subpipe[1],F_DUPFD,fd);
+ shp->fdstatus[1] = shp->fdstatus[subpipe[1]]&~IOCLEX;
sh_close(subpipe[1]);
if(subdup=shp->subdup) for(i=0; i < 10; i++)
{
@@ -135,14 +139,23 @@ static int iousepipe(Shell_t *shp)
return(1);
}
-static void iounpipe(Shell_t *shp)
+void sh_iounpipe(Shell_t *shp)
{
- int n;
+ int fd=sffileno(sfstdout),n,err=errno;
char buff[SF_BUFSIZE];
- close(1);
- fcntl(subpipe[2], F_DUPFD, 1);
- shp->fdstatus[1] = shp->fdstatus[subpipe[2]];
+ if(!usepipe)
+ return;
--usepipe;
+ if(shp->comsub>1)
+ {
+ sh_close(subpipe[2]);
+ while(read(subpipe[0],buff,sizeof(buff))>0);
+ goto done;
+ }
+ while(close(fd)<0 && errno==EINTR)
+ errno = err;
+ fcntl(subpipe[2], F_DUPFD, fd);
+ shp->fdstatus[1] = shp->fdstatus[subpipe[2]];
if(subdup) for(n=0; n < 10; n++)
{
if(subdup&(1<<n))
@@ -174,6 +187,7 @@ static void iounpipe(Shell_t *shp)
else if(errno!=EINTR)
break;
}
+done:
sh_close(subpipe[0]);
subpipe[0] = -1;
tsetio = 0;
@@ -1597,10 +1611,14 @@ int sh_exec(register const Shnode_t *t,
if(shp->subshell)
{
sh_subtmpfile(shp);
- if(shp->comsub==1 && !(shp->fdstatus[1]&IONOSEEK))
- unpipe=iousepipe(shp);
if((type&(FAMP|TFORK))==(FAMP|TFORK))
- sh_subfork();
+ {
+ if(shp->comsub==1 && !(shp->fdstatus[1]&IONOSEEK))
+ {
+ unpipe=iousepipe(shp);
+ sh_subfork();
+ }
+ }
}
no_fork = !ntflag && !(type&(FAMP|FPOU)) && !shp->subshell &&
!(shp->st.trapcom[SIGINT] && *shp->st.trapcom[SIGINT]) &&
@@ -1676,7 +1694,7 @@ int sh_exec(register const Shnode_t *t,
if(parent<0)
{
if(shp->comsub==1 && usepipe && unpipe)
- iounpipe(shp);
+ sh_iounpipe(shp);
break;
}
#else
@@ -1693,7 +1711,7 @@ int sh_exec(register const Shnode_t *t,
if(parent<0)
{
if(shp->comsub==1 && usepipe && unpipe)
- iounpipe(shp);
+ sh_iounpipe(shp);
break;
}
#else
@@ -1734,7 +1752,7 @@ int sh_exec(register const Shnode_t *t,
if(shp->topfd > topfd)
sh_iorestore(shp,topfd,0);
if(usepipe && tsetio && subdup && unpipe)
- iounpipe(shp);
+ sh_iounpipe(shp);
if(!sh_isoption(SH_MONITOR))
{
shp->trapnote &= ~SH_SIGIGNORE;
@@ -1954,7 +1972,7 @@ int sh_exec(register const Shnode_t *t,
shp->exitval = type;
}
if(shp->comsub==1 && usepipe)
- iounpipe(shp);
+ sh_iounpipe(shp);
shp->pipepid = 0;
shp->st.ioset = 0;
if(simple && was_errexit)
@@ -3165,7 +3183,7 @@ pid_t _sh_fork(Shell_t *shp,register pid
{
if(shp->topfd > restorefd)
sh_iorestore(shp,restorefd,0);
- iounpipe(shp);
+ sh_iounpipe(shp);
}
}
return(parent);
@@ -3626,7 +3644,7 @@ static void coproc_init(Shell_t *shp, in
sh_pipe(shp->cpipe);
if((outfd=shp->cpipe[1]) < 10)
{
- int fd=fcntl(shp->cpipe[1],F_DUPFD,10);
+ int fd=sh_fcntl(shp->cpipe[1],F_DUPFD,10);
if(fd>=10)
{
shp->fdstatus[fd] = (shp->fdstatus[outfd]&~IOCLEX);