diff --git a/.ksh.metadata b/.ksh.metadata new file mode 100644 index 0000000..3643f5b --- /dev/null +++ b/.ksh.metadata @@ -0,0 +1,2 @@ +316428e9937806183a134aa1669dea40c3a73695 SOURCES/ast-ksh.2012-08-01.tgz +0b472a615db384fe707042baaa3347dc1aa1c81e SOURCES/INIT.2012-08-01.tgz diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/dotkshrc b/SOURCES/dotkshrc new file mode 100644 index 0000000..349e599 --- /dev/null +++ b/SOURCES/dotkshrc @@ -0,0 +1,12 @@ +# .kshrc + +# Source global definitions +if [ -f /etc/kshrc ]; then + . /etc/kshrc +fi + +# use emacs editing mode by default +set -o emacs + +# User specific aliases and functions + diff --git a/SOURCES/ksh-20070328-builtins.patch b/SOURCES/ksh-20070328-builtins.patch new file mode 100644 index 0000000..061bf9a --- /dev/null +++ b/SOURCES/ksh-20070328-builtins.patch @@ -0,0 +1,11 @@ +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) +- CMDLIST(mkdir) + CMDLIST(logname) + CMDLIST(cat) + CMDLIST(cmp) diff --git a/SOURCES/ksh-20080202-manfix.patch b/SOURCES/ksh-20080202-manfix.patch new file mode 100644 index 0000000..8fe4225 --- /dev/null +++ b/SOURCES/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/SOURCES/ksh-20100202-pathvar.patch b/SOURCES/ksh-20100202-pathvar.patch new file mode 100644 index 0000000..5086499 --- /dev/null +++ b/SOURCES/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/SOURCES/ksh-20100621-fdstatus.patch b/SOURCES/ksh-20100621-fdstatus.patch new file mode 100644 index 0000000..99abb55 --- /dev/null +++ b/SOURCES/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/SOURCES/ksh-20100826-fixregr.patch b/SOURCES/ksh-20100826-fixregr.patch new file mode 100644 index 0000000..87cb13c --- /dev/null +++ b/SOURCES/ksh-20100826-fixregr.patch @@ -0,0 +1,68 @@ +diff -up ksh-20120801/src/cmd/ksh93/tests/builtins.sh.fixregr ksh-20120801/src/cmd/ksh93/tests/builtins.sh +--- ksh-20120801/src/cmd/ksh93/tests/builtins.sh.fixregr 2012-07-16 17:23:56.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/tests/builtins.sh 2012-08-08 12:29:00.733243019 +0200 +@@ -303,9 +303,9 @@ then err_exit "printf '%..*s' not workin + fi + [[ $(printf '%q\n') == '' ]] || err_exit 'printf "%q" with missing arguments' + # we won't get hit by the one second boundary twice, right? +-[[ $(printf '%T\n' now) == "$(date)" ]] || +-[[ $(printf '%T\n' now) == "$(date)" ]] || +-err_exit 'printf "%T" now' ++[[ $(printf '%T\n' now | sed 's/GMT/UTC/') == "$(date)" ]] || ++[[ $(printf '%T\n' now | sed 's/GMT/UTC/') == "$(date)" ]] || ++err_exit 'printf "%T" now = '"$(printf '%T\n' now) != $(date)" + behead() + { + read line +diff -up ksh-20120801/src/cmd/ksh93/tests/locale.sh.fixregr ksh-20120801/src/cmd/ksh93/tests/locale.sh +--- ksh-20120801/src/cmd/ksh93/tests/locale.sh.fixregr 2012-06-26 21:57:46.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/tests/locale.sh 2012-08-08 12:29:20.039405240 +0200 +@@ -104,6 +104,7 @@ if (( $($SHELL -c $'export LC_ALL='$loca + then LC_ALL=$locale $SHELL -c b1=$'"\342\202\254\342\202\254\342\202\254\342\202\254w\342\202\254\342\202\254\342\202\254\342\202\254"; [[ ${b1:4:1} == w ]]' || err_exit 'multibyte ${var:offset:len} not working correctly' + fi + ++locale=en_US.UTF-8 + #$SHELL -c 'export LANG='$locale'; printf "\u[20ac]\u[20ac]" > $tmp/two_euro_chars.txt' + printf $'\342\202\254\342\202\254' > $tmp/two_euro_chars.txt + exp="6 2 6" +@@ -111,11 +112,11 @@ set -- $($SHELL -c " + unset LC_CTYPE + export LANG=$locale + export LC_ALL=C +- command wc -C < $tmp/two_euro_chars.txt ++ command wc -m < $tmp/two_euro_chars.txt + unset LC_ALL +- command wc -C < $tmp/two_euro_chars.txt ++ command wc -m < $tmp/two_euro_chars.txt + export LC_ALL=C +- command wc -C < $tmp/two_euro_chars.txt ++ command wc -m < $tmp/two_euro_chars.txt + ") + got=$* + [[ $got == $exp ]] || err_exit "command wc LC_ALL default failed -- expected '$exp', got '$got'" +@@ -134,6 +135,8 @@ set -- $($SHELL -c " + got=$* + [[ $got == $exp ]] || err_exit "builtin wc LC_ALL default failed -- expected '$exp', got '$got'" + ++locale=C_EU.UTF-8 ++ + # multibyte char straddling buffer boundary + + { +@@ -190,6 +193,7 @@ do exp=$1 + done + + # setocale(LC_ALL,"") after setlocale() initialization ++locale=en_US.UTF-8 + + printf 'f1\357\274\240f2\n' > input1 + printf 't2\357\274\240f1\n' > input2 +@@ -336,7 +340,7 @@ then LC_ALL=en_US.UTF-8 + [[ $(print -r -- "$x") == $'hello\u[20ac]\xee world' ]] || err_exit '%q with unicode and non-unicode not working' + if [[ $(whence od) ]] + then got='68 65 6c 6c 6f e2 82 ac ee 20 77 6f 72 6c 64 0a' +- [[ $(print -r -- "$x" | od -An -tx1) == "$got" ]] || err_exit "incorrect string from printf %q" ++ [[ $(print -r -- "$x" | od -An -tx1) =~ $got ]] || err_exit "incorrect string from printf %q" + fi + + fi diff --git a/SOURCES/ksh-20120801-cdfix.patch b/SOURCES/ksh-20120801-cdfix.patch new file mode 100644 index 0000000..59265dd --- /dev/null +++ b/SOURCES/ksh-20120801-cdfix.patch @@ -0,0 +1,14 @@ +diff -up ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c +--- ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix 2013-02-01 16:04:55.507150242 +0100 ++++ ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c 2013-02-01 16:06:39.361007641 +0100 +@@ -214,7 +214,10 @@ int b_cd(int argc, char *argv[],Shbltin_ + if(*++dp=='.' && (*++dp=='/' || *dp==0)) + n++; + else if(*dp && *dp!='/') ++ { ++ dp--; + break; ++ } + if(*dp==0) + break; + } diff --git a/SOURCES/ksh-20120801-cdfix2.patch b/SOURCES/ksh-20120801-cdfix2.patch new file mode 100644 index 0000000..84bb491 --- /dev/null +++ b/SOURCES/ksh-20120801-cdfix2.patch @@ -0,0 +1,25 @@ +diff -up ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix2 ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c +--- ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix2 2013-02-01 16:46:50.441771371 +0100 ++++ ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c 2013-02-01 16:57:43.241784024 +0100 +@@ -61,6 +61,7 @@ int sh_diropenat(Shell_t *shp, int dir, + { + int fd,shfd; + int savederrno=errno; ++ struct stat fs; + #ifndef AT_FDCWD + NOT_USED(dir); + #endif +@@ -133,6 +134,13 @@ int sh_diropenat(Shell_t *shp, int dir, + + if(fd < 0) + return fd; ++ ++ if (!fstat(fd, &fs) && !S_ISDIR(fs.st_mode)) ++ { ++ close(fd); ++ errno = ENOTDIR; ++ return -1; ++ } + + /* Move fd to a number > 10 and *register* the fd number with the shell */ + shfd = sh_fcntl(fd, F_dupfd_cloexec, 10); diff --git a/SOURCES/ksh-20120801-covsfix.patch b/SOURCES/ksh-20120801-covsfix.patch new file mode 100644 index 0000000..c64e2a7 --- /dev/null +++ b/SOURCES/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/SOURCES/ksh-20120801-forkbomb.patch b/SOURCES/ksh-20120801-forkbomb.patch new file mode 100644 index 0000000..7a1a5c1 --- /dev/null +++ b/SOURCES/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/SOURCES/ksh-20120801-kshmfix.patch b/SOURCES/ksh-20120801-kshmfix.patch new file mode 100644 index 0000000..72c792a --- /dev/null +++ b/SOURCES/ksh-20120801-kshmfix.patch @@ -0,0 +1,53 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/main.c.monintoron ksh-20120801/src/cmd/ksh93/sh/main.c +--- ksh-20120801/src/cmd/ksh93/sh/main.c.monintoron 2013-05-31 10:15:02.738828102 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/main.c 2013-05-31 10:15:36.057095262 +0200 +@@ -406,10 +406,10 @@ static void exfile(register Shell_t *shp + { + buff.mode = SH_JMPEXIT; + sh_onoption(SH_TRACKALL); +- sh_offoption(SH_MONITOR); + } + sh_offstate(SH_INTERACTIVE); +- sh_offstate(SH_MONITOR); ++ if(sh_isoption(SH_MONITOR)) ++ sh_onstate(SH_MONITOR); + sh_offstate(SH_HISTORY); + sh_offoption(SH_HISTORY); + } +diff -up ksh-20120801/src/cmd/ksh93/sh/jobs.c.orig ksh-20120801/src/cmd/ksh93/sh/jobs.c +--- ksh-20120801/src/cmd/ksh93/sh/jobs.c.orig 2013-05-31 10:12:28.358590452 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/jobs.c 2013-05-31 10:16:51.203697890 +0200 +@@ -548,7 +548,7 @@ int job_reap(register int sig) + { + px = job_byjid((int)pw->p_job); + for(; px && (px->p_flag&P_DONE); px=px->p_nxtproc); +- if(!px) ++ if(!px && sh_isoption(SH_INTERACTIVE)) + tcsetpgrp(JOBTTY,job.mypid); + } + #ifndef SHOPT_BGX +@@ -842,10 +842,11 @@ static void job_set(register struct proc + + static void job_reset(register struct process *pw) + { ++ Shell_t *shp = pw->p_shp; + /* save the terminal state for current job */ + #ifdef SIGTSTP + job_fgrp(pw,tcgetpgrp(job.fd)); +- if(tcsetpgrp(job.fd,job.mypid) !=0) ++ if(sh_isoption(SH_INTERACTIVE) && tcsetpgrp(job.fd,job.mypid) !=0) + return; + #endif /* SIGTSTP */ + /* force the following tty_get() to do a tcgetattr() unless fg */ +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 2013-05-31 10:12:27.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2013-05-31 10:18:14.650367185 +0200 +@@ -2201,7 +2201,7 @@ int sh_exec(register const Shnode_t *t, + } + shp->exitval = n; + #ifdef SIGTSTP +- if(!pipejob && sh_isstate(SH_MONITOR)) ++ if(!pipejob && sh_isstate(SH_MONITOR) && sh_isoption(SH_INTERACTIVE)) + tcsetpgrp(JOBTTY,shp->gd->pid); + #endif /*SIGTSTP */ + job.curpgid = savepgid; diff --git a/SOURCES/ksh-20120801-macro.patch b/SOURCES/ksh-20120801-macro.patch new file mode 100644 index 0000000..004a5eb --- /dev/null +++ b/SOURCES/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/SOURCES/ksh-20120801-memlik.patch b/SOURCES/ksh-20120801-memlik.patch new file mode 100644 index 0000000..31f1eb9 --- /dev/null +++ b/SOURCES/ksh-20120801-memlik.patch @@ -0,0 +1,37 @@ +diff -up ksh-20120801/src/cmd/ksh93/sh/array.c.memlik ksh-20120801/src/cmd/ksh93/sh/array.c +--- ksh-20120801/src/cmd/ksh93/sh/array.c.memlik 2012-06-07 00:00:42.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/array.c 2013-06-11 16:52:47.557123973 +0200 +@@ -1701,7 +1701,11 @@ void *nv_associative(register Namval_t * + ap->header.scope = 0; + } + else +- dtclose(ap->header.table); ++ { ++ if((ap->header.nelem&ARRAY_MASK)==0 && (ap->cur=nv_search("0",ap->header.table,0))) ++ nv_associative(np,(char*)0,NV_ADELETE); ++ dtclose(ap->header.table); ++ } + return((void*)ap); + case NV_ANEXT: + if(!ap->pos) +diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.memlik ksh-20120801/src/cmd/ksh93/sh/name.c +--- ksh-20120801/src/cmd/ksh93/sh/name.c.memlik 2012-07-23 18:21:57.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/sh/name.c 2013-06-11 16:19:41.036648218 +0200 +@@ -2465,6 +2465,8 @@ static void table_unset(Shell_t *shp, re + } + } + 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); + } +@@ -3326,7 +3328,7 @@ int nv_rename(register Namval_t *np, int + shp->last_root = last_root; + if(flags&NV_MOVE) + { +- if(arraynp && !nv_isattr(np,NV_MINIMAL) && (mp=(Namval_t*)np->nvenv) && (ap=nv_arrayptr(mp))) ++ if(arraynp && !nv_isattr(np,NV_MINIMAL) && (mp=(Namval_t*)np->nvenv) && (ap=nv_arrayptr(mp)) && !ap->fun) + ap->nelem++; + } + if((nv_arrayptr(nr) && !arraynr) || nv_isvtree(nr)) diff --git a/SOURCES/ksh-20120801-mlikfiks.patch b/SOURCES/ksh-20120801-mlikfiks.patch new file mode 100644 index 0000000..fbf016a --- /dev/null +++ b/SOURCES/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/SOURCES/ksh-20120801-mtty.patch b/SOURCES/ksh-20120801-mtty.patch new file mode 100644 index 0000000..7f599e6 --- /dev/null +++ b/SOURCES/ksh-20120801-mtty.patch @@ -0,0 +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 + * completed. Make parent the job group id. + */ + if(postid==0) +- job.curpgid = parent; ++ job.curpgid = getpid(); + if(job.jobcontrol || (flags&FAMP)) + { + if(setpgid(parent,job.curpgid)<0 && errno==EPERM) diff --git a/SOURCES/ksh-20120801-rmdirfix.patch b/SOURCES/ksh-20120801-rmdirfix.patch new file mode 100644 index 0000000..ae9dfd7 --- /dev/null +++ b/SOURCES/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/SOURCES/ksh-20120801-tabfix.patch b/SOURCES/ksh-20120801-tabfix.patch new file mode 100644 index 0000000..962763e --- /dev/null +++ b/SOURCES/ksh-20120801-tabfix.patch @@ -0,0 +1,18 @@ +diff -up ksh-20120801/src/cmd/ksh93/edit/emacs.c.tabfix ksh-20120801/src/cmd/ksh93/edit/emacs.c +--- ksh-20120801/src/cmd/ksh93/edit/emacs.c.tabfix 2012-07-17 22:44:44.000000000 +0200 ++++ ksh-20120801/src/cmd/ksh93/edit/emacs.c 2013-03-07 15:58:59.902161711 +0100 +@@ -1011,10 +1011,13 @@ static int escape(register Emacs_t* ep,r + ep->ed->e_tabcount=0; + else + { ++ int oldi = i; + i=ed_getchar(ep->ed,0); + ed_ungetchar(ep->ed,i); +- if(isdigit(i)) ++ if(isdigit(i) && oldi=='=') + ed_ungetchar(ep->ed,ESC); ++ else if (isdigit(i) || i=='\t') ++ ep->ed->e_tabcount=0; + } + } + else diff --git a/SOURCES/ksh-20130214-fixkill.patch b/SOURCES/ksh-20130214-fixkill.patch new file mode 100644 index 0000000..0862880 --- /dev/null +++ b/SOURCES/ksh-20130214-fixkill.patch @@ -0,0 +1,21 @@ +diff -up ksh-20130214/src/cmd/ksh93/sh/jobs.c.fixkill ksh-20130214/src/cmd/ksh93/sh/jobs.c +--- ksh-20130214/src/cmd/ksh93/sh/jobs.c.fixkill 2012-09-26 17:43:04.000000000 +0200 ++++ ksh-20130214/src/cmd/ksh93/sh/jobs.c 2013-02-22 16:38:05.080161740 +0100 +@@ -1104,6 +1104,8 @@ static struct process *job_bystring(regi + + int job_kill(register struct process *pw,register int sig) + { ++ if(pw==0) ++ goto error; + Shell_t *shp = pw->p_shp; + register pid_t pid; + register int r; +@@ -1127,8 +1129,6 @@ int job_kill(register struct process *pw + #endif /* SIGTSTP */ + job_lock(); + errno = ECHILD; +- if(pw==0) +- goto error; + pid = pw->p_pid; + #if SHOPT_COSHELL + if(pw->p_cojob) diff --git a/SOURCES/ksh-20130628-longer.patch b/SOURCES/ksh-20130628-longer.patch new file mode 100644 index 0000000..4761a34 --- /dev/null +++ b/SOURCES/ksh-20130628-longer.patch @@ -0,0 +1,58 @@ +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 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 */ \ + long timeout; /* read timeout */ \ +- short curenv; /* current subshell number */ \ +- short jobenv; /* subshell number for jobs */ \ ++ long curenv; /* current subshell number */ \ ++ long jobenv; /* subshell number for jobs */ \ + int infd; /* input file descriptor */ \ + short nextprompt; /* next prompt is PS */ \ + 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 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 */ + unsigned short p_flag; /* flags - see below */ +- int p_env; /* subshell environment number */ ++ long p_env; /* subshell environment number */ + #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 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; + +-static int subenv; ++static long subenv; + + + /* +@@ -171,7 +171,8 @@ void sh_subfork(void) + { + register struct subshell *sp = subshell_data; + Shell_t *shp = sp->shp; +- 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 +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; +- int savecurenv = shp->curenv; ++ long savecurenv = shp->curenv; + int savejobpgid = job.curpgid; + int *saveexitval = job.exitval; + int16_t subshell; diff --git a/SOURCES/kshcomp.conf b/SOURCES/kshcomp.conf new file mode 100644 index 0000000..7a49da4 --- /dev/null +++ b/SOURCES/kshcomp.conf @@ -0,0 +1 @@ +:kshcomp:M::\x0b\x13\x08::/bin/ksh93: diff --git a/SOURCES/kshrc.rhs b/SOURCES/kshrc.rhs new file mode 100644 index 0000000..fd8a14c --- /dev/null +++ b/SOURCES/kshrc.rhs @@ -0,0 +1,53 @@ +# +# /etc/kshrc is sourced in interactive shells. It +# should contain commands to set up aliases, functions, +# options, key bindings, etc. +# + +# Set prompts +#PROMPT='[%n@%m]%~%# ' # default prompt +#RPROMPT=' %~' # prompt for right side of screen + +_src_etc_profile_d() +{ + # from zshrc, with ksh fixes + if [[ ! -o login ]]; then # We're not a login shell + for i in /etc/profile.d/*.sh; do + if [ -r "$i" ]; then + . $i + fi + done + unset i + fi +} + +pathmunge () { +case ":${PATH}:" in +*:"$1":*) + ;; +*) + if [ "$2" = "after" ]; then + PATH=$PATH:$1 + else + PATH=$1:$PATH + fi +esac +} + +_src_etc_profile_d + +unset -f _src_etc_profile_d +unset -f pathmunge + +# key bindings - make Delete, Home, End,... work +keybd_trap () { + case ${.sh.edchar} in + $'\e[1~') .sh.edchar=$'\001';; # Home = beginning-of-line + $'\e[F') .sh.edchar=$'\005';; # End = end-of-line + $'\e[5~') .sh.edchar=$'\e>';; # PgUp = history-previous + $'\e[6~') .sh.edchar=$'\e<';; # PgDn = history-next + $'\e[3~') .sh.edchar=$'\004';; # Delete = delete-char + esac +} +trap keybd_trap KEYBD + diff --git a/SPECS/ksh.spec b/SPECS/ksh.spec new file mode 100644 index 0000000..f8a2cb3 --- /dev/null +++ b/SPECS/ksh.spec @@ -0,0 +1,584 @@ +%define releasedate 2012-08-01 + +Name: ksh +Summary: The Original ATT Korn Shell +URL: http://www.kornshell.com/ +Group: System Environment/Shells +#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: EPL +Version: 20120801 +Release: 11%{?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 +Source2: kshcomp.conf +Source3: kshrc.rhs +Source4: dotkshrc + +# expected results of test suite +%global testresults %{_sourcedir}/expectedresults.log + +# don't use not wanted/needed builtins - Fedora/RHEL specific +Patch1: ksh-20070328-builtins.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 +Patch100: ksh-20120801-mtty.patch + +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Conflicts: pdksh +Requires: coreutils, diffutils, chkconfig +# regression test suite uses 'ps' from procps +BuildRequires: procps, bison +Requires(post): grep, coreutils, chkconfig, systemd-units +Requires(preun): grep, coreutils, chkconfig + +%description +KSH-93 is the most recent version of the KornShell by David Korn of +AT&T Bell Laboratories. +KornShell is a shell programming language, which is upward compatible +with "sh" (the Bourne Shell). + +%prep +%setup -q -c +%setup -q -T -D -a 1 +%patch1 -p1 -b .builtins +%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 +%patch100 -p1 -b .mtty + +#/dev/fd test does not work because of mock +sed -i 's|ls /dev/fd|ls /proc/self/fd|' src/cmd/ksh93/features/options + +# sh/main.c was not using CCFLAGS +sed -i '/-c sh\/main.c/s|${mam_cc_FLAGS} |${mam_cc_FLAGS} ${CCFLAGS} |p' src/cmd/ksh93/Mamfile + +%build +XTRAFLAGS="" +for f in -Wmissing-braces -Wunused-result -Wreturn-type -Wint-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 $XTRAFLAGS -DSHOPT_AUDIT" +export CC=gcc +./bin/package "make" + + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT{/bin,%{_bindir},%{_mandir}/man1} +install -c -m 755 arch/*/bin/ksh $RPM_BUILD_ROOT/bin/ksh93 +install -c -m 755 arch/*/bin/shcomp $RPM_BUILD_ROOT%{_bindir}/shcomp +install -c -m 644 arch/*/man/man1/sh.1 $RPM_BUILD_ROOT%{_mandir}/man1/ksh93.1 +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/skel +install -m 644 %{SOURCE4} $RPM_BUILD_ROOT%{_sysconfdir}/skel/.kshrc +install -m 644 %{SOURCE3} $RPM_BUILD_ROOT%{_sysconfdir}/kshrc +install -D -m 644 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/binfmt.d/kshcomp.conf + +#fool rpmbuild about %ghost files +touch $RPM_BUILD_ROOT/bin/ksh +touch $RPM_BUILD_ROOT%{_mandir}/man1/ksh.1.gz + +%check +[ -f ./skipcheck -o -f ./../skipcheck ] && exit 0 ||: +%if 0%{?rhel} > 6 +%ifarch s390 +exit 0 +%endif +%endif + +export SHELL=$(ls $(pwd)/arch/*/bin/ksh) +cd src/cmd/ksh93/tests/ +ulimit -c unlimited +if [ ! -e /dev/fd ] +then + echo "ERROR: /dev/fd does not exist, regression tests skipped" + exit 0 +fi +$SHELL ./shtests 2>&1 | tee testresults.log +ls core.* 2>/dev/null ||: +exit 0 + +%post +if [ ! -f /etc/shells ]; then + echo "/bin/ksh" > /etc/shells +else + if ! grep -q '^/bin/ksh$' /etc/shells ; then + echo "/bin/ksh" >> /etc/shells + fi +fi + +/bin/systemctl try-restart systemd-binfmt.service >/dev/null 2>&1 || : +%{_sbindir}/alternatives --install /bin/ksh ksh \ + /bin/ksh93 50 \ + --slave %{_mandir}/man1/ksh.1.gz ksh-man \ + %{_mandir}/man1/ksh93.1.gz + +#if not symlink we are updating ksh where there was no alternatives before +#so replace with symlink and set alternatives +if [ ! -L /bin/ksh ]; then + %{_sbindir}/alternatives --auto ksh + ln -sf /etc/alternatives/ksh /bin/ksh + ln -sf /etc/alternatives/ksh-man %{_mandir}/man1/ksh.1.gz +fi + + +%preun +if [ $1 = 0 ]; then + %{_sbindir}/alternatives --remove ksh /bin/ksh93 +fi + +%postun +if [ ! -f /bin/ksh ]; then + sed -i '/^\/bin\/ksh$/ d' /etc/shells +fi + +%verifyscript +echo -n "Looking for ksh in /etc/shells... " +if ! grep '^/bin/ksh$' /etc/shells > /dev/null; then + echo "missing" + echo "ksh missing from /etc/shells" >&2 +else + echo "found" +fi + +%files +%defattr(-, root, root,-) +%doc src/cmd/ksh93/COMPATIBILITY src/cmd/ksh93/RELEASE src/cmd/ksh93/TYPES +# LICENSE file is missing, temporarily? +/bin/ksh93 +%ghost /bin/ksh +/usr/bin/shcomp +%{_mandir}/man1/ksh93.1.gz +%ghost %{_mandir}/man1/ksh.1.gz +%config(noreplace) %{_sysconfdir}/skel/.kshrc +%config(noreplace) %{_sysconfdir}/kshrc +%config(noreplace) %{_sysconfdir}/binfmt.d/kshcomp.conf + +%clean + rm -rf $RPM_BUILD_ROOT + +%changelog +* Wed Oct 30 2013 Michal Hlavinka - 20120801-11 +- ksh stops on read when monitor mode is enabled (#1023110) + +* Wed Jun 12 2013 Michal Hlavinka - 20120801-10 +- fix memory leak +- monitor mode in scripts wasn't working + +* Fri May 24 2013 Michal Hlavinka - 20120801-9 +- add alternatives switching with mksh + +* Thu Mar 07 2013 Michal Hlavinka - 20120801-8 +- fix another reproducer for tab completion + +* Fri Feb 22 2013 Michal Hlavinka - 20120801-7 +- do not segfault on kill % (#914669) + +* Fri Feb 01 2013 Michal Hlavinka - 20120801-6 +- cd file did not produce any error + +* Fri Jan 25 2013 Michal Hlavinka - 20120801-5 +- ksh could not enter directories with path containing /.something (#889748) +- file name autocomplete prevented following numeric input (#889745) + +* Wed Nov 21 2012 Michal Hlavinka - 20120801-4 +- bind Home, End, Delete,... key correctly for emacs mode +- do not crash when executed from deleted directory + +* Fri Sep 14 2012 Michal Hlavinka - 20120801-3 +- fix typo in binfmt config file +- register binary format after package installation + +* Thu Sep 13 2012 Michal Hlavinka - 20120801-2 +- add support for direct execution of compiled scripts + +* Wed Aug 08 2012 Michal Hlavinka - 20120801-1 +- ksh updated to 20120801 + +* Tue Jul 31 2012 Michal Hlavinka - 20120727-1 +- ksh updated to 2012-07-27 + +* Thu Jul 19 2012 Fedora Release Engineering - 20120628-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon Jul 02 2012 Michal Hlavinka - 20120628-1 +- ksh updated to 20120628 + +* Wed Jun 27 2012 Michal Hlavinka - 20120626-1 +- ksh updated to 20120626 + +* Fri Jun 22 2012 Michal Hlavinka - 20120620-1 +- ksh updated to 2012-06-20 + +* Wed Jun 13 2012 Michal Hlavinka - 20120612-1 +- ksh updated to 20120612 + +* Mon Jun 04 2012 Michal Hlavinka - 20120531-1 +- ksh updated to 2012-05-31 + +* Mon Mar 19 2012 Michal Hlavinka - 20120229-2 +- do not hang after return code 12 + +* Wed Mar 14 2012 Michal Hlavinka - 20120229-1 +- ksh updated to 2012-02-29 + +* Tue Mar 13 2012 Michal Hlavinka - 20120214-2 +- fix tilda expansion in scripts + +* Mon Feb 20 2012 Michal Hlavinka - 20120214-1 +- ksh updated to 20120214 + +* Mon Feb 06 2012 Michal Hlavinka - 20120202-1 +- ksh updated to 20120202 + +* Thu Jan 05 2012 Michal Hlavinka - 20120101-1 +- ksh updated to 2012-01-01 + +* Wed Dec 07 2011 Michal Hlavinka - 20110630-9 +- do not crash when browsing through history containing comment (#733813) + +* Wed Dec 07 2011 Michal Hlavinka - 20110630-8 +- do not crash when two subseguent dots are used in variable or command name (#733544) + +* Mon Dec 05 2011 Michal Hlavinka - 20110630-7 +- fix: ksh can prematurely exit without crash or any error +- make spec work in epel + +* Thu Nov 10 2011 Michal Hlavinka - 20110630-6 +- add files to %%doc + +* Thu Oct 06 2011 Michal Hlavinka - 20110630-5 +- ksh sometimes returns wrong exit code when pid numbers are being recycled + +* Tue Oct 04 2011 Michal Hlavinka - 20110630-4 +- restore tty settings after timed out read (#572291) + +* Fri Aug 12 2011 Michal Hlavinka - 20110630-3 +- do not crash when killing last bg job when there is not any + +* Wed Aug 03 2011 Michal Hlavinka - 20110630-2 +- fix: IFS manipulation in a function can cause crash + +* Fri Jul 01 2011 Michal Hlavinka - 20110630-1 +- ksh updated to 2011-06-30 + +* Wed Jun 08 2011 Michal Hlavinka - 20110505-2 +- fix: resume of suspended process using pipes does not work (#708909) + +* Mon May 09 2011 Michal Hlavinka - 20110505-1 +- ksh updated to 2011-05-05 + +* Fri Apr 29 2011 Michal Hlavinka - 20110428-1 +- ksh updated to 2011-04-28 + +* Mon Apr 18 2011 Michal Hlavinka - 20110415-1 +- ksh updated to 2011-04-15 + +* Tue Mar 29 2011 Michal Hlavinka - 20110208-3 +- fix array definition being treated as fixed array +- fix suspend crashing ksh + +* Mon Mar 07 2011 Michal Hlavinka - 20110208-2 +- fix ( ) compound list altering environment + +* Wed Feb 09 2011 Michal Hlavinka - 20110208-1 +- ksh updated to 2011-02-08 + +* Mon Feb 07 2011 Fedora Release Engineering - 20110202-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Fri Feb 04 2011 Michal Hlavinka - 20110202-1 +- ksh updated to 2011-02-02 + +* Wed Feb 02 2011 Michal Hlavinka - 20110131-1 +- ksh updated to 2011-01-31 + +* Fri Jan 28 2011 Michal Hlavinka - 20110127-1 +- ksh updated to 2011-01-27 + +* Thu Jan 20 2011 Michal Hlavinka - 20110118-1 +- ksh updated to 2011-01-18 + +* Mon Jan 17 2011 Michal Hlavinka - 20110104-1 +- ksh updated to 2011-01-04 + +* Thu Dec 23 2010 Michal Hlavinka - 20101212-2.20101122 +- found ugly regression, reverting to 2010-11-22 (with io race patch) for now + +* Thu Dec 16 2010 Michal Hlavinka - 20101212-1 +- ksh updated to 2010-12-12 + +* Mon Dec 06 2010 Michal Hlavinka - 20101201-2 +- fix file io race condition when file was created, but still does not exist + +* Fri Dec 03 2010 Michal Hlavinka - 20101201-1 +- ksh updated to 2010-12-01 + +* Tue Nov 23 2010 Michal Hlavinka - 20101122-1 +- ksh updated to 2010-11-22 + +* Mon Nov 01 2010 Michal Hlavinka - 20101026-1 +- ksh updated to 2010-10-26 + +* Tue Oct 12 2010 Michal Hlavinka - 20101010-1 +- ksh updated to 2010-10-10 + +* Fri Oct 08 2010 Michal Hlavinka - 20100924-2 +- disable only known to be broken builtins, let other enabled +- skip regression tests if /dev/fd is missing + +* Tue Sep 28 2010 Michal Hlavinka - 20100924-1 +- ksh updated to 2010-09-24 + +* Mon Aug 30 2010 Michal Hlavinka - 20100826-1 +- ksh updated to 2010-08-26 +- make regression test suite usable during package build + +* Fri Aug 13 2010 Michal Hlavinka - 20100811-1 +- ksh updated to 2010-08-11 + +* Thu Jul 08 2010 Michal Hlavinka - 20100701-1 +- updated to 2010-07-01 + +* Fri Jun 25 2010 Michal Hlavinka - 20100621-1 +- updated to 2010-06-21 + +* Tue Jun 15 2010 Michal Hlavinka - 20100527-2 +- add shcomp for shell compiling + +* Thu Jun 10 2010 Michal Hlavinka - 20100527-1 +- updated to 2010-05-27 + +* Mon May 31 2010 Michal Hlavinka - 20100309-6 +- add pathmunge to /etc/kshrc + +* Wed May 05 2010 Michal Hlavinka - 20100309-5 +- fix rare cd builtin crash (#578582) + +* Wed May 05 2010 Michal Hlavinka - 20100309-4 +- fix infinite loop when whence builtin is used with -q option (#587127) +- fix stdin for double command substitution (#584007) + +* Mon Mar 29 2010 Michal Hlavinka - 20100309-3 +- fix typo in last patch + +* Fri Mar 26 2010 Michal Hlavinka - 20100309-2 +- restore tty settings after timed out read for utf-8 locale + +* Wed Mar 10 2010 Michal Hlavinka - 20100309-1 +- updated to 2010-03-09 +- fix mock building - detection of /dev/fd/X + +* Mon Jan 04 2010 Michal Hlavinka - 20100202-1 +- updated to 2010-02-02 + +* Mon Jan 04 2010 Michal Hlavinka - 20091224-1 +- updated to 2009-12-24 + +* Mon Dec 07 2009 Michal Hlavinka - 20091206-1 +- updated to 2009-12-06 + +* Fri Dec 04 2009 Michal Hlavinka - 20091130-1 +- updated to 2009-11-30 + +* Wed Nov 18 2009 Michal Hlavinka - 20091021-1 +- updated to 2009-10-21 + +* Thu Aug 27 2009 Michal Hlavinka - 20090630-1 +- updated to 2009-06-30 + +* Fri Jul 24 2009 Fedora Release Engineering - 20090505-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Mon May 11 2009 Michal Hlavinka - 20090505-1 +- updated to 2009-05-05 + +* Tue May 05 2009 Michal Hlavinka - 20090501-1 +- updated to 2009-05-01 + +* Tue Mar 10 2009 Michal Hlavinka - 20081104-3 +- fix typos in spec file + +* Wed Feb 25 2009 Fedora Release Engineering - 20081104-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Wed Jan 21 2009 Michal Hlavinka 20081104-1 +- update to 2008-11-04 +- ast-ksh-locales are not useable remove them + +* Tue Oct 21 2008 Michal Hlavinka 20080725-4 +- fix #467025 - Ksh fails to initialise environment when login from graphic console + +* Wed Aug 06 2008 Tomas Smetana 20080725-3 +- fix BuildRequires, rebuild + +* Tue Aug 5 2008 Tom "spot" Callaway 20080725-2 +- fix license tag + +* Mon Jul 28 2008 Tomas Smetana 20080725-1 +- new upstream version + +* Thu Jun 26 2008 Tomas Smetana 20080624-1 +- new upstream version + +* Mon Feb 11 2008 Tomas Smetana 20080202-1 +- new upstream version + +* Wed Jan 30 2008 Tomas Smetana 20071105-3 +- fix #430602 - ksh segfaults after unsetting OPTIND + +* Mon Jan 07 2008 Tomas Smetana 20071105-2 +- fix #405381 - ksh will not handle $(xxx) when typeset -r IFS +- fix #386501 - bad group in spec file + +* Wed Nov 07 2007 Tomas Smetana 20071105-1 +- new upstream version + +* Wed Aug 22 2007 Tomas Smetana 20070628-1.1 +- rebuild + +* Thu Jul 12 2007 Tomas Smetana 20070628-1 +- new upstream version +- fix unaligned access messages (Related: #219420) + +* Tue May 22 2007 Tomas Smetana 20070328-2 +- fix wrong exit status of spawned process after SIGSTOP +- fix building of debuginfo package, add %%{?dist} to release +- fix handling of SIGTTOU in non-interactive shell +- remove useless builtins + +* Thu Apr 19 2007 Tomas Smetana 20070328-1 +- new upstream source +- fix login shell invocation (#182397) +- fix memory leak + +* Wed Feb 21 2007 Karsten Hopp 20070111-1 +- new upstream version +- fix invalid write in uname function + +* Wed Jul 12 2006 Jesse Keating - 20060214-1.1 +- rebuild + +* Thu Jun 01 2006 Karsten Hopp 20060214-1 +- new upstream source + +* Mon Feb 27 2006 Karsten Hopp 20060124-3 +- PreReq grep, coreutils (#182835) + +* Tue Feb 14 2006 Karsten Hopp 20060124-2 +- make it build in chroots (#180561) + +* Mon Feb 13 2006 Karsten Hopp 20060124-1 +- version 20060124 + +* Fri Feb 10 2006 Jesse Keating - 20050202-5.1 +- bump again for double-long bug on ppc(64) + +* Fri Feb 10 2006 Karsten Hopp 20050202-5 +- rebuild + +* Tue Feb 07 2006 Jesse Keating - 20050202-4.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Thu Feb 02 2006 Karsten Hopp 20050202-4 +- fix uname -i output +- fix loop (*-path.patch) +- conflict pdksh instead of obsoleting it + +* Fri Dec 16 2005 Jesse Keating 20050202-3.1 +- rebuilt for new gcj + +* Tue May 10 2005 Karsten Hopp 20050202-3 +- enable debuginfo + +* Tue Mar 15 2005 Karsten Hopp 20050202-2 +- add /usr/bin/ksh link for compatibility with pdksh scripts (#151134) + +* Wed Mar 02 2005 Karsten Hopp 20050202-1 +- update and rebuild with gcc-4 + +* Tue Mar 01 2005 Karsten Hopp 20041225-2 +- fix gcc4 build + +* Fri Jan 21 2005 Karsten Hopp 20041225-1 +- rebuild with new ksh tarball (license change) + +* Tue Nov 02 2004 Karsten Hopp 20040229-11 +- disable ia64 for now + +* Fri Oct 15 2004 Karsten Hopp 20040229-9 +- rebuild + +* Thu Sep 02 2004 Nalin Dahyabhai 20040229-8 +- remove '&' from summary + +* Thu Sep 02 2004 Bill Nottingham 20040229-7 +- obsolete pdksh (#131303) + +* Mon Aug 02 2004 Karsten Hopp 20040229-6 +- obsolete ksh93, provide ksh93 + +* Mon Jul 05 2004 Karsten Hopp 20040229-3 +- add /bin/ksh to /etc/shells + +* Wed Jun 16 2004 Karsten Hopp 20040229-2 +- add ppc64 patch to avoid ppc64 dot symbol problem + +* Fri May 28 2004 Karsten Hopp 20040229-1 +- initial version +