diff --git a/ksh.changes b/ksh.changes index 6765be4..9f90a21 100644 --- a/ksh.changes +++ b/ksh.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Tue Apr 23 12:31:35 UTC 2013 - werner@suse.de + +- Add patch ksh93-fdstatus.dif as fix for bnc#814135 and bnc#808449 + ------------------------------------------------------------------- Tue Mar 19 16:48:37 UTC 2013 - werner@suse.de diff --git a/ksh.spec b/ksh.spec index c7e9d49..73ec503 100644 --- a/ksh.spec +++ b/ksh.spec @@ -124,6 +124,9 @@ Patch30: ksh93-pathtemp.dif Patch31: ksh93-dttree-crash.dif # PATCH-FIX-UPSTREAM ksh93-heredoclex.dif [bnc#804998] Patch32: ksh93-heredoclex.dif +# PATCH-FIX-UPSTREAM ksh93-fdstatus.dif [bnc#808449, bnc#814135] +# this is a backport from the alpha version ksh93v-2013-04-22 +Patch33: ksh93-fdstatus.dif Patch42: ksh-locale.patch %description @@ -210,6 +213,7 @@ fi %patch30 %patch31 %patch32 +%patch33 %build # diff --git a/ksh93-fdstatus.dif b/ksh93-fdstatus.dif new file mode 100644 index 0000000..a02ff87 --- /dev/null +++ b/ksh93-fdstatus.dif @@ -0,0 +1,268 @@ +| 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<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);