From ebf9b31727c58591bdc8617444d9b18556cfb2de Mon Sep 17 00:00:00 2001 From: Michal Hlavinka Date: Jul 24 2014 11:13:05 +0000 Subject: fix segfault in job list code - do not resend signal on termination (#1092132) - fix brace expansion on/off - fix incorrect rounding of numsers 0.5 < |x| <1.0 in printf (#1080940) - fix parser errors related to the end of the here-document marker - ksh hangs when command substitution fills out the pipe buffer - using typeset -l with a restricted variabled caused segmentation fault - monitor mode was documented incorrectly - do not crash when unsetting running function from another one (#1105139) - should report an error when trying to cd into directory without execution bit - job locking mechanism did not survive compiler optimization - reading a file via command substitution did not work when any of stdin, stdout or stderr were closed (#1070308) - fix lexical parser crash --- diff --git a/ksh-20070328-builtins.patch b/ksh-20070328-builtins.patch index 5c6b21c..061bf9a 100644 --- a/ksh-20070328-builtins.patch +++ b/ksh-20070328-builtins.patch @@ -1,32 +1,11 @@ -diff -up ksh-20120620/src/cmd/ksh93/data/builtins.c.builtins ksh-20120620/src/cmd/ksh93/data/builtins.c ---- ksh-20120620/src/cmd/ksh93/data/builtins.c.builtins 2012-06-19 10:02:12.000000000 +0200 -+++ ksh-20120620/src/cmd/ksh93/data/builtins.c 2012-06-22 12:35:05.587717588 +0200 -@@ -131,20 +131,28 @@ const struct shtable3 shtab_builtins[] = - #undef mktemp /* undo possible map-libc mktemp => _ast_mktemp */ - #include SHOPT_CMDLIB_HDR - #else -+#if 1 - CMDLIST(basename) - CMDLIST(chmod) +diff -up ksh-20080202/src/cmd/ksh93/data/builtins.c.builtins ksh-20080202/src/cmd/ksh93/data/builtins.c +--- ksh-20080202/src/cmd/ksh93/data/builtins.c.builtins 2008-10-01 09:24:46.000000000 +0200 ++++ ksh-20080202/src/cmd/ksh93/data/builtins.c 2008-10-01 09:24:58.000000000 +0200 +@@ -129,7 +129,6 @@ const struct shtable3 shtab_builtins[] = CMDLIST(dirname) CMDLIST(getconf) CMDLIST(head) -+#if 0 -+does not work when ACLs are used - CMDLIST(mkdir) -+#endif +- CMDLIST(mkdir) CMDLIST(logname) -+#if 1 -+//does not work in chrooted environments, because /dev/fd/? is missing CMDLIST(cat) -+#endif CMDLIST(cmp) - CMDLIST(cut) - CMDLIST(uname) - CMDLIST(wc) - CMDLIST(sync) - #endif -+#endif - #if SHOPT_REGRESS - "__regress__", NV_BLTIN|BLT_ENV, bltin(__regress__), - #endif diff --git a/ksh-20080202-manfix.patch b/ksh-20080202-manfix.patch new file mode 100644 index 0000000..8fe4225 --- /dev/null +++ b/ksh-20080202-manfix.patch @@ -0,0 +1,47 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh.1.manfix ksh-20120801/src/cmd/ksh93/sh.1 +--- ksh-20120801/src/cmd/ksh93/sh.1.manfix 2012-06-18 16:16:22.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh.1 2013-04-30 13:35:17.393909479 +0200 +@@ -39,7 +39,7 @@ ksh93, rksh93, pfksh93 \- KornShell, a s + .B ksh93 + .\} + [ +-.B \(+-abcefhikmnoprstuvxBCDP ++.B \(+-abcefhiknoprstuvxBCDP + ] [ + .B \-R + file ] [ +@@ -47,25 +47,6 @@ file ] [ + option ] .\|.\|. [ + .B \- + ] [ arg .\|.\|. ] +-.br +-.if \nZ=0 \{\ +-.B rsh +-.\} +-.if \nZ=1 \{\ +-.B rksh +-.\} +-.if \nZ=2 \{\ +-.B rksh93 +-.\} +-[ +-.B \(+-abcefhikmnoprstuvxBCD +-] [ +-.B \-R +-file ] [ +-.B \(+-o +-option ] .\|.\|. [ +-.B \- +-] [ arg .\|.\|. ] + .SH DESCRIPTION + .if \nZ=0 .I Sh\^ + .if \nZ=1 .I Ksh\^ +@@ -7963,6 +7944,8 @@ option is used + to generate a cross reference database + that can be used by a separate utility + to find definitions and references for variables and commands. ++The filename argument specifies the generated database. A script file must be ++provided on the command line as well. + .PP + The remaining options and arguments are described under the + .B set diff --git a/ksh-20100202-pathvar.patch b/ksh-20100202-pathvar.patch new file mode 100644 index 0000000..5086499 --- /dev/null +++ b/ksh-20100202-pathvar.patch @@ -0,0 +1,20 @@ +diff -up ksh-20100202/src/cmd/ksh93/sh.1.pathvar ksh-20100202/src/cmd/ksh93/sh.1 +--- ksh-20100202/src/cmd/ksh93/sh.1.pathvar 2011-04-26 16:42:08.000000000 +0200 ++++ ksh-20100202/src/cmd/ksh93/sh.1 2011-04-27 09:09:00.315883280 +0200 +@@ -4025,13 +4025,9 @@ the directory containing the command. + Alternative directory names are separated by + a colon + .RB ( : ). +-The default path is +-.B /bin:/usr/bin: +-(specifying +-.BR /bin , +-.BR /usr/bin , +-and the current directory +-in that order). ++The default path is equal to ++.BI getconf\ PATH ++output. + The current directory can be specified by + two or more adjacent colons, or by a colon + at the beginning or end of the path list. diff --git a/ksh-20100621-fdstatus.patch b/ksh-20100621-fdstatus.patch new file mode 100644 index 0000000..99abb55 --- /dev/null +++ b/ksh-20100621-fdstatus.patch @@ -0,0 +1,54 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.fdstatus ksh-20120801/src/cmd/ksh93/sh/io.c +--- ksh-20120801/src/cmd/ksh93/sh/io.c.fdstatus 2013-07-04 18:01:27.187516655 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/io.c 2013-07-04 18:01:38.249607392 +0200 +@@ -1508,7 +1508,7 @@ int sh_redirect(Shell_t *shp,struct iono + fn = fd; + if(fd<10) + { +- if((fn=fcntl(fd,F_DUPFD,10)) < 0) ++ if((fn=sh_fcntl(fd,F_DUPFD,10)) < 0) + goto fail; + if(fn>=shp->gd->lim.open_max && !sh_iovalidfd(shp,fn)) + goto fail; +diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.fdstatus ksh-20120801/src/cmd/ksh93/sh/subshell.c +--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.fdstatus 2012-07-17 23:54:21.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2013-07-04 17:56:20.342000310 +0200 +@@ -122,7 +122,7 @@ 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) + { + fcntl(fd,F_SETFD,FD_CLOEXEC); + shp->fdstatus[fd] = shp->fdstatus[1]|IOCLEX; +@@ -554,7 +554,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + sp->pwdfd = n; + if(n<10) + { +- sp->pwdfd = fcntl(n,F_DUPFD,10); ++ sp->pwdfd = sh_fcntl(n,F_DUPFD,10); + close(n); + } + if(sp->pwdfd>0) +diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.fdstatus ksh-20120801/src/cmd/ksh93/sh/xec.c +--- ksh-20120801/src/cmd/ksh93/sh/xec.c.fdstatus 2012-07-23 16:49:32.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2013-07-04 17:57:47.153712116 +0200 +@@ -116,7 +116,7 @@ static int iousepipe(Shell_t *shp) + return(0); + usepipe++; + fcntl(subpipe[0],F_SETFD,FD_CLOEXEC); +- subpipe[2] = fcntl(1,F_DUPFD,10); ++ subpipe[2] = sh_fcntl(1,F_DUPFD,10); + fcntl(subpipe[2],F_SETFD,FD_CLOEXEC); + shp->fdstatus[subpipe[2]] = shp->fdstatus[1]; + close(1); +@@ -3622,7 +3622,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); diff --git a/ksh-20100621-manfix3.patch b/ksh-20100621-manfix3.patch new file mode 100644 index 0000000..bced575 --- /dev/null +++ b/ksh-20100621-manfix3.patch @@ -0,0 +1,12 @@ +diff -up ksh-20100621/src/cmd/ksh93/sh.1.manfix3 ksh-20100621/src/cmd/ksh93/sh.1 +--- ksh-20100621/src/cmd/ksh93/sh.1.manfix3 2013-05-02 13:07:51.180529762 +0200 ++++ ksh-20100621/src/cmd/ksh93/sh.1 2013-05-02 13:11:30.469327199 +0200 +@@ -7585,7 +7585,7 @@ file descriptor 2. + If the + .B \-i + option is present or +-if the shell input and output are attached to a terminal (as told by ++if the shell input and error output are attached to a terminal (as told by + .IR tcgetattr (2)), + then this shell is + .IR interactive . diff --git a/ksh-20120801-cdfix3.patch b/ksh-20120801-cdfix3.patch new file mode 100644 index 0000000..7e47f71 --- /dev/null +++ b/ksh-20120801-cdfix3.patch @@ -0,0 +1,12 @@ +diff -up ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix3 ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c +--- ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix3 2014-06-20 12:39:02.757407689 +0200 ++++ ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c 2014-06-20 12:40:19.530998070 +0200 +@@ -290,7 +290,7 @@ int b_cd(int argc, char *argv[],Shbltin_ + if(newdirfd >=0) + { + /* chdir for directories on HSM/tapeworms may take minutes */ +- if(fchdir(newdirfd) >= 0) ++ if((rval=fchdir(newdirfd)) >= 0) + { + if(shp->pwdfd >= 0) + sh_close(shp->pwdfd); diff --git a/ksh-20120801-covsfix.patch b/ksh-20120801-covsfix.patch new file mode 100644 index 0000000..c64e2a7 --- /dev/null +++ b/ksh-20120801-covsfix.patch @@ -0,0 +1,58 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.covsfix ksh-20120801/src/cmd/ksh93/sh/init.c +--- ksh-20120801/src/cmd/ksh93/sh/init.c.covsfix 2013-07-22 17:41:34.674054068 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/init.c 2013-07-22 17:42:50.761361921 +0200 +@@ -1237,9 +1237,11 @@ static void put_mode(Namval_t* np, const + mode = *(double*)val; + } + else ++ { + mode = strperm(val, &last,0); +- if(*last) +- errormsg(SH_DICT,ERROR_exit(1),"%s: invalid mode string",val); ++ if(*last) ++ errormsg(SH_DICT,ERROR_exit(1),"%s: invalid mode string",val); ++ } + nv_putv(np,(char*)&mode,NV_INTEGER,nfp); + } + else +diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.covsfix ksh-20120801/src/cmd/ksh93/sh/io.c +--- ksh-20120801/src/cmd/ksh93/sh/io.c.covsfix 2013-07-22 17:06:30.282927080 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/io.c 2013-07-22 17:08:49.645721280 +0200 +@@ -954,6 +954,7 @@ int sh_pipe(register int pv[]) + socklen_t slen; + if ((pv[out] = socket (AF_INET, SOCK_STREAM, 0)) < 0) + errormsg(SH_DICT,ERROR_system(1),e_pipe); ++ memset(&sin.sin_zero, 0, sizeof(sin.sin_zero)); + do + { + sin.sin_family = AF_INET; +diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.covsfix ksh-20120801/src/cmd/ksh93/sh/name.c +--- ksh-20120801/src/cmd/ksh93/sh/name.c.covsfix 2013-07-22 17:40:31.644635604 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/name.c 2013-07-22 17:41:15.828227073 +0200 +@@ -3094,6 +3094,7 @@ void nv_newattr (register Namval_t *np, + if(!mp) + nv_putval (np, cp, NV_RDONLY); + free(cp); ++ cp = NULL; + } + } + while(ap && nv_nextsub(np)); +diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.covsfix ksh-20120801/src/cmd/ksh93/sh/subshell.c +--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.covsfix 2013-07-22 17:46:15.607533423 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2013-07-22 17:48:36.739290968 +0200 +@@ -205,7 +205,14 @@ void sh_subfork(void) + shp->comsub = 0; + SH_SUBSHELLNOD->nvalue.s = 0; + sp->subpid=0; +- shp->st.trapcom[0] = (comsub==2?NULL:trap); ++ if (comsub==2) ++ { ++ shp->st.trapcom[0] = NULL; ++ if(trap) ++ free((void*)trap); ++ } ++ else ++ shp->st.trapcom[0] = (comsub==2?NULL:trap); + shp->savesig = 0; + } + } diff --git a/ksh-20120801-crash.patch b/ksh-20120801-crash.patch new file mode 100644 index 0000000..37b7962 --- /dev/null +++ b/ksh-20120801-crash.patch @@ -0,0 +1,64 @@ +diff -up ksh-20120801/src/cmd/ksh93/include/jobs.h.crash ksh-20120801/src/cmd/ksh93/include/jobs.h +--- ksh-20120801/src/cmd/ksh93/include/jobs.h.crash 2014-07-22 11:48:57.205062905 +0200 ++++ ksh-20120801/src/cmd/ksh93/include/jobs.h 2014-07-22 11:48:57.243062711 +0200 +@@ -118,6 +118,7 @@ struct jobs + char jobcontrol; /* turned on for real job control */ + char waitsafe; /* wait will not block */ + char waitall; /* wait for all jobs in pipe */ ++ char hack1_waitall; + char toclear; /* job table needs clearing */ + unsigned char *freejobs; /* free jobs numbers */ + #if SHOPT_COSHELL +diff -up ksh-20120801/src/cmd/ksh93/sh/jobs.c.crash ksh-20120801/src/cmd/ksh93/sh/jobs.c +--- ksh-20120801/src/cmd/ksh93/sh/jobs.c.crash 2014-07-22 11:48:57.190062982 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/jobs.c 2014-07-22 11:48:57.243062711 +0200 +@@ -1957,6 +1957,7 @@ again: + { + count = bp->count; + jp = bp->list; ++ jpold = 0; + goto again; + } + if(jp) +diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.crash ksh-20120801/src/cmd/ksh93/sh/subshell.c +--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.crash 2014-07-22 11:48:57.234062758 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-07-22 11:54:04.164491483 +0200 +@@ -492,6 +492,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + struct sh_scoped savst; + struct dolnod *argsav=0; + int argcnt; ++ int pipefail = 0; + memset((char*)sp, 0, sizeof(*sp)); + sfsync(shp->outpool); + sh_sigcheck(shp); +@@ -541,7 +542,10 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + sp->comsub = shp->comsub; + shp->subshare = comsub==2 || (comsub==1 && sh_isoption(SH_SUBSHARE)); + if(comsub) ++ { + shp->comsub = comsub; ++ job.hack1_waitall=(comsub==1); ++ } + sp->shpwdfd=-1; + if(!comsub || !shp->subshare) + { +@@ -648,6 +652,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + } + else + { ++ job.hack1_waitall=0; + if(comsub!=1 && shp->spid) + { + job_wait(shp->spid); +diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.crash ksh-20120801/src/cmd/ksh93/sh/xec.c +--- ksh-20120801/src/cmd/ksh93/sh/xec.c.crash 2014-07-22 11:48:57.228062787 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-07-22 11:48:57.245062700 +0200 +@@ -2125,7 +2125,7 @@ int sh_exec(register const Shnode_t *t, + memset(exitval,0,job.waitall*sizeof(int)); + } + else +- job.waitall |= !pipejob && sh_isstate(SH_MONITOR); ++ job.waitall |= job.hack1_waitall || !pipejob && sh_isstate(SH_MONITOR); + job_lock(); + nlock++; + do diff --git a/ksh-20120801-fd2lost.patch b/ksh-20120801-fd2lost.patch new file mode 100644 index 0000000..0605f6e --- /dev/null +++ b/ksh-20120801-fd2lost.patch @@ -0,0 +1,72 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/macro.c.fd2lost ksh-20120801/src/cmd/ksh93/sh/macro.c +--- ksh-20120801/src/cmd/ksh93/sh/macro.c.fd2lost 2014-01-22 16:23:21.211658984 +0100 ++++ ksh-20120801/src/cmd/ksh93/sh/macro.c 2014-01-22 16:23:21.243658703 +0100 +@@ -391,7 +391,7 @@ void sh_machere(Shell_t *shp,Sfio_t *inf + break; + } + case S_PAR: +- comsubst(mp,(Shnode_t*)0,1); ++ comsubst(mp,(Shnode_t*)0,3); + break; + case S_EOF: + if((c=fcfill()) > 0) +@@ -1165,7 +1165,7 @@ retry1: + case S_PAR: + if(type) + goto nosub; +- comsubst(mp,(Shnode_t*)0,1); ++ comsubst(mp,(Shnode_t*)0,3); + return(1); + case S_DIG: + var = 0; +diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.fd2lost ksh-20120801/src/cmd/ksh93/sh/subshell.c +--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.fd2lost 2014-01-22 16:23:21.222658887 +0100 ++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-01-22 16:23:21.243658703 +0100 +@@ -122,7 +122,8 @@ void sh_subtmpfile(Shell_t *shp) + else if(errno!=EBADF) + errormsg(SH_DICT,ERROR_system(1),e_toomany); + /* popping a discipline forces a /tmp file create */ +- sfdisc(sfstdout,SF_POPDISC); ++ if(shp->comsub != 1) ++ sfdisc(sfstdout,SF_POPDISC); + if((fd=sffileno(sfstdout))<0) + { + /* unable to create the /tmp file so use a pipe */ +@@ -635,6 +636,13 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + } + else + { ++ if(comsub!=1 && shp->spid) ++ { ++ job_wait(shp->spid); ++ if(shp->pipepid==shp->spid) ++ shp->spid = 0; ++ shp->pipepid = 0; ++ } + /* move tmp file to iop and restore sfstdout */ + iop = sfswap(sfstdout,NIL(Sfio_t*)); + if(!iop) +diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.fd2lost ksh-20120801/src/cmd/ksh93/sh/xec.c +--- ksh-20120801/src/cmd/ksh93/sh/xec.c.fd2lost 2014-01-22 16:23:21.237658756 +0100 ++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-01-22 16:38:36.374666019 +0100 +@@ -1756,6 +1756,8 @@ int sh_exec(register const Shnode_t *t, + nlock--; + job_unlock(); + } ++ if(shp->subshell) ++ shp->spid = parent; + if(type&FPCL) + sh_close(shp->inpipe[0]); + if(type&(FCOOP|FAMP)) +@@ -1771,7 +1773,11 @@ int sh_exec(register const Shnode_t *t, + if(shp->pipepid) + shp->pipepid = parent; + else ++ { + job_wait(parent); ++ if(parent==shp->spid) ++ shp->spid = 0; ++ } + if(shp->topfd > topfd) + sh_iorestore(shp,topfd,0); + if(usepipe && tsetio && subdup && unpipe) diff --git a/ksh-20120801-filecomsubst.patch b/ksh-20120801-filecomsubst.patch new file mode 100644 index 0000000..676cc27 --- /dev/null +++ b/ksh-20120801-filecomsubst.patch @@ -0,0 +1,11 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.tryfix01 ksh-20120801/src/cmd/ksh93/sh/io.c +--- ksh-20120801/src/cmd/ksh93/sh/io.c.tryfix01 2014-02-26 16:15:52.355391420 +0100 ++++ ksh-20120801/src/cmd/ksh93/sh/io.c 2014-02-26 16:23:55.588148801 +0100 +@@ -1326,6 +1326,7 @@ int sh_redirect(Shell_t *shp,struct iono + if(flag==SH_SHOWME) + goto traceit; + fd=sh_chkopen(fname); ++ fd=sh_iomovefd(fd); + } + else if(sh_isoption(SH_RESTRICTED)) + errormsg(SH_DICT,ERROR_exit(1),e_restricted,fname); diff --git a/ksh-20120801-forkbomb.patch b/ksh-20120801-forkbomb.patch new file mode 100644 index 0000000..7a1a5c1 --- /dev/null +++ b/ksh-20120801-forkbomb.patch @@ -0,0 +1,12 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/fault.c.forkbomb ksh-20120801/src/cmd/ksh93/sh/fault.c +--- ksh-20120801/src/cmd/ksh93/sh/fault.c.forkbomb 2013-04-30 16:20:40.237490109 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/fault.c 2013-04-30 16:21:49.961068778 +0200 +@@ -519,7 +519,7 @@ void sh_exit(register int xno) + if(pp && pp->mode>1) + cursig = -1; + #ifdef SIGTSTP +- if(shp->trapnote&SH_SIGTSTP) ++ if((shp->trapnote&SH_SIGTSTP) && job.jobcontrol) + { + /* ^Z detected by the shell */ + shp->trapnote = 0; diff --git a/ksh-20120801-fununset.patch b/ksh-20120801-fununset.patch new file mode 100644 index 0000000..1f5cb17 --- /dev/null +++ b/ksh-20120801-fununset.patch @@ -0,0 +1,12 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.fununset ksh-20120801/src/cmd/ksh93/sh/xec.c +--- ksh-20120801/src/cmd/ksh93/sh/xec.c.fununset 2014-06-16 14:21:09.293513844 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-06-16 14:21:09.309513760 +0200 +@@ -3570,7 +3570,7 @@ static void sh_funct(Shell_t *shp,Namval + #endif + nv_putval(SH_PATHNAMENOD,shp->st.filename,NV_NOFREE); + shp->pipepid = pipepid; +- np->nvalue.rp->running -= 2; ++ if (np->nvalue.rp) np->nvalue.rp->running -= 2; + } + + /* diff --git a/ksh-20120801-heresub.patch b/ksh-20120801-heresub.patch new file mode 100644 index 0000000..880071c --- /dev/null +++ b/ksh-20120801-heresub.patch @@ -0,0 +1,32 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/lex.c.heresub ksh-20120801/src/cmd/ksh93/sh/lex.c +--- ksh-20120801/src/cmd/ksh93/sh/lex.c.heresub 2014-05-21 16:48:42.635700984 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/lex.c 2014-05-21 16:48:42.678700772 +0200 +@@ -1557,6 +1557,7 @@ static int comsub(register Lex_t *lp, in + { + register int n,c,count=1; + register int line=lp->sh->inlineno; ++ struct ionod *inheredoc = lp->heredoc; + char *first,*cp=fcseek(0),word[5]; + int off, messages=0, assignok=lp->assignok, csub; + struct lexstate save; +@@ -1683,7 +1684,7 @@ done: + lp->lexd.dolparen--; + lp->lex = save; + lp->assignok = (endchar(lp)==RBRACT?assignok:0); +- if(lp->heredoc) ++ if(lp->heredoc && !inheredoc) + errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax5,lp->sh->inlineno,lp->heredoc->ioname); + return(messages); + } +diff -up ksh-20120801/src/cmd/ksh93/sh/macro.c.heresub ksh-20120801/src/cmd/ksh93/sh/macro.c +--- ksh-20120801/src/cmd/ksh93/sh/macro.c.heresub 2014-05-21 16:48:42.650700910 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/macro.c 2014-05-21 16:48:42.678700772 +0200 +@@ -2085,7 +2085,7 @@ static void comsubst(Mac_t *mp,register + } + sfputc(stkp,c); + } +- sfputc(stkp,' '); ++ sfputc(stkp,'\n'); + c = stktell(stkp); + str=stkfreeze(stkp,1); + /* disable verbose and don't save in history file */ diff --git a/ksh-20120801-hokaido.patch b/ksh-20120801-hokaido.patch deleted file mode 100644 index 24c0ff5..0000000 --- a/ksh-20120801-hokaido.patch +++ /dev/null @@ -1,32 +0,0 @@ -diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.hokaido ksh-20120801/src/cmd/ksh93/sh/xec.c ---- ksh-20120801/src/cmd/ksh93/sh/xec.c.hokaido 2014-06-10 08:30:29.953485752 +0200 -+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-06-10 09:22:32.646799331 +0200 -@@ -1618,11 +1618,25 @@ int sh_exec(register const Shnode_t *t, - #endif /* SHOPT_COSHELL */ - if(shp->subshell) - { -- sh_subtmpfile(shp); -+ if(shp->comsub==1) -+ { -+ int t=shp->comsub; -+ if(t==1)shp->comsub=2; -+ sh_subtmpfile(shp); -+ shp->comsub=t; -+ } -+ else -+ sh_subtmpfile(shp); - if(shp->comsub==1 && !(shp->fdstatus[1]&IONOSEEK)) -- unpipe=iousepipe(shp); -+ unpipe = iousepipe(shp); - if((type&(FAMP|TFORK))==(FAMP|TFORK)) -- sh_subfork(); -+ { -+ if(shp->comsub && !(shp->fdstatus[1]&IONOSEEK)) -+ { -+ if (!unpipe) unpipe = iousepipe(shp); -+ sh_subfork(); -+ } -+ } - } - no_fork = !ntflag && !(type&(FAMP|FPOU)) && !shp->subshell && - !(shp->st.trapcom[SIGINT] && *shp->st.trapcom[SIGINT]) && diff --git a/ksh-20120801-kshmfix.patch b/ksh-20120801-kshmfix.patch index 72c792a..cc68406 100644 --- a/ksh-20120801-kshmfix.patch +++ b/ksh-20120801-kshmfix.patch @@ -51,3 +51,16 @@ diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.orig ksh-20120801/src/cmd/ksh93/sh/ tcsetpgrp(JOBTTY,shp->gd->pid); #endif /*SIGTSTP */ job.curpgid = savepgid; +diff -up ksh-20120801/src/cmd/ksh93/edit/edit.c.kshmfix ksh-20120801/src/cmd/ksh93/edit/edit.c +--- ksh-20120801/src/cmd/ksh93/edit/edit.c.kshmfix 2013-09-23 10:46:57.007256192 +0200 ++++ ksh-20120801/src/cmd/ksh93/edit/edit.c 2013-09-23 10:47:43.988937610 +0200 +@@ -1050,7 +1050,7 @@ int ed_getchar(register Edit_t *ep,int m + { + if(mode<=0 && -c == ep->e_intr) + { +- sh_fault(SIGINT); ++ killpg(getpgrp(),SIGINT); + siglongjmp(ep->e_env, UINTR); + } + if(mode<=0 && ep->sh->st.trap[SH_KEYTRAP]) + diff --git a/ksh-20120801-locking.patch b/ksh-20120801-locking.patch new file mode 100644 index 0000000..189d254 --- /dev/null +++ b/ksh-20120801-locking.patch @@ -0,0 +1,26 @@ +diff -up ksh-20120801/src/cmd/ksh93/include/jobs.h.locking ksh-20120801/src/cmd/ksh93/include/jobs.h +--- ksh-20120801/src/cmd/ksh93/include/jobs.h.locking 2014-06-27 15:51:07.144923719 +0200 ++++ ksh-20120801/src/cmd/ksh93/include/jobs.h 2014-06-27 15:52:56.463272276 +0200 +@@ -149,15 +149,18 @@ extern struct jobs job; + #define vmbusy() 0 + #endif + +-#define job_lock() (job.in_critical++) ++#define asoincint(p) __sync_fetch_and_add(p,1) ++#define asodecint(p) __sync_fetch_and_sub(p,1) ++ ++#define job_lock() asoincint(&job.in_critical) + #define job_unlock() \ + do { \ + int sig; \ +- if (!--job.in_critical && (sig = job.savesig)) \ ++ if (asodecint(&job.in_critical)==1 && (sig = job.savesig)) \ + { \ +- if (!job.in_critical++ && !vmbusy()) \ ++ if (!asoincint(&job.in_critical) && !vmbusy()) \ + job_reap(sig); \ +- job.in_critical--; \ ++ asodecint(&job.in_critical); \ + } \ + } while(0) + diff --git a/ksh-20120801-macro.patch b/ksh-20120801-macro.patch new file mode 100644 index 0000000..004a5eb --- /dev/null +++ b/ksh-20120801-macro.patch @@ -0,0 +1,178 @@ +diff -up ksh-20120801/src/cmd/ksh93/include/io.h.macro ksh-20120801/src/cmd/ksh93/include/io.h +--- ksh-20120801/src/cmd/ksh93/include/io.h.macro 2012-07-18 16:12:38.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/include/io.h 2013-07-04 16:14:05.809595966 +0200 +@@ -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 iounpipe(Shell_t*); + extern int sh_chkopen(const char*); + extern int sh_ioaccess(int,int); + extern int sh_devtofd(const char*); +diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.macro ksh-20120801/src/cmd/ksh93/sh/subshell.c +--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.macro 2013-07-04 16:14:05.783595751 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2013-07-04 16:15:46.673432991 +0200 +@@ -171,7 +171,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) +@@ -204,7 +204,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; + } + } +@@ -743,7 +743,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + fchdir(shp->pwdfd); + } + shp->subshare = sp->subshare; +- shp->comsub = sp->comsub; + shp->subdup = sp->subdup; + #if SHOPT_COSHELL + shp->coshell = sp->coshell; +@@ -773,7 +772,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) ++ iounpipe(shp); ++ } ++ shp->comsub = sp->comsub; + if(comsub && iop && sp->pipefd<0) + sfseek(iop,(off_t)0,SEEK_SET); + if(shp->trapnote) +diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.macro ksh-20120801/src/cmd/ksh93/sh/xec.c +--- ksh-20120801/src/cmd/ksh93/sh/xec.c.macro 2013-07-04 16:14:05.800595891 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2013-07-04 16:14:05.810595975 +0200 +@@ -102,11 +102,11 @@ struct funenv + * temp file. + */ + static int subpipe[3],subdup,tsetio,usepipe; +-static void iounpipe(Shell_t*); ++void iounpipe(Shell_t*); + +-static int iousepipe(Shell_t *shp) ++int iousepipe(Shell_t *shp) + { +- int i; ++ int fd=sffileno(sfstdout),i,err=errno; + if(usepipe) + { + usepipe++; +@@ -115,13 +115,18 @@ static int iousepipe(Shell_t *shp) + if(sh_rpipe(subpipe) < 0) + return(0); + usepipe++; +- fcntl(subpipe[0],F_SETFD,FD_CLOEXEC); +- subpipe[2] = sh_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 +140,23 @@ static int iousepipe(Shell_t *shp) + return(1); + } + +-static void iounpipe(Shell_t *shp) ++void 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 && !(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]) && +@@ -3495,8 +3514,7 @@ static void sh_funct(Shell_t *shp,Namval + struct funenv fun; + char *fname = nv_getval(SH_FUNNAMENOD); + struct Level *lp =(struct Level*)(SH_LEVELNOD->nvfun); +- int level, pipepid=shp->pipepid, comsub=shp->comsub; +- shp->comsub = 0; ++ int level, pipepid=shp->pipepid; + shp->pipepid = 0; + sh_stats(STAT_FUNCT); + if(!lp->hdr.disc) +@@ -3539,7 +3557,6 @@ static void sh_funct(Shell_t *shp,Namval + lp->maxlevel = level; + SH_LEVELNOD->nvalue.s = lp->maxlevel; + shp->last_root = nv_dict(DOTSHNOD); +- shp->comsub = comsub; + #if 0 + nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE); + #else diff --git a/ksh-20120801-manfix4.patch b/ksh-20120801-manfix4.patch new file mode 100644 index 0000000..6355445 --- /dev/null +++ b/ksh-20120801-manfix4.patch @@ -0,0 +1,12 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh.1.manfix4 ksh-20120801/src/cmd/ksh93/sh.1 +--- ksh-20120801/src/cmd/ksh93/sh.1.manfix4 2014-05-22 12:04:51.593750721 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh.1 2014-05-22 12:05:32.561556452 +0200 +@@ -4147,7 +4147,7 @@ command are ignored if the command is fo + .B & + and the + .B monitor +-option is not active. ++option is active. + Otherwise, signals have the values + inherited by the shell from its parent + (but see also diff --git a/ksh-20120801-memlik3.patch b/ksh-20120801-memlik3.patch new file mode 100644 index 0000000..9df57d2 --- /dev/null +++ b/ksh-20120801-memlik3.patch @@ -0,0 +1,76 @@ +diff -up ksh-20120801/src/cmd/ksh93/include/name.h.memlik3 ksh-20120801/src/cmd/ksh93/include/name.h +--- ksh-20120801/src/cmd/ksh93/include/name.h.memlik3 2012-05-10 18:33:41.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/include/name.h 2014-01-22 14:14:32.774483776 +0100 +@@ -215,7 +215,7 @@ extern Namval_t *nv_mount(Namval_t*, co + extern Namval_t *nv_arraychild(Namval_t*, Namval_t*, int); + extern int nv_compare(Dt_t*, Void_t*, Void_t*, Dtdisc_t*); + extern void nv_outnode(Namval_t*,Sfio_t*, int, int); +-extern int nv_subsaved(Namval_t*); ++extern int nv_subsaved(Namval_t*,int); + extern void nv_typename(Namval_t*, Sfio_t*); + extern void nv_newtype(Namval_t*); + extern int nv_istable(Namval_t*); +diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.memlik3 ksh-20120801/src/cmd/ksh93/sh/name.c +--- ksh-20120801/src/cmd/ksh93/sh/name.c.memlik3 2014-01-22 14:14:32.751483987 +0100 ++++ ksh-20120801/src/cmd/ksh93/sh/name.c 2014-01-22 14:14:32.775483767 +0100 +@@ -1297,7 +1297,7 @@ void nv_delete(Namval_t* np, Dt_t *root, + { + if(dtdelete(root,np)) + { +- if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np))) ++ if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np,flags&NV_TABLE))) + free((void*)np); + } + #if 0 +@@ -2461,14 +2461,14 @@ static void table_unset(Shell_t *shp, re + { + _nv_unset(nq,flags); + npnext = (Namval_t*)dtnext(root,nq); +- nv_delete(nq,root,0); ++ nv_delete(nq,root,NV_TABLE); + } + } + npnext = (Namval_t*)dtnext(root,np); + if(nv_arrayptr(np)) + nv_putsub(np,NIL(char*),ARRAY_SCAN); + _nv_unset(np,flags); +- nv_delete(np,root,0); ++ nv_delete(np,root,NV_TABLE); + } + } + +diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.memlik3 ksh-20120801/src/cmd/ksh93/sh/subshell.c +--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.memlik3 2014-01-22 14:14:32.768483831 +0100 ++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-01-22 14:20:50.810236676 +0100 +@@ -218,16 +218,28 @@ void sh_subfork(void) + } + } + +-int nv_subsaved(register Namval_t *np) ++int nv_subsaved(register Namval_t *np,int table) + { + register struct subshell *sp; +- register struct Link *lp; ++ register struct Link *lp, *lpprev; + for(sp = (struct subshell*)subshell_data; sp; sp=sp->prev) + { +- for(lp=sp->svar; lp; lp = lp->next) ++ lpprev = 0; ++ for(lp=sp->svar; lp; lpprev=lp, lp=lp->next) + { + if(lp->node==np) ++ { ++ if(table&NV_TABLE) ++ { ++ if(lpprev) ++ lpprev->next = lp->next; ++ else ++ sp->svar = lp->next; ++ free((void*)np); ++ free((void*)lp); ++ } + return(1); ++ } + } + } + return(0); diff --git a/ksh-20120801-mlikfiks.patch b/ksh-20120801-mlikfiks.patch new file mode 100644 index 0000000..fbf016a --- /dev/null +++ b/ksh-20120801-mlikfiks.patch @@ -0,0 +1,34 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/lex.c.mlikfiks ksh-20120801/src/cmd/ksh93/sh/lex.c +--- ksh-20120801/src/cmd/ksh93/sh/lex.c.mlikfiks 2013-07-22 12:45:30.923170264 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/lex.c 2013-07-22 12:46:25.235556905 +0200 +@@ -2465,7 +2465,7 @@ static int alias_exceptf(Sfio_t *iop,int + if(dp!=handle) + sfdisc(iop,dp); + } +- else if(type==SF_FINAL) ++ else if(type==SF_DPOP || type==SF_FINAL) + free((void*)ap); + goto done; + } +diff -up ksh-20120801/src/cmd/ksh93/sh/path.c.mlikfiks ksh-20120801/src/cmd/ksh93/sh/path.c +--- ksh-20120801/src/cmd/ksh93/sh/path.c.mlikfiks 2013-07-22 12:47:23.149990016 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/path.c 2013-07-22 12:48:33.363283877 +0200 +@@ -613,6 +613,7 @@ static void funload(Shell_t *shp,int fno + } + while((rp=dtnext(shp->fpathdict,rp)) && strcmp(pname,rp->fname)==0); + sh_close(fno); ++ free((void*)pname); + return; + } + sh_onstate(SH_NOLOG); +diff -up ksh-20120801/src/cmd/ksh93/sh/macro.c.aliasfix ksh-20120801/src/cmd/ksh93/sh/macro.c +--- ksh-20120801/src/cmd/ksh93/sh/macro.c.aliasfix 2013-07-29 15:03:45.841680475 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/macro.c 2013-07-29 15:04:23.871336821 +0200 +@@ -2085,6 +2085,7 @@ static void comsubst(Mac_t *mp,register + } + sfputc(stkp,c); + } ++ sfputc(stkp,' '); + c = stktell(stkp); + str=stkfreeze(stkp,1); + /* disable verbose and don't save in history file */ diff --git a/ksh-20120801-mtty.patch b/ksh-20120801-mtty.patch index 7f599e6..d992a88 100644 --- a/ksh-20120801-mtty.patch +++ b/ksh-20120801-mtty.patch @@ -1,12 +1,12 @@ diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.mtty ksh-20120801/src/cmd/ksh93/sh/xec.c ---- ksh-20120801/src/cmd/ksh93/sh/xec.c.mtty 2013-10-30 13:23:31.342298357 +0100 -+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2013-10-30 13:24:20.453885803 +0100 -@@ -3144,7 +3144,7 @@ pid_t _sh_fork(Shell_t *shp,register pid +--- ksh-20120801/src/cmd/ksh93/sh/xec.c.mtty 2014-01-22 16:52:06.441608750 +0100 ++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-01-22 16:52:06.485608361 +0100 +@@ -3163,7 +3169,7 @@ pid_t _sh_fork(Shell_t *shp,register pid * completed. Make parent the job group id. */ if(postid==0) - job.curpgid = parent; -+ job.curpgid = getpid(); ++ job.curpgid = job.jobcontrol?parent:getpid(); if(job.jobcontrol || (flags&FAMP)) { if(setpgid(parent,job.curpgid)<0 && errno==EPERM) diff --git a/ksh-20120801-nomulti.patch b/ksh-20120801-nomulti.patch new file mode 100644 index 0000000..5d7e7a4 --- /dev/null +++ b/ksh-20120801-nomulti.patch @@ -0,0 +1,11 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.nomulti ksh-20120801/src/cmd/ksh93/sh/init.c +--- ksh-20120801/src/cmd/ksh93/sh/init.c.nomulti 2013-10-08 20:46:46.202471042 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/init.c 2013-10-08 20:46:57.912331483 +0200 +@@ -1446,7 +1446,6 @@ Shell_t *sh_init(register int argc,regis + #endif /* SHOPT_TIMEOUT */ + /* initialize jobs table */ + job_clear(); +- sh_onoption(SH_MULTILINE); + if(argc>0) + { + /* check for restricted shell */ diff --git a/ksh-20120801-rmdirfix.patch b/ksh-20120801-rmdirfix.patch new file mode 100644 index 0000000..ae9dfd7 --- /dev/null +++ b/ksh-20120801-rmdirfix.patch @@ -0,0 +1,505 @@ +diff -up ksh20120801/src/cmd/ksh93/sh/subshell.c.orig ksh20120801/src/cmd/ksh93/sh/subshell.c +--- ksh20120801/src/cmd/ksh93/sh/subshell.c.orig 2012-07-17 23:54:21.000000000 +0200 ++++ ksh20120801/src/cmd/ksh93/sh/subshell.c 2012-10-24 15:03:44.436870792 +0200 +@@ -40,14 +40,6 @@ + # define PIPE_BUF 512 + #endif + +-#ifndef O_SEARCH +-# ifdef O_PATH +-# define O_SEARCH O_PATH +-# else +-# define O_SEARCH 0 +-# endif +-#endif +- + /* + * Note that the following structure must be the same + * size as the Dtlink_t structure +@@ -84,7 +76,7 @@ static struct subshell + char *pwd; /* present working directory */ + const char *shpwd; /* saved pointer to sh.pwd */ + void *jobs; /* save job info */ +- int pwdfd; /* file descritor for pwd */ ++ int shpwdfd;/* fd for present working directory */ + mode_t mask; /* saved umask */ + short tmpfd; /* saved tmp file descriptor */ + short pipefd; /* read fd if pipe is created */ +@@ -101,7 +93,6 @@ static struct subshell + int subdup; + char subshare; + char comsub; +- char pwdclose; + #if SHOPT_COSHELL + void *coshell; + #endif /* SHOPT_COSHELL */ +@@ -518,7 +509,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + shp->pathinit = 0; + } + sp->pathlist = path_dup((Pathcomp_t*)shp->pathlist); +- sp->pwdfd = -1; + if(!shp->pwd) + path_pwd(shp,0); + sp->bckpid = shp->bckpid; +@@ -531,39 +521,14 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + shp->subshare = comsub==2 || (comsub==1 && sh_isoption(SH_SUBSHARE)); + if(comsub) + shp->comsub = comsub; ++ sp->shpwdfd=-1; + if(!comsub || !shp->subshare) + { +- struct subshell *xp; + sp->shpwd = shp->pwd; +-#ifdef _lib_fchdir +- for(xp=sp->prev; xp; xp=xp->prev) +- { +- if(xp->pwdfd>0 && strcmp(xp->pwd,shp->pwd)==0) +- { +- sp->pwdfd = xp->pwdfd; +- break; +- } +- } +- if(sp->pwdfd<0) +- { +- int n = open(".",O_RDONLY); +- if(O_SEARCH && errno==EACCES) +- n = open(".",O_RDONLY); +- if(n>=0) +- { +- sp->pwdfd = n; +- if(n<10) +- { +- sp->pwdfd = sh_fcntl(n,F_DUPFD,10); +- close(n); +- } +- if(sp->pwdfd>0) +- { +- fcntl(sp->pwdfd,F_SETFD,FD_CLOEXEC); +- sp->pwdclose = 1; +- } +- } +- } ++ sp->shpwdfd=((shp->pwdfd >= 0))?sh_fcntl(shp->pwdfd, F_dupfd_cloexec, 10):-1; ++#ifdef O_SEARCH ++ if(sp->shpwdfd<0) ++ errormsg(SH_DICT,ERROR_system(1), "Can't obtain directory fd."); + #endif + sp->pwd = (shp->pwd?strdup(shp->pwd):0); + sp->mask = shp->mask; +@@ -741,14 +706,11 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + Namval_t *pwdnod = sh_scoped(shp,PWDNOD); + if(shp->pwd) + { +- if(sp->pwdfd >=0) +- { +- if(fchdir(sp->pwdfd)<0) +- chdir(sp->pwd); +- } +- else +- chdir(sp->pwd); + shp->pwd=sp->pwd; ++#ifndef O_SEARCH ++ if (sp->shpwdfd < 0) ++ chdir(shp->pwd); ++#endif + path_newdir(shp,shp->pathlist); + } + if(nv_isattr(pwdnod,NV_NOFREE)) +@@ -762,8 +724,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + } + else + free((void*)sp->pwd); +- if(sp->pwdclose) +- close(sp->pwdfd); + if(sp->mask!=shp->mask) + umask(shp->mask=sp->mask); + if(shp->coutpipe!=sp->coutpipe) +@@ -775,6 +735,13 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + shp->cpipe[1] = sp->cpipe; + shp->coutpipe = sp->coutpipe; + } ++ if(sp->shpwdfd >=0) ++ { ++ if(shp->pwdfd >=0) ++ sh_close(shp->pwdfd); ++ shp->pwdfd=sp->shpwdfd; ++ fchdir(shp->pwdfd); ++ } + shp->subshare = sp->subshare; + shp->comsub = sp->comsub; + shp->subdup = sp->subdup; +diff -up ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.orig ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c +--- ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.orig 2012-08-02 16:50:40.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c 2012-10-24 15:37:46.814469045 +0200 +@@ -38,6 +38,10 @@ + #include "builtins.h" + #include + ++#ifndef EINTR_REPEAT ++# define EINTR_REPEAT(expr) while((expr) && (errno == EINTR)) errno=0; ++#endif ++ + /* + * Invalidate path name bindings to relative paths + */ +@@ -49,6 +53,95 @@ static void rehash(register Namval_t *np + _nv_unset(np,0); + } + ++/* ++ * Obtain a file handle to the directory "path" relative to directory ++ * "dir", or open a NFSv4 xattr directory handle for file dir/path. ++ */ ++int sh_diropenat(Shell_t *shp, int dir, const char *path, bool xattr) ++{ ++ int fd,shfd; ++ int savederrno=errno; ++#ifndef AT_FDCWD ++ NOT_USED(dir); ++#endif ++#ifndef O_XATTR ++ NOT_USED(xattr); ++#endif ++ ++#ifdef O_XATTR ++ if(xattr) ++ { ++ int apfd; /* attribute parent fd */ ++ /* open parent node... */ ++ EINTR_REPEAT((apfd = openat(dir, path, O_RDONLY|O_NONBLOCK|O_cloexec)) < 0); ++ if(apfd < 0) ++ return -1; ++ ++ /* ... and then open a fd to the attribute directory */ ++ EINTR_REPEAT((fd = openat(apfd, e_dot, O_XATTR|O_cloexec)) < 0); ++ ++ savederrno = errno; ++ EINTR_REPEAT(close(apfd) < 0); ++ errno = savederrno; ++ } ++ else ++#endif ++ { ++#ifdef AT_FDCWD ++ /* ++ * Open directory. First we try without |O_SEARCH| and ++ * if this fails with EACCESS we try with |O_SEARCH| ++ * again. ++ * This is required ... ++ * - ... because some platforms may require that it can ++ * only be used for directories while some filesystems ++ * (e.g. Reiser4 or HSM systems) allow a |fchdir()| into ++ * files, too) ++ * - ... to preserve the semantics of "cd", e.g. ++ * otherwise "cd" would return [No access] instead of ++ * [Not a directory] for files on filesystems which do ++ * not allow a "cd" into files. ++ * - ... to allow that a ++ * $ redirect {n} 10 and *register* the fd number with the shell */ ++ shfd = sh_fcntl(fd, F_dupfd_cloexec, 10); ++ savederrno=errno; ++ sh_close(fd); ++ errno=savederrno; ++ return(shfd); ++} ++ + int b_cd(int argc, char *argv[],Shbltin_t *context) + { + register char *dir; +@@ -56,18 +149,20 @@ int b_cd(int argc, char *argv[],Shbltin_ + register const char *dp; + register Shell_t *shp = context->shp; + int saverrno=0; +- int rval,flag=0; ++ int rval; ++ bool flag=false,xattr=false; + char *oldpwd; ++ int newdirfd; + Namval_t *opwdnod, *pwdnod; + if(sh_isoption(SH_RESTRICTED)) + errormsg(SH_DICT,ERROR_exit(1),e_restricted+4); + while((rval = optget(argv,sh_optcd))) switch(rval) + { + case 'L': +- flag = 0; ++ flag = false; + break; + case 'P': +- flag = 1; ++ flag = true; + break; + case ':': + errormsg(SH_DICT,2, "%s", opt_info.arg); +@@ -179,14 +274,72 @@ int b_cd(int argc, char *argv[],Shbltin_ + continue; + #endif /* SHOPT_FS_3D */ + } ++ rval = newdirfd = sh_diropenat(shp, shp->pwdfd, ++ path_relative(shp,stakptr(PATH_OFFSET)), xattr); ++ if(newdirfd >=0) ++ { ++ /* chdir for directories on HSM/tapeworms may take minutes */ ++ if(fchdir(newdirfd) >= 0) ++ { ++ if(shp->pwdfd >= 0) ++ sh_close(shp->pwdfd); ++ shp->pwdfd=newdirfd; ++ goto success; ++ } ++ } ++#ifndef O_SEARCH ++ else ++ { + if((rval=chdir(path_relative(shp,stakptr(PATH_OFFSET)))) >= 0) +- goto success; +- if(errno!=ENOENT && saverrno==0) ++ { ++ if(shp->pwdfd >= 0) ++ { ++ sh_close(shp->pwdfd); ++#ifdef AT_FDCWD ++ shp->pwdfd = AT_FDCWD; ++#else ++ shp->pwdfd = -1; ++#endif ++ } ++ } ++ } ++#endif ++ if(saverrno==0) + saverrno=errno; ++ if(newdirfd >=0) ++ sh_close(newdirfd); + } + while(cdpath); + if(rval<0 && *dir=='/' && *(path_relative(shp,stakptr(PATH_OFFSET)))!='/') +- rval = chdir(dir); ++ { ++ rval = newdirfd = sh_diropenat(shp, ++ shp->pwdfd, ++ dir, xattr); ++ if(newdirfd >=0) ++ { ++ /* chdir for directories on HSM/tapeworms may take minutes */ ++ if(fchdir(newdirfd) >= 0) ++ { ++ if(shp->pwdfd >= 0) ++ sh_close(shp->pwdfd); ++ shp->pwdfd=newdirfd; ++ goto success; ++ } ++ } ++#ifndef O_SEARCH ++ else ++ { ++ if(chdir(dir) >=0) ++ { ++ if(shp->pwdfd >= 0) ++ { ++ sh_close(shp->pwdfd); ++ shp->pwdfd=-1; ++ } ++ } ++ } ++#endif ++ } + /* use absolute chdir() if relative chdir() fails */ + if(rval<0) + { +@@ -213,7 +366,7 @@ success: + if(*dir != '/') + return(0); + nv_putval(opwdnod,oldpwd,NV_RDONLY); +- flag = strlen(dir); ++ flag = (strlen(dir)>0)?true:false; + /* delete trailing '/' */ + while(--flag>0 && dir[flag]=='/') + dir[flag] = 0; +diff -up ksh-20120801/src/cmd/ksh93/include/shell.h.orig ksh-20120801/src/cmd/ksh93/include/shell.h +--- ksh-20120801/src/cmd/ksh93/include/shell.h.orig 2012-07-17 22:07:40.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/include/shell.h 2012-10-24 15:42:10.756987230 +0200 +@@ -145,6 +145,7 @@ struct Shell_s + unsigned char trapnote; /* set when trap/signal is pending */ + char shcomp; /* set when runing shcomp */ + short subshell; /* set for virtual subshell */ ++ int pwdfd; /* file descriptor for pwd */ + #ifdef _SH_PRIVATE + _SH_PRIVATE + #endif /* _SH_PRIVATE */ +diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.orig ksh-20120801/src/cmd/ksh93/sh/init.c +--- ksh-20120801/src/cmd/ksh93/sh/init.c.orig 2012-05-11 19:19:10.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/init.c 2012-10-24 15:31:59.659485151 +0200 +@@ -1365,6 +1365,18 @@ Shell_t *sh_init(register int argc,regis + } + } + sh_ioinit(shp); ++#ifdef AT_FDCWD ++ shp->pwdfd = sh_diropenat(shp, AT_FDCWD, e_dot, false); ++#else ++ /* Systems without AT_FDCWD/openat() do not use the |dir| argument */ ++ shp->pwdfd = sh_diropenat(shp, -1, e_dot, false); ++#endif ++#ifdef O_SEARCH ++ /* This should _never_ happen, guranteed by design and goat sacrifice */ ++ if(shp->pwdfd < 0) ++ errormsg(SH_DICT,ERROR_system(1), "Can't obtain directory fd."); ++#endif ++ + /* initialize signal handling */ + sh_siginit(shp); + stakinstall(NIL(Stak_t*),nospace); +diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.orig ksh-20120801/src/cmd/ksh93/sh/xec.c +--- ksh-20120801/src/cmd/ksh93/sh/xec.c.orig 2012-07-23 16:49:32.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2012-10-24 15:35:02.209539671 +0200 +@@ -1348,8 +1348,12 @@ int sh_exec(register const Shnode_t *t, + { + if(!shp->pwd) + path_pwd(shp,0); +- if(shp->pwd) +- stat(".",&statb); ++#ifndef O_SEARCH ++ else if (shp->pwdfd>=0) ++ fstat(shp->pwdfd,&statb); ++ else if (shp->pwd) ++ stat(e_dot,&statb); ++#endif + sfsync(NULL); + share = sfset(sfstdin,SF_SHARE,0); + sh_onstate(SH_STOPOK); +@@ -1428,14 +1432,32 @@ int sh_exec(register const Shnode_t *t, + sh_offstate(SH_NOFORK); + if(!(nv_isattr(np,BLT_ENV))) + { +- if(shp->pwd) ++#ifdef O_SEARCH ++ while((fchdir(shp->pwdfd) < 0) && errno==EINTR) ++ errno = 0; ++#else ++ if(shp->pwd || (shp->pwdfd >= 0)) + { + struct stat stata; + stat(".",&stata); + /* restore directory changed */ + if(statb.st_ino!=stata.st_ino || statb.st_dev!=stata.st_dev) +- chdir(shp->pwd); ++ { ++ /* chdir for directories on HSM/tapeworms may take minutes */ ++ int err=errno; ++ if(shp->pwdfd >= 0) ++ { ++ while((fchdir(shp->pwdfd) < 0) && errno==EINTR) ++ errno = err; ++ } ++ else ++ { ++ while((chdir(shp->pwd) < 0) && errno==EINTR) ++ errno = err; ++ } ++ } + } ++#endif /* O_SEARCH */ + sh_offstate(SH_STOPOK); + if(share&SF_SHARE) + sfset(sfstdin,SF_PUBLIC|SF_SHARE,1); +diff -up ksh-20120801/src/lib/libast/features/common.orig ksh-20120801/src/lib/libast/features/common +--- ksh-20120801/src/lib/libast/features/common.orig 2011-12-12 20:55:33.000000000 +0100 ++++ ksh-20120801/src/lib/libast/features/common 2012-10-24 15:54:35.433885131 +0200 +@@ -463,6 +463,66 @@ typ uintptr_t stdint.h inttypes.h no{ + typedef unsigned _ast_int4_t uintptr_t; + #endif + }end ++typ _Bool = uint8_t ++cat{ ++ #if defined(_STDC_C99) || __STDC_VERSION__ >= 199901L ++ #include ++ #else ++ #define bool _Bool ++ #define false 0 ++ #define true 1 ++ #endif ++}end ++tst key __thread -lpthread note{ __thread keyword exists and works with -lpthread }end execute{ ++ #include ++ ++ #define INITIAL 1 ++ #define LOOP 100 ++ ++ static __thread int specific = INITIAL; ++ static int global = 0; ++ ++ static void* worker(void* arg) ++ { ++ int k; ++ int v; ++ v = (int)(arg - 0); ++ for (k = 0; k < LOOP; ++k) ++ { ++ specific += v; ++ usleep(1); ++ } ++ if (specific != (INITIAL + LOOP * v)) ++ global = 1; ++ return 0; ++ } ++ int main() ++ { ++ pthread_t th[2]; ++ ++ if (pthread_create(&th[0], 0, worker, (void*)0 + 5) || ++ pthread_create(&th[1], 0, worker, (void*)0 + 7)) ++ { ++ NOTE("pthread_create failed"); ++ return 1; ++ } ++ pthread_join(th[0], 0); ++ pthread_join(th[1], 0); ++ if (global) ++ { ++ NOTE("__thread variable not thread specific"); ++ return 1; ++ } ++ if (specific != INITIAL) ++ { ++ NOTE("main __thread variable changed by another thread"); ++ return 1; ++ } ++ return 0; ++ } ++}end no{ ++ #define __thread /* __thread keyword does not exist or does not work with -lpthread */ ++}end + + tst - -DTRY=1 - -DTRY=1 -Dvoid=char - -DTRY=2 - -DTRY=3 - -DTRY=4 output{ + #if _STD_ && _hdr_stdarg diff --git a/ksh-20120801-roundit.patch b/ksh-20120801-roundit.patch new file mode 100644 index 0000000..015bc85 --- /dev/null +++ b/ksh-20120801-roundit.patch @@ -0,0 +1,12 @@ +diff -up ksh-20120801/src/lib/libast/sfio/sfcvt.c.rounditgood ksh-20120801/src/lib/libast/sfio/sfcvt.c +--- ksh-20120801/src/lib/libast/sfio/sfcvt.c.rounditgood 2014-02-27 16:45:54.630161032 +0100 ++++ ksh-20120801/src/lib/libast/sfio/sfcvt.c 2014-02-27 16:45:54.658161205 +0100 +@@ -491,7 +491,7 @@ int format; /* conversion format */ + *decpt += 1; + if(!(format&SFFMT_EFORMAT)) + { /* add one more 0 for %f precision */ +- ep[-1] = '0'; ++ if(ep-sp>1) ep[-1] = '0'; + ep += 1; + } + } diff --git a/ksh-20120801-sufix.patch b/ksh-20120801-sufix.patch new file mode 100644 index 0000000..b820e1c --- /dev/null +++ b/ksh-20120801-sufix.patch @@ -0,0 +1,11 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.sufix ksh-20120801/src/cmd/ksh93/sh/io.c +--- ksh-20120801/src/cmd/ksh93/sh/io.c.sufix 2014-04-08 14:30:14.412343555 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/io.c 2014-04-08 14:31:18.403876587 +0200 +@@ -2144,6 +2144,7 @@ static int io_prompt(Shell_t *shp,Sfio_t + } + #endif /* TIOCLBIC */ + cp = sh_mactry(shp,nv_getval(sh_scoped(shp,PS1NOD))); ++ shp->exitval = 0; + for(;c= *cp;cp++) + { + if(c==HIST_CHAR) diff --git a/ksh-20120801-tpstl.patch b/ksh-20120801-tpstl.patch new file mode 100644 index 0000000..41e17c8 --- /dev/null +++ b/ksh-20120801-tpstl.patch @@ -0,0 +1,12 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.tpstl ksh-20120801/src/cmd/ksh93/sh/init.c +--- ksh-20120801/src/cmd/ksh93/sh/init.c.tpstl 2014-04-03 11:21:25.395547276 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/init.c 2014-04-03 11:26:03.908867208 +0200 +@@ -332,7 +332,7 @@ static Namfun_t *clone_optindex(Namval_t + /* Trap for restricted variables FPATH, PATH, SHELL, ENV */ + static void put_restricted(register Namval_t* np,const char *val,int flags,Namfun_t *fp) + { +- Shell_t *shp = nv_shell(np); ++ Shell_t *shp = sh_getinterp(); + int path_scoped = 0, fpath_scoped=0; + Pathcomp_t *pp; + char *name = nv_name(np); diff --git a/ksh-20130628-longer.patch b/ksh-20130628-longer.patch index 887fafd..4761a34 100644 --- a/ksh-20130628-longer.patch +++ b/ksh-20130628-longer.patch @@ -1,6 +1,6 @@ diff -up ksh-20120801/src/cmd/ksh93/include/defs.h.longer ksh-20120801/src/cmd/ksh93/include/defs.h --- ksh-20120801/src/cmd/ksh93/include/defs.h.longer 2012-06-25 20:47:47.000000000 +0200 -+++ ksh-20120801/src/cmd/ksh93/include/defs.h 2014-01-17 13:10:49.624714556 +0100 ++++ ksh-20120801/src/cmd/ksh93/include/defs.h 2013-07-08 17:33:42.238534376 +0200 @@ -162,8 +162,8 @@ struct shared Namval_t *prev_table; /* previous table used in nv_open */ \ Sfio_t *outpool; /* ouput stream pool */ \ @@ -14,7 +14,7 @@ diff -up ksh-20120801/src/cmd/ksh93/include/defs.h.longer ksh-20120801/src/cmd/k short poolfiles; \ diff -up ksh-20120801/src/cmd/ksh93/include/jobs.h.longer ksh-20120801/src/cmd/ksh93/include/jobs.h --- ksh-20120801/src/cmd/ksh93/include/jobs.h.longer 2011-12-19 13:36:37.000000000 +0100 -+++ ksh-20120801/src/cmd/ksh93/include/jobs.h 2014-01-17 13:10:49.625714536 +0100 ++++ ksh-20120801/src/cmd/ksh93/include/jobs.h 2013-07-08 17:32:52.881124147 +0200 @@ -87,7 +87,7 @@ struct process unsigned short p_exit; /* exit value or signal number */ unsigned short p_exitmin; /* minimum exit value for xargs */ @@ -24,9 +24,10 @@ diff -up ksh-20120801/src/cmd/ksh93/include/jobs.h.longer ksh-20120801/src/cmd/k #ifdef JOBS off_t p_name; /* history file offset for command */ struct termios p_stty; /* terminal state for job */ +diff -up ksh-20120801/src/cmd/ksh93/sh/jobs.c.longer ksh-20120801/src/cmd/ksh93/sh/jobs.c diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.longer ksh-20120801/src/cmd/ksh93/sh/subshell.c ---- ksh-20120801/src/cmd/ksh93/sh/subshell.c.longer 2014-01-17 13:10:49.559715864 +0100 -+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-01-17 13:13:41.392290104 +0100 +--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.longer 2013-07-08 17:32:52.874124090 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2013-07-08 17:32:52.882124156 +0200 @@ -98,7 +98,7 @@ static struct subshell #endif /* SHOPT_COSHELL */ } *subshell_data; @@ -36,16 +37,17 @@ diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.longer ksh-20120801/src/cmd/ks /* -@@ -171,7 +171,7 @@ void sh_subfork(void) +@@ -171,7 +171,8 @@ void sh_subfork(void) { register struct subshell *sp = subshell_data; Shell_t *shp = sp->shp; -- int curenv = shp->curenv; -+ long curenv = shp->curenv; +- int curenv = shp->curenv, comsub=shp->comsub; ++ long curenv = shp->curenv; ++ int comsub=shp->comsub; pid_t pid; char *trap = shp->st.trapcom[0]; if(trap) -@@ -461,7 +461,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ +@@ -461,7 +462,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ struct subshell sub_data; register struct subshell *sp = &sub_data; int jmpval,nsig=0,duped=0; diff --git a/ksh-20140301-fikspand.patch b/ksh-20140301-fikspand.patch new file mode 100644 index 0000000..9899392 --- /dev/null +++ b/ksh-20140301-fikspand.patch @@ -0,0 +1,12 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/expand.c.fikspand ksh-20120801/src/cmd/ksh93/sh/expand.c +--- ksh-20120801/src/cmd/ksh93/sh/expand.c.fikspand 2010-11-24 05:46:30.000000000 +0100 ++++ ksh-20120801/src/cmd/ksh93/sh/expand.c 2014-05-22 12:55:46.252717371 +0200 +@@ -278,6 +278,8 @@ int path_generate(Shell_t *shp,struct ar + char comma, range=0; + int first, last, incr, count = 0; + char tmp[32], end[1]; ++ if(!sh_isoption(SH_BRACEEXPAND)) ++ return path_expand(shp,todo->argval,arghead); + todo->argchn.ap = 0; + again: + apin = ap = todo; diff --git a/ksh-20140415-hokaido.patch b/ksh-20140415-hokaido.patch new file mode 100644 index 0000000..5aedf10 --- /dev/null +++ b/ksh-20140415-hokaido.patch @@ -0,0 +1,26 @@ +diff -up ksh-20140415/src/cmd/ksh93/sh/subshell.c.hokaido ksh-20140415/src/cmd/ksh93/sh/subshell.c +diff -up ksh-20140415/src/cmd/ksh93/sh/xec.c.hokaido ksh-20140415/src/cmd/ksh93/sh/xec.c +--- ksh-20140415/src/cmd/ksh93/sh/xec.c.hokaido 2014-03-17 22:13:55.000000000 +0100 ++++ ksh-20140415/src/cmd/ksh93/sh/xec.c 2014-05-20 18:23:49.712532290 +0200 +@@ -1630,12 +1630,20 @@ tryagain: + #endif /* SHOPT_COSHELL */ + if(shp->subshell) + { ++ int comsubsave = shp->comsub; ++ if(comsubsave==1) ++ shp->comsub = 2; + sh_subtmpfile(shp); ++ shp->comsub = comsubsave; ++ if(shp->comsub==1 && !(shp->fdstatus[1]&IONOSEEK)) ++ unpipe = iousepipe(shp); ++ + if((type&(FAMP|TFORK))==(FAMP|TFORK)) + { + if(shp->comsub && !(shp->fdstatus[1]&IONOSEEK)) + { +- unpipe = iousepipe(shp); ++ if (!unpipe) ++ unpipe = iousepipe(shp); + sh_subfork(); + } + } diff --git a/ksh.spec b/ksh.spec index 78fa80d..bea0fea 100644 --- a/ksh.spec +++ b/ksh.spec @@ -1,39 +1,123 @@ -%global releasedate 2012-08-01 +%global releasedate 20120801 +%global release_date %{lua:reldate=rpm.expand("%{releasedate}");print(("%s-%s-%s"):format(reldate:sub(0,4),reldate:sub(5,6),reldate:sub(7)))} Name: ksh Summary: The Original ATT Korn Shell URL: http://www.kornshell.com/ Group: System Environment/Shells -License: EPL -Version: 20120801 -Release: 18%{?dist} -Source0: http://www.research.att.com/~gsf/download/tgz/ast-ksh.%{releasedate}.tgz -Source1: http://www.research.att.com/~gsf/download/tgz/INIT.%{releasedate}.tgz +#zlib is used for INIT.2010-02-02.tgz/src/cmd/INIT/ratz.c - used only for build tool +#CPL everywhere else (for KSH itself) +License: CPL +Version: %{releasedate} +Release: 19%{?dist} +Source0: http://www.research.att.com/~gsf/download/tgz/ast-ksh.%{release_date}.tgz +Source1: http://www.research.att.com/~gsf/download/tgz/INIT.%{release_date}.tgz Source2: kshcomp.conf Source3: kshrc.rhs Source4: dotkshrc -#expected results of test suite + +# expected results of test suite Source5: expectedresults.log -#don't use not wanted/needed builtins - Fedora/RHEL specific +# don't use not wanted/needed builtins - Fedora/RHEL specific Patch1: ksh-20070328-builtins.patch -#fix regression test suite to be usable during packagebuild - Fedora/RHEL specific -Patch2: ksh-20100826-fixregr.patch -Patch3: rmdirfix.patch -Patch4: ksh-20120801-cdfix.patch -Patch5: ksh-20120801-tabfix.patch -Patch6: ksh-20120801-cdfix2.patch -Patch7: ksh-20130214-fixkill.patch -Patch8: ksh-20120801-kshmfix.patch -Patch9: ksh-20120801-memlik.patch -Patch10: ksh-20120801-mtty.patch -Patch11: ksh-20120801-argvfix.patch -Patch12: ksh-20130628-longer.patch +# fedora/rhel specific, rhbz#619692 +Patch6: ksh-20080202-manfix.patch + +# rhbz#702008 +Patch17: ksh-20100202-pathvar.patch + +# rhbz#924440 +Patch18: ksh-20100621-fdstatus.patch + +# fixes for regressions found in ksh-20120801 rebase +Patch19: ksh-20120801-rmdirfix.patch +Patch20: ksh-20120801-cdfix.patch +Patch21: ksh-20120801-cdfix2.patch +Patch22: ksh-20120801-tabfix.patch +Patch23: ksh-20130214-fixkill.patch + +# for ksh <= 2013-05-31, rhbz#960034 +Patch24: ksh-20120801-kshmfix.patch + +# for ksh <= 2016-06-28, rhbz#921455 +Patch25: ksh-20120801-memlik.patch + +# for ksh <= 2013-03-20, rhbz#922851 +Patch26: ksh-20120801-forkbomb.patch + +# for ksh <= 2013-04-19, rhbz#913110 +Patch27: ksh-20120801-macro.patch + +# not completely upstream yet, rhbz#858263 +Patch29: ksh-20130628-longer.patch + +# fix regression test suite to be usable during packagebuild - Fedora/RHEL specific +Patch99: ksh-20100826-fixregr.patch + +# for ksh <= 2013-07-19, rhbz#982142 +Patch30: ksh-20120801-mlikfiks.patch + +# not yet upstream, related to 2012-08-01 rebase +Patch31: ksh-20120801-covsfix.patch + +# rhbz#1007816 +Patch32: ksh-20100621-manfix3.patch + +# rhbz#1016611 +Patch33: ksh-20120801-nomulti.patch + +# for ksh <= 2014-01-14, rhbz# +Patch34: ksh-20120801-mtty.patch + +# from upstream, rbzh#1048272 +Patch35: ksh-20120801-fd2lost.patch + +# sent upstream 2014-01, rhbz#1047507 +Patch36: ksh-20120801-argvfix.patch + +# for ksh <= 2014-01-14, rhbz#1048995 +Patch37: ksh-20120801-memlik3.patch # for ksh <= 2013-04-09, rhbz#960371 -Patch13: ksh-20120801-lexfix.patch -Patch14: ksh-20120801-hokaido.patch +Patch38: ksh-20120801-lexfix.patch + +# not yet upstream, for ksh <= 2014-02-26, rhbz#1070328 +Patch39: ksh-20120801-filecomsubst.patch + +# for ksh <= 2014-06-25, rhbz#825520,rhbz#1084406 +Patch40: ksh-20120801-crash.patch + +# for ksh < 2013-03-19, rhbz#1085385 +Patch41: ksh-20120801-sufix.patch + +# sent upstream, rhbz#1099935 +Patch42: ksh-20140301-fikspand.patch + +# for ksh < 2014-04-15, rhbz#1070871 +Patch43: ksh-20120801-roundit.patch + +# for ksh < 2014-04-15, rhbz#1111120 +Patch44: ksh-20120801-heresub.patch + +# not included upstream yet, rhbz#1077090 +Patch45: ksh-20140415-hokaido.patch + +# for ksh < 2012-10-04, rhbz#1121960 +Patch46: ksh-20120801-tpstl.patch + +# sent upstream, rhbz#1100215 +Patch47: ksh-20120801-manfix4.patch + +# not upstream yet, rhbz#1100215 +Patch48: ksh-20120801-fununset.patch + +# for ksh < 2014-06-25, rhbz#1109893 +Patch49: ksh-20120801-cdfix3.patch + +# sent upstream, rhbz#1116506 +Patch50: ksh-20120801-locking.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Conflicts: pdksh @@ -54,19 +138,41 @@ with "sh" (the Bourne Shell). %setup -q -c %setup -q -T -D -a 1 %patch1 -p1 -b .builtins -%patch2 -p1 -b .fixregr -%patch3 -p1 -b .rmdirfix -%patch4 -p1 -b .cdfix -%patch5 -p1 -b .tabfix -%patch6 -p1 -b .cdfix2 -%patch7 -p1 -b .fixkill -%patch8 -p1 -b .kshmfix -%patch9 -p1 -b .memlik -%patch10 -p1 -b .mtty -%patch11 -p1 -b .argvfix -%patch12 -p1 -b .longer -%patch13 -p1 -b .lexfix -%patch14 -p1 -b .hokaido +%patch6 -p1 -b .manfix +%patch17 -p1 -b .pathvar +%patch99 -p1 -b .fixregr +%patch18 -p1 -b .fdstatus +%patch19 -p1 -b .rmdirfix +%patch20 -p1 -b .cdfix +%patch21 -p1 -b .cdfix2 +%patch22 -p1 -b .tabfix +%patch23 -p1 -b .fixkill +%patch24 -p1 -b .kshmfix +%patch25 -p1 -b .memlik +%patch26 -p1 -b .forkbomb +%patch27 -p1 -b .macro +%patch29 -p1 -b .longer +%patch30 -p1 -b .mlikfiks +%patch31 -p1 -b .covsfix +%patch32 -p1 -b .manfix3 +%patch33 -p1 -b .nomulti +%patch34 -p1 -b .mtty +%patch35 -p1 -b .fd2lost +%patch36 -p1 -b .argvfix +%patch37 -p1 -b .memlik3 +%patch38 -p1 -b .lexfix +%patch39 -p1 -b .filecomsubst +%patch40 -p1 -b .crash +%patch41 -p1 -b .sufix +%patch42 -p1 -b .fikspand +%patch43 -p1 -b .roundit +%patch44 -p1 -b .heresub +%patch45 -p1 -b .hokaido +%patch46 -p1 -b .tpstl +%patch47 -p1 -b .manfix4 +%patch48 -p1 -b .fununset +%patch49 -p1 -b .cdfix3 +%patch50 -p1 -b .locking #/dev/fd test does not work because of mock sed -i 's|ls /dev/fd|ls /proc/self/fd|' src/cmd/ksh93/features/options @@ -75,12 +181,17 @@ sed -i 's|ls /dev/fd|ls /proc/self/fd|' src/cmd/ksh93/features/options sed -i '/-c sh\/main.c/s|${mam_cc_FLAGS} |${mam_cc_FLAGS} ${CCFLAGS} |p' src/cmd/ksh93/Mamfile %build +XTRAFLAGS="" +for f in -Wno-unknown-pragmas -Wno-missing-braces -Wno-unused-result -Wno-return-type -Wno-int-to-pointer-cast -Wno-parentheses -Wno-unused -Wno-unused-but-set-variable -Wno-cpp +do + gcc $f -E - /dev/null 2>&1 && XTRAFLAGS="$XTRAFLAGS $f" +done ./bin/package ./bin/package make mamake ||: ./bin/package make mamake ||: -export CCFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing -Wno-unknown-pragmas -Wno-parentheses -Wno-unused -Wno-unused-but-set-variable -Wno-cpp" +export CCFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing $XTRAFLAGS" export CC=gcc -./bin/package "make" +./bin/package make -S #cp lib/package/LICENSES/epl LICENSE @@ -112,6 +223,7 @@ then exit 0 fi $SHELL ./shtests 2>&1 | tee testresults.log +ls core.* 2>/dev/null ||: exit 0 sed -e '/begins at/d' -e '/ 0 error/d' -e 's/at [^\[]*\[/\[/' testresults.log -e '/tests skipped/d' >filteredresults.log if ! cmp filteredresults.log %{SOURCE5} >/dev/null || ls core.* @@ -134,7 +246,7 @@ fi %postun if [ ! -f /bin/ksh ]; then - sed -i '/^\/bin\/ksh$/ d' /etc/shells + sed -i '/^\/bin\/ksh$/ d' /etc/shells fi %verifyscript @@ -161,6 +273,22 @@ fi rm -rf $RPM_BUILD_ROOT %changelog +* Tue Jul 22 2014 Michal Hlavinka - 20120801-19 +- fix segfault in job list code +- do not resend signal on termination (#1092132) +- fix brace expansion on/off +- fix incorrect rounding of numsers 0.5 < |x| <1.0 in printf (#1080940) +- fix parser errors related to the end of the here-document marker +- ksh hangs when command substitution fills out the pipe buffer +- using typeset -l with a restricted variabled caused segmentation fault +- monitor mode was documented incorrectly +- do not crash when unsetting running function from another one (#1105139) +- should report an error when trying to cd into directory without execution bit +- job locking mechanism did not survive compiler optimization +- reading a file via command substitution did not work when any of stdin, + stdout or stderr were closed (#1070308) +- fix lexical parser crash + * Tue Jun 10 2014 Michal Hlavinka - 20120801-18 - fix FTBFS(#1107070) diff --git a/rmdirfix.patch b/rmdirfix.patch deleted file mode 100644 index 132de7d..0000000 --- a/rmdirfix.patch +++ /dev/null @@ -1,505 +0,0 @@ -diff -up ksh20120801/src/cmd/ksh93/sh/subshell.c.orig ksh20120801/src/cmd/ksh93/sh/subshell.c ---- ksh20120801/src/cmd/ksh93/sh/subshell.c.orig 2012-07-17 23:54:21.000000000 +0200 -+++ ksh20120801/src/cmd/ksh93/sh/subshell.c 2012-10-24 15:03:44.436870792 +0200 -@@ -40,14 +40,6 @@ - # define PIPE_BUF 512 - #endif - --#ifndef O_SEARCH --# ifdef O_PATH --# define O_SEARCH O_PATH --# else --# define O_SEARCH 0 --# endif --#endif -- - /* - * Note that the following structure must be the same - * size as the Dtlink_t structure -@@ -84,7 +76,7 @@ static struct subshell - char *pwd; /* present working directory */ - const char *shpwd; /* saved pointer to sh.pwd */ - void *jobs; /* save job info */ -- int pwdfd; /* file descritor for pwd */ -+ int shpwdfd;/* fd for present working directory */ - mode_t mask; /* saved umask */ - short tmpfd; /* saved tmp file descriptor */ - short pipefd; /* read fd if pipe is created */ -@@ -101,7 +93,6 @@ static struct subshell - int subdup; - char subshare; - char comsub; -- char pwdclose; - #if SHOPT_COSHELL - void *coshell; - #endif /* SHOPT_COSHELL */ -@@ -518,7 +509,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ - shp->pathinit = 0; - } - sp->pathlist = path_dup((Pathcomp_t*)shp->pathlist); -- sp->pwdfd = -1; - if(!shp->pwd) - path_pwd(shp,0); - sp->bckpid = shp->bckpid; -@@ -531,39 +521,14 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ - shp->subshare = comsub==2 || (comsub==1 && sh_isoption(SH_SUBSHARE)); - if(comsub) - shp->comsub = comsub; -+ sp->shpwdfd=-1; - if(!comsub || !shp->subshare) - { -- struct subshell *xp; - sp->shpwd = shp->pwd; --#ifdef _lib_fchdir -- for(xp=sp->prev; xp; xp=xp->prev) -- { -- if(xp->pwdfd>0 && strcmp(xp->pwd,shp->pwd)==0) -- { -- sp->pwdfd = xp->pwdfd; -- break; -- } -- } -- if(sp->pwdfd<0) -- { -- int n = open(".",O_RDONLY); -- if(O_SEARCH && errno==EACCES) -- n = open(".",O_RDONLY); -- if(n>=0) -- { -- sp->pwdfd = n; -- if(n<10) -- { -- sp->pwdfd = fcntl(n,F_DUPFD,10); -- close(n); -- } -- if(sp->pwdfd>0) -- { -- fcntl(sp->pwdfd,F_SETFD,FD_CLOEXEC); -- sp->pwdclose = 1; -- } -- } -- } -+ sp->shpwdfd=((shp->pwdfd >= 0))?sh_fcntl(shp->pwdfd, F_dupfd_cloexec, 10):-1; -+#ifdef O_SEARCH -+ if(sp->shpwdfd<0) -+ errormsg(SH_DICT,ERROR_system(1), "Can't obtain directory fd."); - #endif - sp->pwd = (shp->pwd?strdup(shp->pwd):0); - sp->mask = shp->mask; -@@ -741,14 +706,11 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ - Namval_t *pwdnod = sh_scoped(shp,PWDNOD); - if(shp->pwd) - { -- if(sp->pwdfd >=0) -- { -- if(fchdir(sp->pwdfd)<0) -- chdir(sp->pwd); -- } -- else -- chdir(sp->pwd); - shp->pwd=sp->pwd; -+#ifndef O_SEARCH -+ if (sp->shpwdfd < 0) -+ chdir(shp->pwd); -+#endif - path_newdir(shp,shp->pathlist); - } - if(nv_isattr(pwdnod,NV_NOFREE)) -@@ -762,8 +724,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ - } - else - free((void*)sp->pwd); -- if(sp->pwdclose) -- close(sp->pwdfd); - if(sp->mask!=shp->mask) - umask(shp->mask=sp->mask); - if(shp->coutpipe!=sp->coutpipe) -@@ -775,6 +735,13 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ - shp->cpipe[1] = sp->cpipe; - shp->coutpipe = sp->coutpipe; - } -+ if(sp->shpwdfd >=0) -+ { -+ if(shp->pwdfd >=0) -+ sh_close(shp->pwdfd); -+ shp->pwdfd=sp->shpwdfd; -+ fchdir(shp->pwdfd); -+ } - shp->subshare = sp->subshare; - shp->comsub = sp->comsub; - shp->subdup = sp->subdup; -diff -up ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.orig ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c ---- ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.orig 2012-08-02 16:50:40.000000000 +0200 -+++ ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c 2012-10-24 15:37:46.814469045 +0200 -@@ -38,6 +38,10 @@ - #include "builtins.h" - #include - -+#ifndef EINTR_REPEAT -+# define EINTR_REPEAT(expr) while((expr) && (errno == EINTR)) errno=0; -+#endif -+ - /* - * Invalidate path name bindings to relative paths - */ -@@ -49,6 +53,95 @@ static void rehash(register Namval_t *np - _nv_unset(np,0); - } - -+/* -+ * Obtain a file handle to the directory "path" relative to directory -+ * "dir", or open a NFSv4 xattr directory handle for file dir/path. -+ */ -+int sh_diropenat(Shell_t *shp, int dir, const char *path, bool xattr) -+{ -+ int fd,shfd; -+ int savederrno=errno; -+#ifndef AT_FDCWD -+ NOT_USED(dir); -+#endif -+#ifndef O_XATTR -+ NOT_USED(xattr); -+#endif -+ -+#ifdef O_XATTR -+ if(xattr) -+ { -+ int apfd; /* attribute parent fd */ -+ /* open parent node... */ -+ EINTR_REPEAT((apfd = openat(dir, path, O_RDONLY|O_NONBLOCK|O_cloexec)) < 0); -+ if(apfd < 0) -+ return -1; -+ -+ /* ... and then open a fd to the attribute directory */ -+ EINTR_REPEAT((fd = openat(apfd, e_dot, O_XATTR|O_cloexec)) < 0); -+ -+ savederrno = errno; -+ EINTR_REPEAT(close(apfd) < 0); -+ errno = savederrno; -+ } -+ else -+#endif -+ { -+#ifdef AT_FDCWD -+ /* -+ * Open directory. First we try without |O_SEARCH| and -+ * if this fails with EACCESS we try with |O_SEARCH| -+ * again. -+ * This is required ... -+ * - ... because some platforms may require that it can -+ * only be used for directories while some filesystems -+ * (e.g. Reiser4 or HSM systems) allow a |fchdir()| into -+ * files, too) -+ * - ... to preserve the semantics of "cd", e.g. -+ * otherwise "cd" would return [No access] instead of -+ * [Not a directory] for files on filesystems which do -+ * not allow a "cd" into files. -+ * - ... to allow that a -+ * $ redirect {n} 10 and *register* the fd number with the shell */ -+ shfd = sh_fcntl(fd, F_dupfd_cloexec, 10); -+ savederrno=errno; -+ sh_close(fd); -+ errno=savederrno; -+ return(shfd); -+} -+ - int b_cd(int argc, char *argv[],Shbltin_t *context) - { - register char *dir; -@@ -56,18 +149,20 @@ int b_cd(int argc, char *argv[],Shbltin_ - register const char *dp; - register Shell_t *shp = context->shp; - int saverrno=0; -- int rval,flag=0; -+ int rval; -+ bool flag=false,xattr=false; - char *oldpwd; -+ int newdirfd; - Namval_t *opwdnod, *pwdnod; - if(sh_isoption(SH_RESTRICTED)) - errormsg(SH_DICT,ERROR_exit(1),e_restricted+4); - while((rval = optget(argv,sh_optcd))) switch(rval) - { - case 'L': -- flag = 0; -+ flag = false; - break; - case 'P': -- flag = 1; -+ flag = true; - break; - case ':': - errormsg(SH_DICT,2, "%s", opt_info.arg); -@@ -179,14 +274,72 @@ int b_cd(int argc, char *argv[],Shbltin_ - continue; - #endif /* SHOPT_FS_3D */ - } -+ rval = newdirfd = sh_diropenat(shp, shp->pwdfd, -+ path_relative(shp,stakptr(PATH_OFFSET)), xattr); -+ if(newdirfd >=0) -+ { -+ /* chdir for directories on HSM/tapeworms may take minutes */ -+ if(fchdir(newdirfd) >= 0) -+ { -+ if(shp->pwdfd >= 0) -+ sh_close(shp->pwdfd); -+ shp->pwdfd=newdirfd; -+ goto success; -+ } -+ } -+#ifndef O_SEARCH -+ else -+ { - if((rval=chdir(path_relative(shp,stakptr(PATH_OFFSET)))) >= 0) -- goto success; -- if(errno!=ENOENT && saverrno==0) -+ { -+ if(shp->pwdfd >= 0) -+ { -+ sh_close(shp->pwdfd); -+#ifdef AT_FDCWD -+ shp->pwdfd = AT_FDCWD; -+#else -+ shp->pwdfd = -1; -+#endif -+ } -+ } -+ } -+#endif -+ if(saverrno==0) - saverrno=errno; -+ if(newdirfd >=0) -+ sh_close(newdirfd); - } - while(cdpath); - if(rval<0 && *dir=='/' && *(path_relative(shp,stakptr(PATH_OFFSET)))!='/') -- rval = chdir(dir); -+ { -+ rval = newdirfd = sh_diropenat(shp, -+ shp->pwdfd, -+ dir, xattr); -+ if(newdirfd >=0) -+ { -+ /* chdir for directories on HSM/tapeworms may take minutes */ -+ if(fchdir(newdirfd) >= 0) -+ { -+ if(shp->pwdfd >= 0) -+ sh_close(shp->pwdfd); -+ shp->pwdfd=newdirfd; -+ goto success; -+ } -+ } -+#ifndef O_SEARCH -+ else -+ { -+ if(chdir(dir) >=0) -+ { -+ if(shp->pwdfd >= 0) -+ { -+ sh_close(shp->pwdfd); -+ shp->pwdfd=-1; -+ } -+ } -+ } -+#endif -+ } - /* use absolute chdir() if relative chdir() fails */ - if(rval<0) - { -@@ -213,7 +366,7 @@ success: - if(*dir != '/') - return(0); - nv_putval(opwdnod,oldpwd,NV_RDONLY); -- flag = strlen(dir); -+ flag = (strlen(dir)>0)?true:false; - /* delete trailing '/' */ - while(--flag>0 && dir[flag]=='/') - dir[flag] = 0; -diff -up ksh-20120801/src/cmd/ksh93/include/shell.h.orig ksh-20120801/src/cmd/ksh93/include/shell.h ---- ksh-20120801/src/cmd/ksh93/include/shell.h.orig 2012-07-17 22:07:40.000000000 +0200 -+++ ksh-20120801/src/cmd/ksh93/include/shell.h 2012-10-24 15:42:10.756987230 +0200 -@@ -145,6 +145,7 @@ struct Shell_s - unsigned char trapnote; /* set when trap/signal is pending */ - char shcomp; /* set when runing shcomp */ - short subshell; /* set for virtual subshell */ -+ int pwdfd; /* file descriptor for pwd */ - #ifdef _SH_PRIVATE - _SH_PRIVATE - #endif /* _SH_PRIVATE */ -diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.orig ksh-20120801/src/cmd/ksh93/sh/init.c ---- ksh-20120801/src/cmd/ksh93/sh/init.c.orig 2012-05-11 19:19:10.000000000 +0200 -+++ ksh-20120801/src/cmd/ksh93/sh/init.c 2012-10-24 15:31:59.659485151 +0200 -@@ -1365,6 +1365,18 @@ Shell_t *sh_init(register int argc,regis - } - } - sh_ioinit(shp); -+#ifdef AT_FDCWD -+ shp->pwdfd = sh_diropenat(shp, AT_FDCWD, e_dot, false); -+#else -+ /* Systems without AT_FDCWD/openat() do not use the |dir| argument */ -+ shp->pwdfd = sh_diropenat(shp, -1, e_dot, false); -+#endif -+#ifdef O_SEARCH -+ /* This should _never_ happen, guranteed by design and goat sacrifice */ -+ if(shp->pwdfd < 0) -+ errormsg(SH_DICT,ERROR_system(1), "Can't obtain directory fd."); -+#endif -+ - /* initialize signal handling */ - sh_siginit(shp); - stakinstall(NIL(Stak_t*),nospace); -diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.orig ksh-20120801/src/cmd/ksh93/sh/xec.c ---- ksh-20120801/src/cmd/ksh93/sh/xec.c.orig 2012-07-23 16:49:32.000000000 +0200 -+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2012-10-24 15:35:02.209539671 +0200 -@@ -1348,8 +1348,12 @@ int sh_exec(register const Shnode_t *t, - { - if(!shp->pwd) - path_pwd(shp,0); -- if(shp->pwd) -- stat(".",&statb); -+#ifndef O_SEARCH -+ else if (shp->pwdfd>=0) -+ fstat(shp->pwdfd,&statb); -+ else if (shp->pwd) -+ stat(e_dot,&statb); -+#endif - sfsync(NULL); - share = sfset(sfstdin,SF_SHARE,0); - sh_onstate(SH_STOPOK); -@@ -1428,14 +1432,32 @@ int sh_exec(register const Shnode_t *t, - sh_offstate(SH_NOFORK); - if(!(nv_isattr(np,BLT_ENV))) - { -- if(shp->pwd) -+#ifdef O_SEARCH -+ while((fchdir(shp->pwdfd) < 0) && errno==EINTR) -+ errno = 0; -+#else -+ if(shp->pwd || (shp->pwdfd >= 0)) - { - struct stat stata; - stat(".",&stata); - /* restore directory changed */ - if(statb.st_ino!=stata.st_ino || statb.st_dev!=stata.st_dev) -- chdir(shp->pwd); -+ { -+ /* chdir for directories on HSM/tapeworms may take minutes */ -+ int err=errno; -+ if(shp->pwdfd >= 0) -+ { -+ while((fchdir(shp->pwdfd) < 0) && errno==EINTR) -+ errno = err; -+ } -+ else -+ { -+ while((chdir(shp->pwd) < 0) && errno==EINTR) -+ errno = err; -+ } -+ } - } -+#endif /* O_SEARCH */ - sh_offstate(SH_STOPOK); - if(share&SF_SHARE) - sfset(sfstdin,SF_PUBLIC|SF_SHARE,1); -diff -up ksh-20120801/src/lib/libast/features/common.orig ksh-20120801/src/lib/libast/features/common ---- ksh-20120801/src/lib/libast/features/common.orig 2011-12-12 20:55:33.000000000 +0100 -+++ ksh-20120801/src/lib/libast/features/common 2012-10-24 15:54:35.433885131 +0200 -@@ -463,6 +463,66 @@ typ uintptr_t stdint.h inttypes.h no{ - typedef unsigned _ast_int4_t uintptr_t; - #endif - }end -+typ _Bool = uint8_t -+cat{ -+ #if defined(_STDC_C99) || __STDC_VERSION__ >= 199901L -+ #include -+ #else -+ #define bool _Bool -+ #define false 0 -+ #define true 1 -+ #endif -+}end -+tst key __thread -lpthread note{ __thread keyword exists and works with -lpthread }end execute{ -+ #include -+ -+ #define INITIAL 1 -+ #define LOOP 100 -+ -+ static __thread int specific = INITIAL; -+ static int global = 0; -+ -+ static void* worker(void* arg) -+ { -+ int k; -+ int v; -+ v = (int)(arg - 0); -+ for (k = 0; k < LOOP; ++k) -+ { -+ specific += v; -+ usleep(1); -+ } -+ if (specific != (INITIAL + LOOP * v)) -+ global = 1; -+ return 0; -+ } -+ int main() -+ { -+ pthread_t th[2]; -+ -+ if (pthread_create(&th[0], 0, worker, (void*)0 + 5) || -+ pthread_create(&th[1], 0, worker, (void*)0 + 7)) -+ { -+ NOTE("pthread_create failed"); -+ return 1; -+ } -+ pthread_join(th[0], 0); -+ pthread_join(th[1], 0); -+ if (global) -+ { -+ NOTE("__thread variable not thread specific"); -+ return 1; -+ } -+ if (specific != INITIAL) -+ { -+ NOTE("main __thread variable changed by another thread"); -+ return 1; -+ } -+ return 0; -+ } -+}end no{ -+ #define __thread /* __thread keyword does not exist or does not work with -lpthread */ -+}end - - tst - -DTRY=1 - -DTRY=1 -Dvoid=char - -DTRY=2 - -DTRY=3 - -DTRY=4 output{ - #if _STD_ && _hdr_stdarg