diff --git a/ksh.changes b/ksh.changes index 7157fff..4c28437 100644 --- a/ksh.changes +++ b/ksh.changes @@ -1,3 +1,30 @@ +------------------------------------------------------------------- +Fri Oct 25 14:07:57 UTC 2013 - werner@suse.de + +- Add missing sfsetbuf() in patch ksh93-fdstatus.dif +- Rework patch ksh93-dttree-crash.dif +- Rework patch ksh93-uninitialized.dif + +------------------------------------------------------------------- +Tue Oct 22 11:58:21 UTC 2013 - werner@suse.de + +- Change patch ksh93-fdstatus.dif by adding some more EINTR wrapper + +------------------------------------------------------------------- +Fri Oct 18 12:21:58 UTC 2013 - werner@suse.de + +- Add patch ksh93-sfio.dif as on overlapping memory areas there + should memmove be used instead of memcopy (backport 2013-10-10) + +------------------------------------------------------------------- +Fri Oct 18 10:41:05 UTC 2013 - werner@suse.de + +- Change patch ksh93-fdstatus.dif which may solve bnc#844071 +- Add patch ksh93-fs3d.dif to avoid crash due dummy function call + fs3d_mount(3ast) during valgrind sessions +- Add patch ksh93-uninitialized.dif to avoid sometimes random + errors on busy systems which may also related to bnc#844071 + ------------------------------------------------------------------- Thu Sep 19 08:43:37 UTC 2013 - werner@suse.de diff --git a/ksh.spec b/ksh.spec index 48b927d..1e6f795 100644 --- a/ksh.spec +++ b/ksh.spec @@ -129,6 +129,12 @@ Patch32: ksh93-heredoclex.dif Patch33: ksh93-fdstatus.dif # PATCH-FIX-UPSTREAM ksh93-alias-k.dif [bnc#824187] Patch34: ksh93-alias-k.dif +# PATCH-FIX-SUSE Reduce warnings about uninitialized varaibles (most of them are handled correct) +Patch35: ksh93-uninitialized.dif +# PATCH-FIX-SUSE Do not use mount(2) system call instead of fs3d_mount(3ast) +Patch36: ksh93-fs3d.dif +# PATCH-FIX-UPSTREAM Ouch ... use memmove instead of memcopy on overlapping areas +Patch37: ksh93-sfio.dif Patch42: ksh-locale.patch %description @@ -217,6 +223,9 @@ fi %patch32 %patch33 %patch34 +%patch35 +%patch36 +%patch37 %build # @@ -245,9 +254,6 @@ fi test -s $fd -a ! -c $fd && break || true done set -- $(readlink $fd) -grep pts /proc/mounts -ls -ld /dev/ptmx -ls -ld /dev/pts exec ./sigexec $SHELL ${1+"$@"} fi IGNORED=0x$(ps --no-headers -o ignored $$) @@ -324,6 +330,7 @@ ls -ld /dev/pts cflags -Wno-implicit IGNORE cflags -Wno-unused-value IGNORE cflags -Wno-type-limits IGNORE + cflags -Wclobbered RPM_OPT_FLAGS # # Do not use -DSHOPT_SPAWN=1 and/or -DSHOPT_AMP=1 this would cause # errors due race conditions while executing the test suite. @@ -466,7 +473,7 @@ ls -ld /dev/pts done nobuiltin=${PWD}/.nobuiltin nm -D ${root}/lib/libast.so | \ - grep -E 'T[[:blank:]](_ast_)?(str|mem|(get|put|set)env|(c|m|re|v)alloc)' | \ + grep -E 'T[[:blank:]](_ast_)?(str|mem|(get|put|set)env|free|(c|m|re|v|vm)alloc)' | \ sed -r 's/[[:xdigit:]]+[[:blank:]]+T[[:blank:]]+(_ast_)?([^[:blank:]]*)/-fno-builtin-\2/' | \ sort -u > $nobuiltin rm -rf $root @@ -481,7 +488,7 @@ ls -ld /dev/pts *) cflags @$nobuiltin RPM_OPT_FLAGS esac - export > .env + export | grep -vE 'PROFILEREAD|PWD|MAIL|HOME|HOST|HIST|LESS|TMP' > .env bin/package make CCFLAGS="$RPM_OPT_FLAGS -I${root}/include" HOSTTYPE="$HOSTTYPE" AR="$AR" CC="$CC" root=$(echo ${PWD}/arch/linux*) test -d $root || exit 1 @@ -535,7 +542,16 @@ ls -ld /dev/pts sed -ri '/^L[[:blank:]]/a \t 8000' pty.sh sed -ri 's/(SECONDS[[:blank:]]*>[[:blank:]]*)([[:digit:]]+)/\18/' signal.sh unset ${!LESS*} + printf '\033[1m' + grep -E '^(model name|flags)[[:blank:]]*:' /proc/cpuinfo | sort -ur | fold -s + printf '\033(B\033[m' ${SHELL} shtests + result=$(${SHELL} -k -c 'd=`/bin/echo x y=z`; echo $d x y=z') + test "$result" = 'x x' || exit 1 + result=$(${SHELL} -c 'echo | echo "x`/bin/echo y`"') + test "$result" = xy || exit 1 + result=$(${SHELL} -c 'echo | echo "x$(/bin/echo y)"') + test "$result" = xy || exit 1 exec 3> ${TMPDIR:-/tmp}/log LANG=POSIX strace $MEMORY -o '!%{S:31}' ${SHELL} %{S:10} 400 @@ -567,7 +583,9 @@ ls -ld /dev/pts fi LANG=POSIX exec 3>&- + printf '\033[1m' uniq -c ${TMPDIR:-/tmp}/log + printf '\033(B\033[m' killall -q -s 9 ${SHELL} || true popd %endif @@ -704,7 +722,7 @@ ls -ld /dev/pts else cp %{S:3} EPL-1.0 cp %{S:4} CPL-1.0 - ln -sf EPL-v1.0 LICENSE + ln -sf EPL-1.0 LICENSE fi mv src/cmd/ksh93/OBSOLETE src/cmd/ksh93/OBSOLETE.mm echo '.VERBON 22' > grep.mm diff --git a/ksh93-builtin.dif b/ksh93-builtin.dif index e45da7d..c8d9591 100644 --- a/ksh93-builtin.dif +++ b/ksh93-builtin.dif @@ -1,6 +1,6 @@ --- src/cmd/builtin/pty.c +++ src/cmd/builtin/pty.c 2013-02-01 15:59:52.697952156 +0000 -@@ -216,13 +216,19 @@ mkpty(int* master, int* slave) +@@ -216,27 +216,64 @@ mkpty(int* master, int* slave) #if !_lib_openpty char* sname; #endif @@ -17,34 +17,64 @@ - alarm(4); - if (tcgetattr(STDERR_FILENO, &tty) >= 0) +- ttyp = &tty; +- else + alarm(6); -+ if (tcgetattr(sffileno(sfstderr), &tty) >= 0) - ttyp = &tty; - else ++ if (tcgetattr(sffileno(sfstderr), &tty) < 0) { -@@ -230,7 +236,7 @@ mkpty(int* master, int* slave) - error(-1, "unable to get standard error terminal attributes"); ++ if (errno != ENOTTY) ++ error(-1, "unable to get standard error terminal attributes"); ++ cfmakeraw(&tty); + ttyp = 0; +- error(-1, "unable to get standard error terminal attributes"); } ++ tty.c_lflag |= ICANON | IEXTEN | ISIG | ECHO|ECHOE|ECHOK|ECHOKE; ++ tty.c_oflag |= (ONLCR | OPOST); ++ tty.c_oflag &= ~(OCRNL | ONLRET); ++ tty.c_iflag |= BRKINT; ++ tty.c_iflag &= ~IGNBRK; ++ tty.c_lflag |= ISIG; ++ tty.c_cc[VTIME] = 0; ++ tty.c_cc[VMIN] = CMIN; ++#ifdef B115200 ++ cfsetispeed(&tty, B115200); ++ cfsetospeed(&tty, B115200); ++#elif defined(B57600) ++ cfsetispeed(&tty, B57600); ++ cfsetospeed(&tty, B57600); ++#elif defined(B38400) ++ cfsetispeed(&tty, B38400); ++ cfsetospeed(&tty, B38400); ++#endif ++ ttyp = &tty; #ifdef TIOCGWINSZ - if (ioctl(STDERR_FILENO, TIOCGWINSZ, &win) >= 0) -+ if (ioctl(sffileno(sfstderr), TIOCGWINSZ, &win) >= 0) - winp = &win; - else +- winp = &win; +- else ++ if (ioctl(sffileno(sfstderr), TIOCGWINSZ, &win) < 0) { -@@ -238,6 +244,12 @@ mkpty(int* master, int* slave) - error(-1, "unable to get standard error window size"); ++ if (errno != ENOTTY) ++ error(-1, "unable to get standard error window size"); ++ win.ws_row = 0; ++ win.ws_col = 0; + winp = 0; +- error(-1, "unable to get standard error window size"); } - #endif ++ if (win.ws_row < 24) ++ win.ws_row = 24; ++ if (win.ws_col < 80) ++ win.ws_col = 80; ++ winp = &win; ++#endif +#ifdef __linux__ +# if !_lib_openpty +# undef _lib_openpty +# define _lib_openpty 1 +# endif -+#endif + #endif #if _lib_openpty if (openpty(master, slave, NULL, ttyp, winp) < 0) - return -1; -@@ -279,6 +291,9 @@ mkpty(int* master, int* slave) +@@ -279,6 +316,9 @@ mkpty(int* master, int* slave) #if !O_cloexec fcntl(*slave, F_SETFD, FD_CLOEXEC); #endif @@ -54,7 +84,7 @@ alarm(0); return 0; } -@@ -317,9 +332,13 @@ process(Sfio_t* mp, Sfio_t* lp, int dela +@@ -317,9 +357,13 @@ process(Sfio_t* mp, Sfio_t* lp, int dela char* s; Sfio_t* ip; Sfio_t* sps[2]; @@ -69,7 +99,7 @@ { i = 0; t = timeout; -@@ -336,39 +355,39 @@ process(Sfio_t* mp, Sfio_t* lp, int dela +@@ -336,39 +380,39 @@ process(Sfio_t* mp, Sfio_t* lp, int dela { if (n < 0) error(ERROR_SYSTEM|2, "poll failed"); diff --git a/ksh93-dttree-crash.dif b/ksh93-dttree-crash.dif index 3af9865..df45b23 100644 --- a/ksh93-dttree-crash.dif +++ b/ksh93-dttree-crash.dif @@ -40,7 +40,7 @@ shp->fpathdict = dtopen(&_Rpdisc,Dtobag); - if(shp->fpathdict) + if(shp->fpathdict) { -+ dtuserdata(shp->fpathdict,shp,1); ++ /* dtuserdata(shp->fpathdict,shp,1); */ dtinsert(shp->fpathdict,rp); + } } diff --git a/ksh93-fdstatus.dif b/ksh93-fdstatus.dif index 375452c..9f1cba3 100644 --- a/ksh93-fdstatus.dif +++ b/ksh93-fdstatus.dif @@ -1,10 +1,17 @@ -| Fix for bnc#814135, bnc#808449, and bnc#835885 -| - crash in bestreclaim() after traversing a memory block with a very large size (ksh) -| - set -k does not work properly with ksh-93t-13.17 and higher -| - Problem after update of ksh from ksh-93u-0.14.1 to ksh-93u-0.22.1 -| This is a backport from the beta version ksh93v-2013-08-29 +--- src/cmd/ksh93/bltins/enum.c ++++ src/cmd/ksh93/bltins/enum.c 2013-10-25 13:26:45.739248213 +0000 +@@ -266,7 +266,9 @@ int b_enum(int argc, char** argv, Shblti + optdisc.opt.infof = enuminfo; + optdisc.np = tp; + nv_addtype(tp, enum_type, &optdisc.opt, sizeof(optdisc)); ++ nv_onattr(np,NV_LTOU|NV_UTOL); + } ++ nv_open(0,shp->var_tree,0); + return error_info.errors != 0; + } + --- src/cmd/ksh93/bltins/read.c -+++ src/cmd/ksh93/bltins/read.c 2013-09-17 15:01:33.000000000 +0000 ++++ src/cmd/ksh93/bltins/read.c 2013-10-25 13:26:45.740248120 +0000 @@ -280,24 +280,25 @@ int sh_readline(register Shell_t *shp,ch if(size || (flags>>D_FLAG)) /* delimiter not new-line or fixed size read */ { @@ -74,7 +81,7 @@ hist_flush(shp->gd->hist_ptr); if(jmpval > 1) --- src/cmd/ksh93/bltins/trap.c -+++ src/cmd/ksh93/bltins/trap.c 2013-09-17 14:37:19.000000000 +0000 ++++ src/cmd/ksh93/bltins/trap.c 2013-10-25 13:26:45.740248120 +0000 @@ -116,8 +116,7 @@ int b_trap(int argc,char *argv[],Shbltin continue; } @@ -95,37 +102,8 @@ } if(sig>shp->gd->sigmax) --- src/cmd/ksh93/bltins/typeset.c -+++ src/cmd/ksh93/bltins/typeset.c 2013-09-13 16:26:49.000000000 +0000 -@@ -533,6 +533,7 @@ static int setall(char **argv,regist - char *last = 0; - int nvflags=(flag&(NV_ARRAY|NV_NOARRAY|NV_VARNAME|NV_IDENT|NV_ASSIGN|NV_STATIC|NV_MOVE)); - int r=0, ref=0, comvar=(flag&NV_COMVAR),iarray=(flag&NV_IARRAY); -+ size_t len; - Shell_t *shp =tp->sh; - if(!shp->prefix) - { -@@ -579,7 +580,7 @@ static int setall(char **argv,regist - np = sh_fsearch(shp,name,NV_ADD|HASH_NOSCOPE); - else - #endif /* SHOPT_NAMESPACE */ -- np = nv_open(name,sh_subfuntree(1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE); -+ np = nv_open(name,sh_subfuntree(shp,1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE); - } - else - { -@@ -640,7 +641,10 @@ static int setall(char **argv,regist - path_alias(np,path_absolute(shp,nv_name(np),NIL(Pathcomp_t*))); - continue; - } -- np = nv_open(name,troot,nvflags|((nvflags&NV_ASSIGN)?0:NV_ARRAY)|((iarray|(nvflags&(NV_REF|NV_NOADD)==NV_REF))?NV_FARRAY:0)); -+ if(shp->nodelist && (len=strlen(name)) && name[len-1]=='@') -+ np = *shp->nodelist++; -+ else -+ np = nv_open(name,troot,nvflags|((nvflags&NV_ASSIGN)?0:NV_ARRAY)|((iarray|(nvflags&(NV_REF|NV_NOADD)==NV_REF))?NV_FARRAY:0)); - if(!np) - continue; - if(nv_isnull(np) && !nv_isarray(np) && nv_isattr(np,NV_NOFREE)) -@@ -676,7 +680,7 @@ static int setall(char **argv,regist ++++ src/cmd/ksh93/bltins/typeset.c 2013-10-25 13:26:45.741248028 +0000 +@@ -676,7 +676,7 @@ static int setall(char **argv,regist } if(!nv_isarray(np) && !strchr(name,'=') && !(shp->envlist && nv_onlist(shp->envlist,name))) { @@ -134,141 +112,9 @@ { if((flag&(NV_HOST|NV_INTEGER))!=NV_HOST) _nv_unset(np,0); -@@ -1168,14 +1172,14 @@ static int unall(int argc, char **argv, - { - name = sh_optunalias; - if(shp->subshell) -- troot = sh_subaliastree(0); -+ troot = sh_subaliastree(shp,0); - } - else - name = sh_optunset; - while(r = optget(argv,name)) switch(r) - { - case 'f': -- troot = sh_subfuntree(1); -+ troot = sh_subfuntree(shp,1); - break; - case 'a': - all=1; ---- src/cmd/ksh93/edit/edit.c -+++ src/cmd/ksh93/edit/edit.c 2013-09-16 13:04:37.000000000 +0000 -@@ -1414,12 +1414,12 @@ int ed_internal(const char *src, genchar - int ed_external(const genchar *src, char *dest) - { - register genchar wc; -- register int c,size; - register char *dp = dest; - char *dpmax = dp+sizeof(genchar)*MAXLINE-2; - if((char*)src == dp) - { -- char buffer[MAXLINE*sizeof(genchar)]; -+ int c; -+ char buffer[MAXLINE*sizeof(genchar)] = ""; - c = ed_external(src,buffer); - - #ifdef _lib_wcscpy -@@ -1431,6 +1431,7 @@ int ed_external(const genchar *src, char - } - while((wc = *src++) && dp= 0) - { -- close(acctfd); -+ sh_close(acctfd); - acctfd = n; - } - } -@@ -203,7 +203,7 @@ static int sh_checkaudit(History_t *hp, - } - while(*cp==';' || *cp==' '); - done: -- close(fd); -+ sh_close(fd); - return(r); - - } -@@ -272,14 +272,14 @@ retry: - int n; - if((n=fcntl(fd,F_DUPFD,10))>=0) - { -- close(fd); -+ sh_close(fd); - fd=n; - } - } - /* make sure that file has history file format */ - if(hsize && hist_check(fd)) - { -- close(fd); -+ sh_close(fd); - hsize = 0; - if(unlink(cp)>=0) - goto retry; -@@ -308,7 +308,7 @@ retry: - for(histmask=16;histmask <= maxlines; histmask <<=1 ); - if(!(hp=new_of(History_t,(--histmask)*sizeof(off_t)))) - { -- close(fd); -+ sh_close(fd); - return(0); - } - shgd->hist_ptr = hist_ptr = hp; -@@ -425,7 +425,7 @@ void hist_close(register History_t *hp) - #if SHOPT_ACCTFILE - if(acctfd) - { -- close(acctfd); -+ sh_close(acctfd); - acctfd = 0; - } - #endif /* SHOPT_ACCTFILE */ -@@ -470,7 +470,7 @@ static History_t* hist_trim(History_t *h - /* The unlink can fail on windows 95 */ - int fd; - char *last, *name=hist_old->histname; -- close(sffileno(hist_old->histfp)); -+ sh_close(sffileno(hist_old->histfp)); - tmpname = (char*)malloc(strlen(name)+14); - if(last = strrchr(name,'/')) - { -@@ -736,7 +736,7 @@ again: - hist_marker(buff,hp->histind); - write(fd,(char*)hist_stamp,2); - write(fd,buff,HIST_MARKSZ); -- close(fd); -+ sh_close(fd); - } - } - last = 0; -@@ -1195,7 +1195,7 @@ static int hist_exceptf(Sfio_t* fp, int - if(errno==ENOSPC || hp->histwfail++ >= 10) - return(0); - /* write failure could be NFS problem, try to re-open */ -- close(oldfd=sffileno(fp)); -+ sh_close(oldfd=sffileno(fp)); - if((newfd=open(hp->histname,O_BINARY|O_APPEND|O_CREAT|O_RDWR,S_IRUSR|S_IWUSR)) >= 0) - { - if(fcntl(newfd, F_DUPFD, oldfd) !=oldfd) --- src/cmd/ksh93/include/defs.h -+++ src/cmd/ksh93/include/defs.h 2013-09-13 14:19:35.000000000 +0000 -@@ -160,6 +160,7 @@ struct shared - Namval_t *namespace; /* current active namespace*/ \ - Namval_t *last_table; /* last table used in last nv_open */ \ - Namval_t *prev_table; /* previous table used in nv_open */ \ -+ Namval_t **nodelist; /* for decl commands */ \ - Sfio_t *outpool; /* ouput stream pool */ \ - long timeout; /* read timeout */ \ - short curenv; /* current subshell number */ \ -@@ -182,6 +183,8 @@ struct shared ++++ src/cmd/ksh93/include/defs.h 2013-10-25 13:26:45.741248028 +0000 +@@ -182,6 +182,8 @@ struct shared pid_t spid; /* subshell process id */ \ pid_t pipepid; \ pid_t outpipepid; \ @@ -277,21 +123,17 @@ int topfd; \ int savesig; \ unsigned char *sigflag; /* pointer to signal states */ \ -@@ -423,10 +426,10 @@ extern void sh_printopts(Shopt_t,int,Sh - extern int sh_readline(Shell_t*,char**,volatile int,int,ssize_t,long); - extern Sfio_t *sh_sfeval(char*[]); - extern void sh_setmatch(Shell_t*,const char*,int,int,int[],int); --extern Dt_t *sh_subaliastree(int); -+extern Dt_t *sh_subaliastree(Shell_t*,int); - extern void sh_scope(Shell_t*, struct argnod*, int); - extern Namval_t *sh_scoped(Shell_t*, Namval_t*); --extern Dt_t *sh_subfuntree(int); -+extern Dt_t *sh_subfuntree(Shell_t*,int); - extern void sh_subjobcheck(pid_t); - extern int sh_subsavefd(int); - extern void sh_subtmpfile(Shell_t*); +@@ -243,7 +245,7 @@ struct shared + char *cur_line; \ + int offsets[10]; \ + Sfio_t **sftable; \ +- unsigned char *fdstatus; \ ++ unsigned int *fdstatus; \ + const char *pwd; \ + void *jmpbuffer; \ + void *mktype; \ --- src/cmd/ksh93/include/io.h -+++ src/cmd/ksh93/include/io.h 2013-09-09 16:35:27.000000000 +0000 ++++ src/cmd/ksh93/include/io.h 2013-10-25 13:26:45.741248028 +0000 @@ -81,6 +81,7 @@ extern void sh_iosave(Shell_t *, int,in extern int sh_iovalidfd(Shell_t*, int); extern int sh_inuse(Shell_t*, int); @@ -301,7 +143,7 @@ extern int sh_ioaccess(int,int); extern int sh_devtofd(const char*); --- src/cmd/ksh93/include/jobs.h -+++ src/cmd/ksh93/include/jobs.h 2013-09-16 13:36:02.000000000 +0000 ++++ src/cmd/ksh93/include/jobs.h 2013-10-25 13:26:45.741248028 +0000 @@ -103,6 +103,7 @@ struct jobs pid_t mypid; /* process id of shell */ pid_t mypgid; /* process group id of shell */ @@ -325,27 +167,8 @@ job.in_critical--; \ } \ } while(0) ---- src/cmd/ksh93/include/name.h -+++ src/cmd/ksh93/include/name.h 2013-09-11 13:02:16.000000000 +0000 -@@ -124,6 +124,7 @@ struct Ufunction - #define NV_PARAM NV_NODISC /* expansion use positional params */ - - /* This following are for use with nodes which are not name-values */ -+#define NV_DECL 0x20000000 - #define NV_TYPE 0x1000000 - #define NV_STATIC 0x2000000 - #define NV_COMVAR 0x4000000 -@@ -190,7 +191,7 @@ extern int nv_aimax(Namval_t*); - extern int nv_atypeindex(Namval_t*, const char*); - extern int nv_setnotify(Namval_t*,char **); - extern int nv_unsetnotify(Namval_t*,char **); --extern void nv_setlist(struct argnod*, int, Namval_t*); -+extern Namval_t **nv_setlist(struct argnod*, int, Namval_t*); - extern struct argnod* nv_onlist(struct argnod*, const char*); - extern void nv_optimize(Namval_t*); - extern void nv_outname(Sfio_t*,char*, int); --- src/cmd/ksh93/sh/args.c -+++ src/cmd/ksh93/sh/args.c 2013-09-12 14:17:44.000000000 +0000 ++++ src/cmd/ksh93/sh/args.c 2013-10-25 13:26:45.741248028 +0000 @@ -32,6 +32,7 @@ #include "builtins.h" #include "terminal.h" @@ -441,56 +264,8 @@ sh_iosave(shp,-pv[fd], shp->topfd, (char*)0); #else free(shp->fifo); ---- src/cmd/ksh93/sh/arith.c -+++ src/cmd/ksh93/sh/arith.c 2013-09-13 13:44:25.000000000 +0000 -@@ -180,7 +180,10 @@ static Namval_t *scope(register Namval_t - { - ap = nv_arrayptr(np); - if(ap && !ap->table) -+ { - ap->table = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(ap->table,shp,1); -+ } - if(ap && ap->table && (nq=nv_search(nv_getsub(np),ap->table,NV_ADD))) - nq->nvenv = (char*)np; - if(nq && nv_isnull(nq)) --- src/cmd/ksh93/sh/array.c -+++ src/cmd/ksh93/sh/array.c 2013-09-13 14:11:55.000000000 +0000 -@@ -79,6 +79,7 @@ struct assoc_array - - static Namarr_t *array_scope(Namval_t *np, Namarr_t *ap, int flags) - { -+ Shell_t *shp = sh_getinterp(); - Namarr_t *aq; - #if SHOPT_FIXEDARRAY - struct fixed_array *fp; -@@ -95,6 +96,7 @@ static Namarr_t *array_scope(Namval_t *n - if(is_associative(aq)) - { - aq->scope = (void*)dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(aq->scope,shp,1); - dtview((Dt_t*)aq->scope,aq->table); - aq->table = (Dt_t*)aq->scope; - return(aq); -@@ -271,6 +273,7 @@ int nv_arrayisset(Namval_t *np, Namarr_t - */ - static Namval_t *array_find(Namval_t *np,Namarr_t *arp, int flag) - { -+ Shell_t *shp=sh_getinterp(); - register struct index_array *ap = (struct index_array*)arp; - register union Value *up; - Namval_t *mp; -@@ -373,7 +376,10 @@ static Namval_t *array_find(Namval_t *np - { - char *cp; - if(!ap->header.table) -+ { - ap->header.table = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(ap->header.table,shp,1); -+ } - sfprintf(sh.strbuf,"%d",ap->cur); - cp = sfstruse(sh.strbuf); - mp = nv_search(cp, ap->header.table, NV_ADD); ++++ src/cmd/ksh93/sh/array.c 2013-10-25 13:26:45.742247936 +0000 @@ -402,6 +408,7 @@ static Namval_t *array_find(Namval_t *np #if SHOPT_TYPEDEF int nv_arraysettype(Namval_t *np, Namval_t *tp, const char *sub, int flags) @@ -499,88 +274,42 @@ Namval_t *nq; char *av[2]; int rdonly = nv_isattr(np,NV_RDONLY); -@@ -410,7 +417,10 @@ int nv_arraysettype(Namval_t *np, Namval - av[1] = 0; - sh.last_table = 0; - if(!ap->table) -+ { - ap->table = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(ap->table,shp,1); -+ } - if(nq = nv_search(sub, ap->table, NV_ADD)) - { - if(!nq->nvfun && nq->nvalue.cp && *nq->nvalue.cp==0) -@@ -485,6 +495,7 @@ static Namfun_t *array_clone(Namval_t *n - if(ap->table) - { - ap->table = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(ap->table,shp,1); - if(ap->scope && !(flags&NV_COMVAR)) +@@ -438,10 +438,13 @@ int nv_arraysettype(Namval_t *np, Namval + nv_offattr(nq,NV_RDONLY); + if(!nv_isattr(tp,NV_BINARY)) { - ap->scope = ap->table; -@@ -854,7 +865,9 @@ static struct index_array *array_grow(Na - np->nvalue.cp=0; - if(nv_hasdisc(np,&array_disc) || (nv_type(np) && nv_isvtree(np))) ++ char *prefix = shp->prefix; + if(xtrace) + sh_offoption(SH_XTRACE); + ap->nelem &= ~ARRAY_SCAN; ++ shp->prefix = 0; + sh_eval(sh_sfeval(av),0); ++ shp->prefix = prefix; + ap->nelem |= ARRAY_SCAN; + free((void*)av[0]); + if(xtrace) +@@ -773,7 +776,10 @@ static void array_putval(Namval_t *np, c + free((void*)aq->xp); + } + if((nfp = nv_disc(np,(Namfun_t*)ap,NV_POP)) && !(nfp->nofree&1)) ++ { ++ ap = 0; + free((void*)nfp); ++ } + if(!nv_isnull(np)) { -+ Shell_t *shp = sh_getinterp(); - ap->header.table = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(ap->header.table,shp,1); - mp = nv_search("0", ap->header.table,NV_ADD); - if(mp && nv_isnull(mp)) - { -@@ -1169,6 +1182,7 @@ int nv_nextsub(Namval_t *np) - */ - Namval_t *nv_putsub(Namval_t *np,register char *sp,register long mode) - { -+ Shell_t *shp = sh_getinterp(); - register struct index_array *ap = (struct index_array*)nv_arrayptr(np); - register int size = (mode&ARRAY_MASK); - #if SHOPT_FIXEDARRAY -@@ -1180,7 +1194,6 @@ Namval_t *nv_putsub(Namval_t *np,registe - { - if(sp) - { -- Shell_t *shp = sh_getinterp(); - if(ap && ap->xp && !strmatch(sp,"+([0-9])")) - { - Namval_t *mp = nv_namptr(ap->xp,0); -@@ -1258,7 +1271,10 @@ Namval_t *nv_putsub(Namval_t *np,registe - char *cp; - Namval_t *mp; - if(!ap->header.table) -+ { - ap->header.table = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(ap->header.table,shp,1); -+ } - sfprintf(sh.strbuf,"%d",ap->cur); - cp = sfstruse(sh.strbuf); - mp = nv_search(cp, ap->header.table, NV_ADD); -@@ -1666,6 +1682,7 @@ int nv_aimax(register Namval_t* np) - */ - void *nv_associative(register Namval_t *np,const char *sp,int mode) - { -+ Shell_t *shp = sh_getinterp(); - register struct assoc_array *ap = (struct assoc_array*)nv_arrayptr(np); - register int type; - switch(mode) -@@ -1674,6 +1691,7 @@ void *nv_associative(register Namval_t * - if(ap = (struct assoc_array*)calloc(1,sizeof(struct assoc_array))) - { - ap->header.table = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(ap->header.table,shp,1); - ap->cur = 0; - ap->pos = 0; - ap->header.hdr.disc = &array_disc; -@@ -1742,7 +1760,6 @@ void *nv_associative(register Namval_t * - case NV_ANAME: - if(ap->cur) - { -- Shell_t *shp = sh_getinterp(); - if(!shp->instance && nv_isnull(ap->cur)) - return(NIL(void*)); - return((void*)ap->cur->nvname); + if(!np->nvfun) +@@ -785,7 +791,7 @@ static void array_putval(Namval_t *np, c + if(np->nvalue.cp==Empty) + np->nvalue.cp = 0; + } +- if(!string && (flags&NV_TYPE)) ++ if(!string && (flags&NV_TYPE) && ap) + array_unscope(np,ap); + } + --- src/cmd/ksh93/sh/fault.c -+++ src/cmd/ksh93/sh/fault.c 2013-09-12 14:14:49.000000000 +0000 ++++ src/cmd/ksh93/sh/fault.c 2013-10-25 13:26:45.742247936 +0000 @@ -518,6 +518,8 @@ void sh_exit(register int xno) shp->exitval |= (sig=shp->lastsig); if(pp && pp->mode>1) @@ -590,74 +319,74 @@ #ifdef SIGTSTP if(shp->trapnote&SH_SIGTSTP) { ---- src/cmd/ksh93/sh/init.c -+++ src/cmd/ksh93/sh/init.c 2013-09-13 13:52:48.000000000 +0000 -@@ -1909,9 +1909,13 @@ static Init_t *nv_init(Shell_t *shp) - (OPTINDNOD)->nvalue.lp = (&shp->st.optindex); - /* set up the seconds clock */ - shp->alias_tree = inittree(shp,shtab_aliases); -+ dtuserdata(shp->alias_tree,shp,1); - shp->track_tree = dtopen(&_Nvdisc,Dtset); -+ dtuserdata(shp->track_tree,shp,1); - shp->bltin_tree = inittree(shp,(const struct shtable2*)shtab_builtins); -+ dtuserdata(shp->bltin_tree,shp,1); - shp->fun_tree = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(shp->fun_tree,shp,1); - dtview(shp->fun_tree,shp->bltin_tree); - nv_mount(DOTSHNOD, "type", shp->typedict=dtopen(&_Nvdisc,Dtoset)); - nv_adddisc(DOTSHNOD, shdiscnames, (Namval_t**)0); -@@ -1954,6 +1958,7 @@ static Dt_t *inittree(Shell_t *shp,const - nbltins = n; - } - base_treep = treep = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(treep,shp,1); - treep->user = (void*)shp; - for(tp=name_vals;*tp->sh_name;tp++,np++) - { --- src/cmd/ksh93/sh/io.c -+++ src/cmd/ksh93/sh/io.c 2013-09-17 17:08:41.000000000 +0000 -@@ -39,6 +39,7 @@ - #include "shnodes.h" - #include "history.h" - #include "edit.h" -+#include "builtins.h" - #include "timeout.h" - #include "FEATURE/externs" - #include "FEATURE/dynamic" -@@ -453,6 +454,8 @@ void sh_ioinit(Shell_t *shp) - sfnotify(sftrack); - sh_iostream(shp,0); - sh_iostream(shp,1); -+ /* sh_iostream(shp,2); --- ksh93u+ 2012-08-01 does not have a (io)vex to -+ restore sfstderr and close file descriptors */ - /* all write steams are in the same pool and share outbuff */ - shp->outpool = sfopen(NIL(Sfio_t*),NIL(char*),"sw"); /* pool identifier */ - shp->outbuff = (char*)malloc(IOBSIZE+4); -@@ -536,8 +539,12 @@ Sfio_t *sh_iostream(Shell_t *shp, regist ++++ src/cmd/ksh93/sh/io.c 2013-10-25 13:26:45.743247844 +0000 +@@ -407,7 +407,7 @@ int sh_iovalidfd(Shell_t *shp, int fd) + { + Sfio_t **sftable = shp->sftable; + int max,n, **fdptrs = shp->fdptrs; +- unsigned char *fdstatus = shp->fdstatus; ++ unsigned int *fdstatus = shp->fdstatus; + if(fd<0) + return(0); + if(fd < shp->gd->lim.open_max) +@@ -422,13 +422,13 @@ int sh_iovalidfd(Shell_t *shp, int fd) + if(n > max) + n = max; + max = shp->gd->lim.open_max; +- shp->sftable = (Sfio_t**)calloc((n+1)*(sizeof(int*)+sizeof(Sfio_t*)+1),1); ++ shp->sftable = (Sfio_t**)calloc((n+1)*(sizeof(int*)+sizeof(Sfio_t*)+sizeof(*fdstatus)),1); + if(max) + memcpy(shp->sftable,sftable,max*sizeof(Sfio_t*)); + shp->fdptrs = (int**)(&shp->sftable[n]); + if(max) + memcpy(shp->fdptrs,fdptrs,max*sizeof(int*)); +- shp->fdstatus = (unsigned char*)(&shp->fdptrs[n]); ++ shp->fdstatus = (unsigned int*)(&shp->fdptrs[n]); + if(max) + memcpy(shp->fdstatus,fdstatus,max); + if(sftable) +@@ -686,7 +686,10 @@ int sh_close(register int fd) + register Sfio_t *sp; + register int r = 0; + if(fd<0) ++ { ++ errno = EBADF; + return(-1); ++ } + if(fd >= shp->gd->lim.open_max) + sh_iovalidfd(shp,fd); + if(!(sp=shp->sftable[fd]) || sfclose(sp) < 0) +@@ -699,13 +702,15 @@ int sh_close(register int fd) } - if(status&IOREAD) - { -- if(!(bp = (char *)malloc(IOBSIZE+1))) -+ if(shp->bltinfun && shp->bltinfun!=b_read && shp->bltindata.bnode && !nv_isattr(shp->bltindata.bnode,BLT_SPC)) -+ bp = 0; -+ else if(!(bp = (char *)malloc(IOBSIZE+1))) - return(NIL(Sfio_t*)); -+ if(bp) -+ bp[IOBSIZE]=0; - flags |= SF_READ; - if(!(status&IOWRITE)) - flags &= ~SF_WRITE; -@@ -550,7 +557,8 @@ Sfio_t *sh_iostream(Shell_t *shp, regist - { - if(status&IOTTY) - sfset(iop,SF_LINE|SF_WCWIDTH,1); -- sfsetbuf(iop, bp, IOBSIZE); -+ if(bp) -+ sfsetbuf(iop, bp, IOBSIZE); - } - else if(!(iop=sfnew((fd<=2?iop:0),bp,IOBSIZE,fd,flags))) - return(NIL(Sfio_t*)); -@@ -964,7 +972,7 @@ int sh_pipe(register int pv[]) + if(fd>2) + shp->sftable[fd] = 0; ++ if(r = (shp->fdstatus[fd]>>8)) ++ close(r); + shp->fdstatus[fd] = IOCLOSE; + if(shp->fdptrs[fd]) + *shp->fdptrs[fd] = -1; + shp->fdptrs[fd] = 0; + if(fd < 10) + shp->inuse_bits &= ~(1<= shp->gd->lim.open_max) + sh_iovalidfd(shp,fdold); +- if(fdold<0 || fdold>2) ++ if(fdold<0 || fdold>9) + return(fdold); +- fdnew = sh_iomovefd(dup(fdold)); ++ fdnew = sh_iomovefd(sh_fcntl(fdold,F_DUPFD,10)); + shp->fdstatus[fdnew] = (shp->fdstatus[fdold]&~IOCLEX); + close(fdold); + shp->fdstatus[fdold] = IOCLOSE; +@@ -964,7 +969,7 @@ int sh_pipe(register int pv[]) while ((r=bind (pv[out], (struct sockaddr *) &sin, slen)) == -1 && errno==EADDRINUSE); if(r<0 || listen(pv[out],5) <0) { @@ -666,7 +395,7 @@ errormsg(SH_DICT,ERROR_system(1),e_pipe); } fcntl(pv[out],F_SETFD,FD_CLOEXEC); -@@ -1079,7 +1087,7 @@ static char *io_usename(char *name, int +@@ -1079,7 +1084,7 @@ static char *io_usename(char *name, int if((fd = sh_open(name,O_RDONLY,0)) >= 0) { r = fstat(fd,&statb); @@ -675,7 +404,7 @@ if(r) return(0); if(!S_ISREG(statb.st_mode)) -@@ -1144,6 +1152,7 @@ int sh_redirect(Shell_t *shp,struct iono +@@ -1144,6 +1149,7 @@ int sh_redirect(Shell_t *shp,struct iono char *tname=0, *after="", *trace = shp->st.trap[SH_DEBUGTRAP]; Namval_t *np=0; int isstring = shp->subshell?(sfset(sfstdout,0,0)&SF_STRING):0; @@ -683,7 +412,7 @@ if(flag==2) clexec = 1; -@@ -1245,16 +1254,35 @@ int sh_redirect(Shell_t *shp,struct iono +@@ -1245,16 +1251,35 @@ int sh_redirect(Shell_t *shp,struct iono { int dupfd,toclose= -1; io_op[2] = '&'; @@ -722,7 +451,7 @@ { message = e_file; goto fail; -@@ -1267,8 +1295,23 @@ int sh_redirect(Shell_t *shp,struct iono +@@ -1267,8 +1292,23 @@ int sh_redirect(Shell_t *shp,struct iono shp->subdup |= 1<_data, (size_t)last); @@ -747,7 +476,7 @@ if(dupfd!=1 && fn < 10) shp->subdup &= ~(1<fdstatus[fd] = (shp->fdstatus[dupfd]&~IOCLEX); if(toclose<0 && shp->fdstatus[fd]&IOREAD) shp->fdstatus[fd] |= IODUP; -@@ -1496,7 +1553,8 @@ int sh_redirect(Shell_t *shp,struct iono +@@ -1496,7 +1550,8 @@ int sh_redirect(Shell_t *shp,struct iono if(fn>9 || !(shp->inuse_bits&(1<sftable[fn],fn); } @@ -785,7 +514,7 @@ } if(flag==3) return(fd); -@@ -1531,7 +1589,24 @@ int sh_redirect(Shell_t *shp,struct iono +@@ -1531,7 +1586,24 @@ int sh_redirect(Shell_t *shp,struct iono shp->inuse_bits |= (1<fdstatus[fd] |= IOCLEX; -@@ -2059,9 +2134,11 @@ int sh_iocheckfd(Shell_t *shp, register +@@ -1619,12 +1691,12 @@ static int io_heredoc(Shell_t *shp,regis + sfclose(infile); + } + } ++ if(traceon && !(iop->iofile&IOSTRG)) ++ sfputr(sfstderr,iop->ioname,'\n'); + /* close stream outfile, but save file descriptor */ + fd = sffileno(outfile); + sfsetfd(outfile,-1); + sfclose(outfile); +- if(traceon && !(iop->iofile&IOSTRG)) +- sfputr(sfstderr,iop->ioname,'\n'); + lseek(fd,(off_t)0,SEEK_SET); + shp->fdstatus[fd] = IOREAD; + return(fd); +@@ -2059,9 +2131,11 @@ int sh_iocheckfd(Shell_t *shp, register if(!(n&(IOSEEK|IONOSEEK))) { struct stat statb; @@ -823,7 +567,7 @@ if(null_ino==0 && stat(e_devnull,&statb) >=0) { null_ino = statb.st_ino; -@@ -2097,6 +2174,7 @@ int sh_iocheckfd(Shell_t *shp, register +@@ -2097,6 +2171,7 @@ int sh_iocheckfd(Shell_t *shp, register n |= IONOSEEK; else n |= IOSEEK; @@ -831,7 +575,7 @@ } if(fd==0) n &= ~IOWRITE; -@@ -2143,6 +2221,7 @@ static int io_prompt(Shell_t *shp,Sfio_t +@@ -2143,6 +2218,7 @@ static int io_prompt(Shell_t *shp,Sfio_t } #endif /* TIOCLBIC */ cp = sh_mactry(shp,nv_getval(sh_scoped(shp,PS1NOD))); @@ -839,8 +583,42 @@ for(;c= *cp;cp++) { if(c==HIST_CHAR) +@@ -2494,12 +2570,14 @@ skip: + */ + ssize_t sh_read(register int fd, void* buff, size_t n) + { ++ int r,err=errno; + Shell_t *shp = sh_getinterp(); + register Sfio_t *sp; + if(sp=shp->sftable[fd]) + return(sfread(sp,buff,n)); +- else +- return(read(fd,buff,n)); ++ while ((r=read(fd,buff,n))<0 && errno==EINTR) ++ errno = err; ++ return(r); + } + + #undef write +@@ -2508,12 +2586,14 @@ ssize_t sh_read(register int fd, void* b + */ + ssize_t sh_write(register int fd, const void* buff, size_t n) + { ++ int r,err=errno; + Shell_t *shp = sh_getinterp(); + register Sfio_t *sp; + if(sp=shp->sftable[fd]) + return(sfwrite(sp,buff,n)); +- else +- return(write(fd,buff,n)); ++ while ((r=write(fd,buff,n))<0 && errno==EINTR) ++ errno = err; ++ return(r); + } + + #undef lseek --- src/cmd/ksh93/sh/jobs.c -+++ src/cmd/ksh93/sh/jobs.c 2013-09-16 14:18:07.000000000 +0000 ++++ src/cmd/ksh93/sh/jobs.c 2013-10-25 13:26:45.744247751 +0000 @@ -424,6 +424,8 @@ int job_reap(register int sig) } if(pid<=0) @@ -863,6 +641,15 @@ else shp->trapnote |= SH_SIGTRAP; } +@@ -646,7 +653,7 @@ void job_init(Shell_t *shp, int lflag) + return; + while(close(JOBTTY)<0 && errno==EINTR) + errno = err; +- if((fd = open(ttynam,O_RDWR)) <0) ++ if((fd = sh_open(ttynam,O_RDWR)) <0) + return; + if(fd!=JOBTTY) + sh_iorenumber(shp,fd,JOBTTY); @@ -1313,6 +1320,7 @@ int job_post(Shell_t *shp,pid_t pid, pid return(0); } @@ -904,7 +691,7 @@ #endif /* SHOPT_BGX */ for(; pw && (pw->p_flag&P_DONE)&&(notify||!(pw->p_flag&P_NOTIFY)||pw->p_env); pw=pw->p_nxtproc); --- src/cmd/ksh93/sh/lex.c -+++ src/cmd/ksh93/sh/lex.c 2013-09-13 19:12:25.000000000 +0000 ++++ src/cmd/ksh93/sh/lex.c 2013-10-25 13:26:45.744247751 +0000 @@ -556,7 +556,7 @@ int sh_lex(Lex_t* lp) lp->lexd.docword=1; else if(n==LPAREN) @@ -914,8 +701,17 @@ return(c); lp->lexd.nest=1; lp->lastline = shp->inlineno; +@@ -2468,7 +2468,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; + } --- src/cmd/ksh93/sh/macro.c -+++ src/cmd/ksh93/sh/macro.c 2013-09-13 18:46:30.000000000 +0000 ++++ src/cmd/ksh93/sh/macro.c 2013-10-25 13:26:45.745247659 +0000 @@ -392,7 +392,7 @@ void sh_machere(Shell_t *shp,Sfio_t *inf break; } @@ -925,7 +721,48 @@ break; case S_EOF: if((c=fcfill()) > 0) -@@ -1166,7 +1166,7 @@ retry1: +@@ -447,6 +447,7 @@ static void copyto(register Mac_t *mp,in + int ansi_c = 0; + int paren = 0; + int ere = 0; ++ int dotdot = 0; + int brace = 0; + Sfio_t *sp = mp->sp; + Stk_t *stkp = mp->shp->stk; +@@ -846,7 +847,7 @@ e_badsubscript,*cp); + { + sfwrite(stkp,first,c); + sfputc(stkp,0); +- mp->dotdot = stktell(stkp); ++ dotdot = stktell(stkp); + cp = first = fcseek(c+2); + } + break; +@@ -854,6 +855,7 @@ e_badsubscript,*cp); + } + done: + mp->sp = sp; ++ mp->dotdot = dotdot; + mp->quote = oldquote; + } + +@@ -1010,7 +1012,6 @@ static int subcopy(Mac_t *mp, int flag) + mp->pattern = flag?4:0; + mp->arrayok=1; + mp->subcopy++; +- mp->dotdot = 0; + copyto(mp,RBRACT,0); + mp->subcopy = 0; + mp->pattern = xpattern; +@@ -1099,6 +1100,7 @@ static int varsub(Mac_t *mp) + Stk_t *stkp = mp->shp->stk; + retry1: + mp->zeros = 0; ++ mp->dotdot = 0; + idbuff[0] = 0; + idbuff[1] = 0; + c = fcmbget(&LEN); +@@ -1166,7 +1168,7 @@ retry1: case S_PAR: if(type) goto nosub; @@ -934,7 +771,7 @@ return(1); case S_DIG: var = 0; -@@ -1349,7 +1349,7 @@ retry1: +@@ -1349,7 +1351,7 @@ retry1: ap = nv_arrayptr(np=nq); if(ap) { @@ -943,7 +780,7 @@ v = stkptr(stkp,mp->dotdot); dolmax =1; if(array_assoc(ap)) -@@ -2077,6 +2077,18 @@ static void comsubst(Mac_t *mp,register +@@ -2077,6 +2079,18 @@ static void comsubst(Mac_t *mp,register fcrestore(&save); return; } @@ -962,32 +799,19 @@ } else { -@@ -2158,10 +2170,22 @@ static void comsubst(Mac_t *mp,register +@@ -2158,10 +2172,9 @@ static void comsubst(Mac_t *mp,register mp->ifsp = nv_getval(np); stkset(stkp,savptr,savtop); newlines = 0; - sfsetbuf(sp,(void*)sp,0); - bufsize = sfvalue(sp); -+ if(type==3 && mp->shp->spid) -+ { -+ c = mp->shp->exitval; -+ job_wait(mp->shp->spid); -+ if(mp->shp->exitval==ERROR_NOENT) -+ { -+ mp->shp->exitval = c; -+ mp->shp->savexit=mp->shp->exitval; -+ } -+ if(mp->shp->pipepid==mp->shp->spid) -+ mp->shp->spid = 0; -+ mp->shp->pipepid = 0; -+ } /* read command substitution output and put on stack or here-doc */ sfpool(sp, NIL(Sfio_t*), SF_WRITE); + sfset(sp, SF_WRITE|SF_PUBLIC|SF_SHARE,0); sh_offstate(SH_INTERACTIVE); if((foff = sfseek(sp,(Sfoff_t)0,SEEK_END)) > 0) { -@@ -2170,6 +2194,8 @@ static void comsubst(Mac_t *mp,register +@@ -2170,6 +2183,8 @@ static void comsubst(Mac_t *mp,register stkseek(stkp,soff+foff+64); stkseek(stkp,soff); } @@ -996,7 +820,7 @@ while((str=(char*)sfreserve(sp,SF_UNBOUND,0)) && (c=bufsize=sfvalue(sp))>0) { #if SHOPT_CRNL -@@ -2291,6 +2317,13 @@ static void mac_copy(register Mac_t *mp, +@@ -2291,6 +2306,13 @@ static void mac_copy(register Mac_t *mp, Stk_t *stkp=mp->shp->stk; int oldpat = mp->pattern; nopat = (mp->quote||(mp->assign==1)||mp->arith); @@ -1010,19 +834,8 @@ if(mp->zeros) { /* prevent leading 0's from becomming octal constants */ -@@ -2742,7 +2775,10 @@ static char *sh_tilde(Shell_t *shp,regis - skip: - #endif /* _WINIX */ - if(!logins_tree) -+ { - logins_tree = dtopen(&_Nvdisc,Dtbag); -+ dtuserdata(logins_tree,shp,1); -+ } - if(np=nv_search(string,logins_tree,NV_ADD)) - { - c = shp->subshell; --- src/cmd/ksh93/sh/main.c -+++ src/cmd/ksh93/sh/main.c 2013-09-13 12:07:49.000000000 +0000 ++++ src/cmd/ksh93/sh/main.c 2013-10-25 13:26:45.745247659 +0000 @@ -309,7 +309,7 @@ int sh_main(int ac, char *av[], Shinit_f int isdir = 0; if((fdin=sh_open(name,O_RDONLY,0))>=0 &&(fstat(fdin,&statb)<0 || S_ISDIR(statb.st_mode))) @@ -1033,42 +846,8 @@ fdin = -1; } --- src/cmd/ksh93/sh/name.c -+++ src/cmd/ksh93/sh/name.c 2013-09-16 16:00:12.000000000 +0000 -@@ -291,7 +291,7 @@ struct argnod *nv_onlist(struct argnod * - * Perform parameter assignment for a linked list of parameters - * contains attributes for the parameters - */ --void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ) -+Namval_t ** nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ) - { - Shell_t *shp = sh_getinterp(); - register char *cp; -@@ -301,7 +301,7 @@ void nv_setlist(register struct argnod * - int traceon = (sh_isoption(SH_XTRACE)!=0); - int array = (flags&(NV_ARRAY|NV_IARRAY)); - Namarr_t *ap; -- Namval_t node; -+ Namval_t node, **nodelist=0, **nlp=0; - struct Namref nr; - #if SHOPT_TYPEDEF - int maketype = flags&NV_TYPE; -@@ -330,6 +330,15 @@ void nv_setlist(register struct argnod * - } - else - shp->prefix_root = shp->first_root = 0; -+ if(flags&NV_DECL) -+ { -+ struct argnod *ap; -+ int n=0; -+ for(ap=arg;ap; ap=ap->argnxt.ap) -+ n++; -+ nlp = nodelist = (Namval_t**)stakalloc((n+1)*sizeof(Namval_t*)); -+ nodelist[n] = 0; -+ } - for(;arg; arg=arg->argnxt.ap) - { - shp->used_pos = 0; -@@ -421,6 +430,8 @@ void nv_setlist(register struct argnod * ++++ src/cmd/ksh93/sh/name.c 2013-10-25 13:26:45.746247567 +0000 +@@ -421,6 +421,8 @@ void nv_setlist(register struct argnod * if(array&NV_ARRAY) { nv_setarray(np,nv_associative); @@ -1077,7 +856,7 @@ } else { -@@ -436,7 +447,7 @@ void nv_setlist(register struct argnod * +@@ -436,7 +438,7 @@ void nv_setlist(register struct argnod * #endif /* SHOPT_TYPEDEF */ } /* check for array assignment */ @@ -1086,7 +865,7 @@ { int argc; Dt_t *last_root = shp->last_root; -@@ -509,6 +520,7 @@ void nv_setlist(register struct argnod * +@@ -509,6 +511,7 @@ void nv_setlist(register struct argnod * if(!(array&NV_IARRAY) && !(tp->com.comset->argflag&ARG_MESSAGE)) nv_setarray(np,nv_associative); } @@ -1094,34 +873,7 @@ nv_setlist(tp->com.comset,flags&~NV_STATIC,0); shp->prefix = prefix; if(tp->com.comset->argval[1]!='[') -@@ -682,6 +694,7 @@ void nv_setlist(register struct argnod * - } - #endif /* SHOPT_TYPEDEF */ - } -+ return(nodelist); - } - - /* -@@ -821,6 +834,7 @@ Namval_t *nv_create(const char *name, D - { - Dt_t *dp = dtview(shp->var_tree,(Dt_t*)0); - rp->sdict = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(rp->sdict,shp,1); - dtview(rp->sdict,dp); - dtview(shp->var_tree,rp->sdict); - } -@@ -1170,7 +1184,10 @@ Namval_t *nv_create(const char *name, D - ap = nv_arrayptr(np); - } - if(n && ap && !ap->table) -+ { - ap->table = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(ap->table,shp,1); -+ } - if(ap && ap->table && (nq=nv_search(sub,ap->table,n))) - nq->nvenv = (char*)np; - if(nq && nv_isnull(nq)) -@@ -1288,8 +1305,9 @@ void nv_delete(Namval_t* np, Dt_t *root, +@@ -1292,8 +1295,9 @@ void nv_delete(Namval_t* np, Dt_t *root, if(rp->sub) free(rp->sub); rp->sub = 0; @@ -1133,7 +885,7 @@ } } } -@@ -1341,10 +1359,12 @@ Namval_t *nv_open(const char *name, Dt_t +@@ -1345,10 +1349,12 @@ Namval_t *nv_open(const char *name, Dt_t struct Cache_entry *xp; #endif @@ -1147,24 +899,7 @@ if(!root) root = shp->var_tree; shp->last_root = root; -@@ -1391,7 +1411,7 @@ Namval_t *nv_open(const char *name, Dt_t - while((c= *(unsigned char*)cp++) && (c!='=') && (c!='/') && - (c>=0x200 || !(c=sh_lexstates[ST_NORM][c]) || c==S_EPAT || c==S_COLON)); - if(shp->subshell && c=='=') -- root = sh_subaliastree(1); -+ root = sh_subaliastree(shp,1); - if(c= *--cp) - *cp = 0; - np = nv_search(name, root, (flags&NV_NOADD)?0:NV_ADD); -@@ -2350,6 +2370,7 @@ void sh_scope(Shell_t *shp, struct argno - newroot = nv_dict(shp->namespace); - #endif /* SHOPT_NAMESPACE */ - newscope = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(newscope,shp,1); - if(envlist) - { - dtview(newscope,(Dt_t*)shp->var_tree); -@@ -2465,6 +2486,8 @@ static void table_unset(Shell_t *shp, re +@@ -2470,6 +2476,8 @@ static void table_unset(Shell_t *shp, re } } npnext = (Namval_t*)dtnext(root,np); @@ -1173,16 +908,7 @@ _nv_unset(np,flags); nv_delete(np,root,0); } -@@ -2533,7 +2556,7 @@ void _nv_unset(register Namval_t *np,int - } - dtclose(rp->sdict); - } -- stakdelete(slp->slptr); -+ sfclose(slp->slptr); - free((void*)np->nvalue.ip); - np->nvalue.ip = 0; - } -@@ -2547,9 +2570,11 @@ void _nv_unset(register Namval_t *np,int +@@ -2552,9 +2560,11 @@ void _nv_unset(register Namval_t *np,int /* This function contains disc */ if(!nv_local) { @@ -1194,7 +920,7 @@ return; } /* called from disc, assign the actual value */ -@@ -2570,7 +2595,7 @@ void _nv_unset(register Namval_t *np,int +@@ -2575,7 +2585,7 @@ void _nv_unset(register Namval_t *np,int { if(np->nvalue.nrp->root) @@ -1203,18 +929,7 @@ if(np->nvalue.nrp->sub) free(np->nvalue.nrp->sub); free((void*)np->nvalue.nrp); -@@ -3334,7 +3359,10 @@ int nv_rename(register Namval_t *np, int - if(ap=nv_arrayptr(np)) - { - if(!ap->table) -+ { - ap->table = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(ap->table,shp,1); -+ } - if(ap->table) - mp = nv_search(nv_getsub(np),ap->table,NV_ADD); - nv_arraychild(np,mp,0); -@@ -3569,7 +3597,7 @@ void nv_unref(register Namval_t *np) +@@ -3577,7 +3587,7 @@ void nv_unref(register Namval_t *np) { if(np->nvalue.nrp->sub) free(np->nvalue.nrp->sub); @@ -1223,62 +938,8 @@ } free((void*)np->nvalue.nrp); np->nvalue.cp = strdup(nv_name(nq)); ---- src/cmd/ksh93/sh/nvdisc.c -+++ src/cmd/ksh93/sh/nvdisc.c 2013-09-13 14:34:31.000000000 +0000 -@@ -246,6 +246,7 @@ static void chktfree(register Namval_t * - */ - static void assign(Namval_t *np,const char* val,int flags,Namfun_t *handle) - { -+ Shell_t *shp = sh_getinterp(); - int type = (flags&NV_APPEND)?APPEND:ASSIGN; - register struct vardisc *vp = (struct vardisc*)handle; - register Namval_t *nq = vp->disc[type]; -@@ -330,7 +331,7 @@ static void assign(Namval_t *np,const ch - } - else if(!nq || !isblocked(bp,type)) - { -- Dt_t *root = sh_subfuntree(1); -+ Dt_t *root = sh_subfuntree(shp,1); - int n; - Namarr_t *ap; - block(bp,type); -@@ -1225,7 +1226,10 @@ Namval_t *sh_addbuiltin(const char *path - if(np->nvenv) - dtdelete(sh.bltin_tree,np); - if(extra == (void*)1) -+ { -+ dtdelete(sh.bltin_tree,np); - return(0); -+ } - np = 0; - } - break; -@@ -1296,6 +1300,7 @@ static Namfun_t *clone_table(Namval_t* n - Dt_t *oroot=tp->dict,*nroot=dtopen(&_Nvdisc,Dtoset); - if(!nroot) - return(0); -+ dtuserdata(nroot,dtuserdata(oroot,0,0),1); - memcpy((void*)ntp,(void*)fp,sizeof(struct table)); - ntp->dict = nroot; - ntp->parent = nv_lastdict(); -@@ -1437,6 +1442,7 @@ Namval_t *nv_mount(Namval_t *np, const c - { - Namval_t *mp, *pp; - struct table *tp; -+ dtuserdata(dict,sh_getinterp(),1); - if(nv_hasdisc(np,&table_disc)) - pp = np; - else -@@ -1493,6 +1499,6 @@ Namval_t *sh_fsearch(Shell_t *shp, const - sfputr(stkp,nv_name(shp->namespace),'.'); - sfputr(stkp,fname,0); - fname = stkptr(stkp,offset); -- return(nv_search(fname,sh_subfuntree(add&NV_ADD),add)); -+ return(nv_search(fname,sh_subfuntree(shp,add&NV_ADD),add)); - } - #endif /* SHOPT_NAMESPACE */ --- src/cmd/ksh93/sh/nvtree.c -+++ src/cmd/ksh93/sh/nvtree.c 2013-09-16 15:37:34.000000000 +0000 ++++ src/cmd/ksh93/sh/nvtree.c 2013-10-25 13:26:45.747247475 +0000 @@ -144,8 +144,9 @@ static Namfun_t *nextdisc(Namval_t *np) void *nv_diropen(Namval_t *np,const char *name) @@ -1287,105 +948,11 @@ - int c,len=strlen(name); + const char *last; + char *next; -+ size_t c,len=strlen(name); ++ size_t c=0,len=strlen(name); struct nvdir *save, *dp = new_of(struct nvdir,len+1); Namval_t *nq=0,fake; Namfun_t *nfp=0; -@@ -160,7 +161,10 @@ void *nv_diropen(Namval_t *np,const char - dp->len = len; - dp->root = sh.last_root?sh.last_root:sh.var_tree; - #if 1 -- while(1) -+ last = &name[len]; -+ if(!np) -+ np = nv_search(name,dp->root,0); -+ if(!np || !nv_isvtree(np)) while(1) - { - dp->table = sh.last_table; - sh.last_table = 0; -@@ -188,7 +192,7 @@ void *nv_diropen(Namval_t *np,const char - { - char *cp = nv_name(dp->hp); - c = strlen(cp); -- if(memcmp(name,cp,c) || name[c]!='[') -+ if(strncmp(name,cp,c) || name[c]!='[') - dp->hp = (Namval_t*)dtnext(dp->root,dp->hp); - else - { -@@ -266,7 +270,7 @@ static Namval_t *nextnode(struct nvdir * - { - if(dp->nextnode) - return((*dp->nextnode)(dp->hp,dp->root,dp->fun)); -- if(dp->len && memcmp(dp->data, dp->hp->nvname, dp->len)) -+ if(dp->len && strncmp(dp->data, dp->hp->nvname, dp->len)) - return(0); - return((Namval_t*)dtnext(dp->root,dp->hp)); - } -@@ -311,7 +315,7 @@ char *nv_dirnext(void *dir) - dp->hp = (*dp->nextnode)(np,(Dt_t*)0,dp->fun); - } - sh.last_table = last_table; -- if(!dp->len || memcmp(cp,dp->data,dp->len)==0) -+ if(!dp->len || strncmp(cp,dp->data,dp->len)==0) - { - if((nfp=nextdisc(np)) && (nfp->disc->getval||nfp->disc->getnum) && nv_isvtree(np) && strcmp(cp,dp->data)) - nfp = 0; -@@ -703,6 +707,7 @@ static void outval(char *name, const cha - if(!(np=nv_open(vname,wp->root,mode|NV_VARNAME|NV_NOADD|NV_NOASSIGN|NV_NOFAIL|wp->noscope))) - { - wp->shp->last_table = last_table; -+ wp->flags &= ~NV_COMVAR; - return; - } - if(!wp->out) -@@ -739,8 +744,20 @@ static void outval(char *name, const cha - break; - } - if(!xp) -+ { -+ if(nv_type(np) || !(wp->flags&NV_COMVAR)) -+ { -+ wp->flags &= ~NV_COMVAR; -+ return; -+ } -+ if(wp->indent>0) -+ sfnputc(wp->out,'\t',wp->indent); -+ nv_attribute(np,wp->out,"typeset",' '); -+ sfputr(wp->out,name,wp->indent>0?'\n':-1); - return; -+ } - } -+ wp->flags &= ~NV_COMVAR; - if(nv_isnull(np) && !nv_isarray(np) && !nv_isattr(np,NV_INTEGER)) - return; - if(special || (nv_isarray(np) && nv_arrayptr(np))) -@@ -927,6 +944,17 @@ static char **genvalue(char **argv, cons - } - else - { -+ if(n && *cp && cp[-1]!='.' && cp[-1]!='[') -+ break; -+ if(outfile && wp->indent<0 && (wp->flags&NV_COMVAR)) -+ sfputc(outfile,';'); -+ wp->flags |= NV_COMVAR; -+ if(argv[1]) -+ { -+ ssize_t r = (cp-argv[0]) + strlen(cp); -+ if(argv[1][r]=='.' && strncmp(argv[0],argv[1],r)==0) -+ wp->flags &= ~NV_COMVAR; -+ } - outval(cp,arg,wp); - if(wp->array) - { -@@ -943,6 +971,7 @@ static char **genvalue(char **argv, cons - wp->nofollow = 0; - } - wp->array = 0; -+ wp->flags &= ~NV_COMVAR; - if(outfile) - { - int c = prefix[m-1]; -@@ -1031,9 +1060,18 @@ static char *walk_tree(register Namval_t +@@ -1031,9 +1032,18 @@ static char *walk_tree(register Namval_t shp->var_tree = dp; if(nq && mq) { @@ -1405,7 +972,7 @@ continue; } --- src/cmd/ksh93/sh/nvtype.c -+++ src/cmd/ksh93/sh/nvtype.c 2013-09-17 13:37:34.000000000 +0000 ++++ src/cmd/ksh93/sh/nvtype.c 2013-10-25 13:26:45.747247475 +0000 @@ -484,7 +484,10 @@ static Namfun_t *clone_type(Namval_t* np } } @@ -1418,7 +985,7 @@ dp->strsize = -pp->strsize; return(&dp->fun); --- src/cmd/ksh93/sh/parse.c -+++ src/cmd/ksh93/sh/parse.c 2013-09-13 16:21:49.000000000 +0000 ++++ src/cmd/ksh93/sh/parse.c 2013-10-25 13:26:45.748247383 +0000 @@ -1722,6 +1722,7 @@ static struct ionod *inout(Lex_t *lexp,s lexp->digits=0; iop=(struct ionod*) stkalloc(stkp,sizeof(struct ionod)); @@ -1428,17 +995,18 @@ { if(token==RPAREN && (iof&IOLSEEK) && lexp->comsub) --- src/cmd/ksh93/sh/path.c -+++ src/cmd/ksh93/sh/path.c 2013-09-17 13:49:01.000000000 +0000 -@@ -592,7 +592,7 @@ static void funload(Shell_t *shp,int fno - pname = path_fullname(shp,stakptr(PATH_OFFSET)); - if(shp->fpathdict && (rp = dtmatch(shp->fpathdict,(void*)pname))) - { -- Dt_t *funtree = sh_subfuntree(1); -+ Dt_t *funtree = sh_subfuntree(shp,1); - while(1) ++++ src/cmd/ksh93/sh/path.c 2013-10-25 13:27:42.151044203 +0000 +@@ -333,7 +333,8 @@ static char *path_lib(Shell_t *shp,Pathc + char save[8]; + for( ;pp; pp=pp->next) { - rpfirst = dtprev(shp->fpathdict,rp); -@@ -613,6 +613,7 @@ static void funload(Shell_t *shp,int fno +- path_checkdup(shp,pp); ++ if(!pp->dev && !pp->ino) ++ path_checkdup(shp,pp); + if(pp->ino==statb.st_ino && pp->dev==statb.st_dev && pp->mtime==statb.st_mtime) + return(pp->lib); + } +@@ -613,6 +614,7 @@ static void funload(Shell_t *shp,int fno } while((rp=dtnext(shp->fpathdict,rp)) && strcmp(pname,rp->fname)==0); sh_close(fno); @@ -1446,26 +1014,16 @@ return; } sh_onstate(SH_NOLOG); -@@ -868,15 +869,15 @@ Pathcomp_t *path_absolute(Shell_t *shp,r - if(isfun && f>=0 && (cp = strrchr(name,'.'))) +@@ -876,7 +878,7 @@ Pathcomp_t *path_absolute(Shell_t *shp,r { - *cp = 0; -- if(nv_open(name,sh_subfuntree(1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE)) -+ if(nv_open(name,sh_subfuntree(shp,1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE)) - f = -1; - *cp = '.'; - } - if(isfun && f>=0) - { -- nv_onattr(nv_open(name,sh_subfuntree(1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE),NV_LTOU|NV_FUNCTION); -+ nv_onattr(nv_open(name,sh_subfuntree(shp,1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE),NV_LTOU|NV_FUNCTION); + nv_onattr(nv_open(name,sh_subfuntree(1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE),NV_LTOU|NV_FUNCTION); funload(shp,f,name); - close(f); + sh_close(f); f = -1; return(0); } -@@ -1408,7 +1409,7 @@ static void exscript(Shell_t *shp,regist +@@ -1408,7 +1410,7 @@ static void exscript(Shell_t *shp,regist sabuf.ac_etime = compress( (time_t)(after-before)); fd = open( SHACCT , O_WRONLY | O_APPEND | O_CREAT,RW_ALL); write(fd, (const char*)&sabuf, sizeof( sabuf )); @@ -1475,7 +1033,7 @@ } --- src/cmd/ksh93/sh/streval.c -+++ src/cmd/ksh93/sh/streval.c 2013-09-17 15:21:23.000000000 +0000 ++++ src/cmd/ksh93/sh/streval.c 2013-10-25 13:26:45.749247290 +0000 @@ -165,14 +165,11 @@ Sfdouble_t arith_exec(Arith_t *ep) Math_f fun; struct lval node; @@ -1493,7 +1051,7 @@ { arith_error(e_recursive,ep->expr,ep->emode); --- src/cmd/ksh93/sh/subshell.c -+++ src/cmd/ksh93/sh/subshell.c 2013-09-17 15:12:00.000000000 +0000 ++++ src/cmd/ksh93/sh/subshell.c 2013-10-25 13:26:45.749247290 +0000 @@ -122,23 +122,26 @@ void sh_subtmpfile(Shell_t *shp) register struct checkpt *pp = (struct checkpt*)shp->jmplist; register struct subshell *sp = subshell_data->pipe; @@ -1534,7 +1092,15 @@ pid_t pid; char *trap = shp->st.trapcom[0]; if(trap) -@@ -213,7 +216,7 @@ void sh_subfork(void) +@@ -204,6 +207,7 @@ void sh_subfork(void) + { + /* this is the child part of the fork */ + /* setting subpid to 1 causes subshell to exit when reached */ ++ shp->cpid = 0; + sh_onstate(SH_FORKED); + sh_onstate(SH_NOLOG); + sh_offoption(SH_MONITOR); +@@ -213,7 +217,7 @@ void sh_subfork(void) shp->comsub = 0; SH_SUBSHELLNOD->nvalue.s = 0; sp->subpid=0; @@ -1543,7 +1109,7 @@ shp->savesig = 0; } } -@@ -337,7 +340,7 @@ static void nv_restore(struct subshell * +@@ -337,7 +341,7 @@ static void nv_restore(struct subshell * } nv_setsize(mp,nv_size(np)); if(!(flags&NV_MINIMAL)) @@ -1552,41 +1118,7 @@ if(!nofree) mp->nvfun = np->nvfun; if(nv_isattr(np,NV_IDENT)) -@@ -379,7 +382,7 @@ static void nv_restore(struct subshell * - * return pointer to alias tree - * create new one if in a subshell and one doesn't exist and create is non-zero - */ --Dt_t *sh_subaliastree(int create) -+Dt_t *sh_subaliastree(Shell_t *shp,int create) - { - register struct subshell *sp = subshell_data; - if(!sp || sp->shp->curenv==0) -@@ -387,6 +390,7 @@ Dt_t *sh_subaliastree(int create) - if(!sp->salias && create) - { - sp->salias = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(sp->salias,shp,1); - dtview(sp->salias,sp->shp->alias_tree); - sp->shp->alias_tree = sp->salias; - } -@@ -397,7 +401,7 @@ Dt_t *sh_subaliastree(int create) - * return pointer to function tree - * create new one if in a subshell and one doesn't exist and create is non-zero - */ --Dt_t *sh_subfuntree(int create) -+Dt_t *sh_subfuntree(Shell_t *shp,int create) - { - register struct subshell *sp = subshell_data; - if(!sp || sp->shp->curenv==0) -@@ -405,6 +409,7 @@ Dt_t *sh_subfuntree(int create) - if(!sp->sfun && create) - { - sp->sfun = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(sp->sfun,shp,1); - dtview(sp->sfun,sp->shp->fun_tree); - sp->shp->fun_tree = sp->sfun; - } -@@ -492,6 +497,8 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ +@@ -494,6 +498,8 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ subenv = 0; } shp->curenv = ++subenv; @@ -1595,7 +1127,7 @@ savst = shp->st; sh_pushcontext(shp,&buff,SH_JMPSUB); subshell = shp->subshell+1; -@@ -506,6 +513,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ +@@ -508,6 +514,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ sp->options = shp->options; sp->jobs = job_subsave(); sp->subdup = shp->subdup; @@ -1603,7 +1135,7 @@ #if SHOPT_COSHELL sp->coshell = shp->coshell; shp->coshell = 0; -@@ -528,7 +536,9 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ +@@ -530,7 +537,9 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ job.curpgid = 0; sp->subshare = shp->subshare; sp->comsub = shp->comsub; @@ -1614,7 +1146,7 @@ if(comsub) shp->comsub = comsub; if(!comsub || !shp->subshare) -@@ -602,7 +612,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ +@@ -604,7 +613,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ sp->tmpfd = -1; sp->pipefd = -1; /* use sftmp() file for standard output */ @@ -1623,7 +1155,35 @@ { sfswap(sp->saveout,sfstdout); errormsg(SH_DICT,ERROR_system(1),e_tmpcreate); -@@ -688,19 +698,27 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ +@@ -639,6 +648,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + sh_popcontext(shp,&buff); + if(shp->subshell==0) /* must be child process */ + { ++ shp->st.trapcom[0] = 0; + subshell_data = sp->prev; + if(jmpval==SH_JMPSCRIPT) + siglongjmp(*shp->jmplist,jmpval); +@@ -664,6 +674,19 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + } + else + { ++ if(comsub!=1 && shp->spid) ++ { ++ int c = shp->exitval; ++ job_wait(shp->spid); ++ if(shp->exitval==ERROR_NOENT) ++ { ++ shp->exitval = c; ++ shp->savexit=shp->exitval; ++ } ++ 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) +@@ -690,19 +713,27 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ } sfset(iop,SF_READ,1); } @@ -1655,15 +1215,27 @@ job_subrestore(sp->jobs); shp->jobenv = savecurenv; job.curpgid = savejobpgid; -@@ -776,7 +794,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ +@@ -764,8 +795,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) +@@ -777,8 +806,9 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ + shp->cpipe[1] = sp->cpipe; shp->coutpipe = sp->coutpipe; } ++ if(sp->pwdclose) ++ close(sp->pwdfd); shp->subshare = sp->subshare; - shp->comsub = sp->comsub; shp->subdup = sp->subdup; #if SHOPT_COSHELL shp->coshell = sp->coshell; -@@ -806,7 +823,12 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ +@@ -808,7 +838,12 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_ if(nsig>0) kill(getpid(),nsig); if(sp->subpid) @@ -1677,7 +1249,7 @@ sfseek(iop,(off_t)0,SEEK_SET); if(shp->trapnote) --- src/cmd/ksh93/sh/xec.c -+++ src/cmd/ksh93/sh/xec.c 2013-09-13 18:27:02.000000000 +0000 ++++ src/cmd/ksh93/sh/xec.c 2013-10-25 13:29:00.390826813 +0000 @@ -102,26 +102,30 @@ struct funenv * temp file. */ @@ -1805,18 +1377,20 @@ open(e_devnull,O_RDONLY); shp->offsets[0] = -1; shp->offsets[1] = 0; -@@ -1207,7 +1222,9 @@ int sh_exec(register const Shnode_t *t, - if(OPTIMIZE) - flgs |= NV_TAGGED; - #endif -- nv_setlist(argp,flgs,tp); -+ if (np && nv_isattr(np,BLT_DCL)) -+ flgs |= NV_DECL; -+ shp->nodelist = nv_setlist(argp,flgs,tp); - if(np==shp->typeinit) - shp->typeinit = 0; - shp->envlist = argp; -@@ -1570,7 +1587,7 @@ int sh_exec(register const Shnode_t *t, +@@ -1434,7 +1449,11 @@ int sh_exec(register const Shnode_t *t, + stat(".",&stata); + /* restore directory changed */ + if(statb.st_ino!=stata.st_ino || statb.st_dev!=stata.st_dev) +- chdir(shp->pwd); ++ { ++ int err=errno; ++ while((chdir(shp->pwd) < 0) && errno==EINTR) ++ errno = err; ++ } + } + sh_offstate(SH_STOPOK); + if(share&SF_SHARE) +@@ -1570,7 +1589,7 @@ int sh_exec(register const Shnode_t *t, unset_instance(nq,&node,&nr,mode); sh_funstaks(slp->slchild,-1); stakdelete(slp->slptr); @@ -1825,7 +1399,7 @@ siglongjmp(*shp->jmplist,jmpval); goto setexit; } -@@ -1597,10 +1614,14 @@ int sh_exec(register const Shnode_t *t, +@@ -1597,10 +1616,14 @@ int sh_exec(register const Shnode_t *t, if(shp->subshell) { sh_subtmpfile(shp); @@ -1843,7 +1417,7 @@ } no_fork = !ntflag && !(type&(FAMP|FPOU)) && !shp->subshell && !(shp->st.trapcom[SIGINT] && *shp->st.trapcom[SIGINT]) && -@@ -1676,7 +1697,7 @@ int sh_exec(register const Shnode_t *t, +@@ -1676,7 +1699,7 @@ int sh_exec(register const Shnode_t *t, if(parent<0) { if(shp->comsub==1 && usepipe && unpipe) @@ -1852,7 +1426,7 @@ break; } #else -@@ -1693,7 +1714,7 @@ int sh_exec(register const Shnode_t *t, +@@ -1693,7 +1716,7 @@ int sh_exec(register const Shnode_t *t, if(parent<0) { if(shp->comsub==1 && usepipe && unpipe) @@ -1861,7 +1435,7 @@ break; } #else -@@ -1715,6 +1736,8 @@ int sh_exec(register const Shnode_t *t, +@@ -1715,6 +1738,8 @@ int sh_exec(register const Shnode_t *t, nlock--; job_unlock(); } @@ -1870,8 +1444,15 @@ if(type&FPCL) sh_close(shp->inpipe[0]); if(type&(FCOOP|FAMP)) -@@ -1733,8 +1756,8 @@ int sh_exec(register const Shnode_t *t, +@@ -1730,11 +1755,15 @@ 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) @@ -1881,7 +1462,7 @@ if(!sh_isoption(SH_MONITOR)) { shp->trapnote &= ~SH_SIGIGNORE; -@@ -1906,8 +1929,8 @@ int sh_exec(register const Shnode_t *t, +@@ -1906,8 +1935,8 @@ int sh_exec(register const Shnode_t *t, { was_interactive = sh_isstate(SH_INTERACTIVE); sh_offstate(SH_INTERACTIVE); @@ -1891,7 +1472,7 @@ sh_iorenumber(shp,shp->inpipe[0],0); /* * if read end of pipe is a simple command -@@ -1924,7 +1947,7 @@ int sh_exec(register const Shnode_t *t, +@@ -1924,7 +1953,7 @@ int sh_exec(register const Shnode_t *t, jmpval = sigsetjmp(buffp->buff,0); if(jmpval==0) { @@ -1900,7 +1481,7 @@ tsetio = 1; sh_redirect(shp,t->fork.forkio,execflg); (t->fork.forktre)->tre.tretyp |= t->tre.tretyp&FSHOWME; -@@ -1953,8 +1976,8 @@ int sh_exec(register const Shnode_t *t, +@@ -1953,8 +1982,8 @@ int sh_exec(register const Shnode_t *t, if(type || !sh_isoption(SH_PIPEFAIL)) shp->exitval = type; } @@ -1911,7 +1492,7 @@ shp->pipepid = 0; shp->st.ioset = 0; if(simple && was_errexit) -@@ -2179,7 +2202,7 @@ int sh_exec(register const Shnode_t *t, +@@ -2179,7 +2208,7 @@ int sh_exec(register const Shnode_t *t, } shp->exitval = n; #ifdef SIGTSTP @@ -1920,7 +1501,7 @@ tcsetpgrp(JOBTTY,shp->gd->pid); #endif /*SIGTSTP */ job.curpgid = savepgid; -@@ -2320,7 +2343,10 @@ int sh_exec(register const Shnode_t *t, +@@ -2320,7 +2349,10 @@ int sh_exec(register const Shnode_t *t, nv_putsub(np,NIL(char*),0L); nv_putval(np,cp,0); if(nameref) @@ -1931,7 +1512,7 @@ if(trap=shp->st.trap[SH_DEBUGTRAP]) { av[0] = (t->tre.tretyp&COMSCAN)?"select":"for"; -@@ -2352,6 +2378,8 @@ int sh_exec(register const Shnode_t *t, +@@ -2352,6 +2384,8 @@ int sh_exec(register const Shnode_t *t, if(shp->st.breakcnt<0) shp->st.execbrk = (++shp->st.breakcnt !=0); } @@ -1940,7 +1521,7 @@ #if SHOPT_OPTIMIZE endfor: sh_popcontext(shp,buffp); -@@ -2466,8 +2494,10 @@ int sh_exec(register const Shnode_t *t, +@@ -2466,8 +2500,10 @@ int sh_exec(register const Shnode_t *t, #if SHOPT_FILESCAN if(iop) { @@ -1952,43 +1533,7 @@ dup(savein); shp->cur_line = 0; } -@@ -2688,6 +2718,7 @@ int sh_exec(register const Shnode_t *t, - else - { - root = dtopen(&_Nvdisc,Dtoset); -+ dtuserdata(root,shp,1); - nv_mount(np, (char*)0, root); - np->nvalue.cp = Empty; - dtview(root,shp->var_base); -@@ -2729,7 +2760,7 @@ int sh_exec(register const Shnode_t *t, - np = sh_fsearch(shp,fname,NV_ADD|HASH_NOSCOPE); - if(!np) - #endif /* SHOPT_NAMESPACE */ -- np = nv_open(fname,sh_subfuntree(1),NV_NOASSIGN|NV_NOARRAY|NV_VARNAME|NV_NOSCOPE); -+ np = nv_open(fname,sh_subfuntree(shp,1),NV_NOASSIGN|NV_NOARRAY|NV_VARNAME|NV_NOSCOPE); - if(npv) - { - if(!shp->mktype) -@@ -2745,7 +2776,7 @@ int sh_exec(register const Shnode_t *t, - stakdelete(slp->slptr); - if(rp->sdict) - { -- Namval_t *mp, *nq; -+ Namval_t *nq; - shp->last_root = rp->sdict; - for(mp=(Namval_t*)dtfirst(rp->sdict);mp;mp=nq) - { -@@ -2799,7 +2830,8 @@ int sh_exec(register const Shnode_t *t, - rp->np = np; - if(!shp->fpathdict) - shp->fpathdict = dtopen(&_Rpdisc,Dtobag); -- if(shp->fpathdict) { -+ if(shp->fpathdict) -+ { - dtuserdata(shp->fpathdict,shp,1); - dtinsert(shp->fpathdict,rp); - } -@@ -2909,6 +2941,15 @@ int sh_exec(register const Shnode_t *t, +@@ -2910,6 +2946,15 @@ int sh_exec(register const Shnode_t *t, break; } } @@ -2004,7 +1549,7 @@ if(shp->trapnote || (shp->exitval && sh_isstate(SH_ERREXIT)) && t && echeck) sh_chktrap(shp); -@@ -3165,7 +3206,7 @@ pid_t _sh_fork(Shell_t *shp,register pid +@@ -3166,7 +3211,7 @@ pid_t _sh_fork(Shell_t *shp,register pid { if(shp->topfd > restorefd) sh_iorestore(shp,restorefd,0); @@ -2013,7 +1558,7 @@ } } return(parent); -@@ -3477,8 +3518,7 @@ static void sh_funct(Shell_t *shp,Namval +@@ -3478,8 +3523,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); @@ -2023,7 +1568,7 @@ shp->pipepid = 0; sh_stats(STAT_FUNCT); if(!lp->hdr.disc) -@@ -3521,7 +3561,6 @@ static void sh_funct(Shell_t *shp,Namval +@@ -3522,7 +3566,6 @@ static void sh_funct(Shell_t *shp,Namval lp->maxlevel = level; SH_LEVELNOD->nvalue.s = lp->maxlevel; shp->last_root = nv_dict(DOTSHNOD); @@ -2031,7 +1576,7 @@ #if 0 nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE); #else -@@ -3626,11 +3665,11 @@ static void coproc_init(Shell_t *shp, in +@@ -3627,11 +3670,11 @@ static void coproc_init(Shell_t *shp, in sh_pipe(shp->cpipe); if((outfd=shp->cpipe[1]) < 10) { @@ -2045,7 +1590,7 @@ shp->fdstatus[outfd] = IOCLOSE; shp->cpipe[1] = fd; } -@@ -3719,7 +3758,7 @@ static int run_subshell(Shell_t *shp,con +@@ -3720,7 +3763,7 @@ static int run_subshell(Shell_t *shp,con if(!shp->gd->shpath) shp->gd->shpath = pathshell(); pid = spawnveg(shp->shpath,arglist,envlist,grp); @@ -2054,7 +1599,7 @@ for(i=3; i < 10; i++) { if(shp->fdstatus[i]&IOCLEX && i!=pin && i!=pout) -@@ -4000,7 +4039,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons +@@ -4001,7 +4044,7 @@ static pid_t sh_ntfork(Shell_t *shp,cons shp->gd->shpath = pathshell(); spawnpid = path_spawn(shp,shp->gd->shpath,&argv[-1],arge,pp,(grp<<1)|1); if(fd>=0) @@ -2063,3 +1608,17 @@ argv[0] = argv[-1]; } fail: +--- src/cmd/ksh93/tests/leaks.sh ++++ src/cmd/ksh93/tests/leaks.sh 2013-10-25 13:26:45.751247106 +0000 +@@ -67,6 +67,11 @@ done + + data="(v=;sid=;di=;hi=;ti='1328244300';lv='o';id='172.3.161.178';var=(k='conn_num._total';u=;fr=;l='Number of Connections';n='22';t='number';))" + read -C stat <<< "$data" ++for ((i=0; i < 1; i++)) ++do print -r -- "$data" ++done | while read -u$n -C stat ++ do : ++ done {n}<&0- + a=0$(vmstate --format='+%(size)u') + for ((i=0; i < 500; i++)) + do print -r -- "$data" diff --git a/ksh93-fs3d.dif b/ksh93-fs3d.dif new file mode 100644 index 0000000..1fffe6b --- /dev/null +++ b/ksh93-fs3d.dif @@ -0,0 +1,65 @@ +2013-10-17 10:30:20 - werner@suse.de + +Found by debugging with valgrind and environment variable LD_LIBRARY_PATH that +the mount() system call function from the glibc is used instead of a fs3d_mount() +function. To avoid this make fs3d_mount() a weak symbol to be overloadable by +a shared library function and make the stub function return -1 for not configured +file system type. + +--- src/lib/libast/misc/fs3d.c ++++ src/lib/libast/misc/fs3d.c 2013-10-17 10:30:20.000000000 +0000 +@@ -28,6 +28,20 @@ + * only active for non-shared 3d library + */ + ++#if defined(__linux__) && defined(__GNUC__) ++# if defined __USE_ISOC99 ++# define _cat_pragma(exp) _Pragma(#exp) ++# define _weak_pragma(exp) _cat_pragma(weak name) ++# else ++# define _weak_pragma(exp) ++# endif ++# define _declare(name,sym) __extension__ extern __typeof__(sym) name ++# define weak_symbol(sym) _weak_pragma(name) _declare(sym,sym) __attribute__((__weak__)) ++# include ++#else ++# define weak_symbol(sym) ++#endif ++ + #define mount ______mount + + #include +@@ -35,6 +49,7 @@ + #undef mount + + #include ++weak_symbol(fs3d_mount); + + int + fs3d(register int op) +@@ -102,11 +117,18 @@ fs3d(register int op) + * user code that includes will have mount() mapped to fs3d_mount() + * this restricts the various "standard" mount prototype conflicts to this spot + * this means that code that includes cannot access the real mount +- * (at least without some additional macro hackery ++ * (at least without some additional macro hackery) + */ + + #undef mount +- ++#if defined(__linux__) && defined(__GNUC__) ++int __attribute__((__noinline__)) ++fs3d_mount(const char* source, char* target, int flags, void* data) ++{ ++ errno = ENODEV; ++ return -1; ++} ++#else + extern int mount(const char*, char*, int, void*); + + int +@@ -114,3 +136,4 @@ fs3d_mount(const char* source, char* tar + { + return mount(source, target, flags, data); + } ++#endif diff --git a/ksh93-sfio.dif b/ksh93-sfio.dif new file mode 100644 index 0000000..6d29a3d --- /dev/null +++ b/ksh93-sfio.dif @@ -0,0 +1,263 @@ +--- src/lib/libast/include/sfio_t.h ++++ src/lib/libast/include/sfio_t.h 2013-10-11 09:22:41.000000000 +0000 +@@ -34,7 +34,7 @@ + #define _SFIO_PRIVATE \ + Sfoff_t extent; /* current file size */ \ + Sfoff_t here; /* current physical location */ \ +- unsigned char unused_1;/* unused #1 */ \ ++ unsigned char ngetr; /* sfgetr count */ \ + unsigned char tiny[1];/* for unbuffered read stream */ \ + unsigned short bits; /* private flags */ \ + unsigned int mode; /* current io mode */ \ +@@ -82,7 +82,7 @@ + (ssize_t)(-1), /* val */ \ + (Sfoff_t)0, /* extent */ \ + (Sfoff_t)0, /* here */ \ +- 0, /* getr */ \ ++ 0, /* ngetr */ \ + {0}, /* tiny */ \ + 0, /* bits */ \ + (unsigned int)(((type)&(SF_RDWR))|SF_INIT), /* mode */ \ +@@ -93,7 +93,8 @@ + (mutex), /* mutex */ \ + (Void_t*)0, /* stdio */ \ + (Sfoff_t)0, /* lpos */ \ +- (size_t)0 /* iosz */ \ ++ (size_t)0, /* iosz */ \ ++ 0 /* getr */ \ + } + + /* function to clear an Sfio_t structure */ +@@ -110,7 +111,7 @@ + (f)->val = (ssize_t)(-1), /* val */ \ + (f)->extent = (Sfoff_t)(-1), /* extent */ \ + (f)->here = (Sfoff_t)0, /* here */ \ +- (f)->getr = 0, /* getr */ \ ++ (f)->ngetr = 0, /* ngetr */ \ + (f)->tiny[0] = 0, /* tiny */ \ + (f)->bits = 0, /* bits */ \ + (f)->mode = 0, /* mode */ \ +@@ -121,7 +122,8 @@ + (f)->mutex = (mtx), /* mutex */ \ + (f)->stdio = (Void_t*)0, /* stdio */ \ + (f)->lpos = (Sfoff_t)0, /* lpos */ \ +- (f)->iosz = (size_t)0 /* iosz */ \ ++ (f)->iosz = (size_t)0, /* iosz */ \ ++ (f)->getr = 0 /* getr */ \ + ) + + /* expose next stream inside discipline function; state saved in int f */ +--- src/lib/libast/sfio/sfflsbuf.c ++++ src/lib/libast/sfio/sfflsbuf.c 2013-10-18 11:50:01.866235555 +0000 +@@ -96,7 +96,7 @@ int c; /* if c>=0, c is also written out + isall = SFISALL(f,isall); + if((w = SFWR(f,data,n,f->disc)) > 0) + { if((n -= w) > 0) /* save unwritten data, then resume */ +- memcpy((char*)f->data,(char*)data+w,n); ++ memmove((char*)f->data,(char*)data+w,n); + written += w; + f->next = f->data+n; + if(c < 0 && (!isall || n == 0)) +--- src/lib/libast/sfio/sfmode.c ++++ src/lib/libast/sfio/sfmode.c 2013-10-11 09:26:43.000000000 +0000 +@@ -258,7 +258,7 @@ reg Sfio_t* f; /* stream to close */ + #endif + { + Sfproc_t* p; +- int pid, status; ++ int status; + + if(!(p = f->proc)) + return -1; +@@ -279,7 +279,7 @@ reg Sfio_t* f; /* stream to close */ + sigcritical(SIG_REG_EXEC|SIG_REG_PROC); + #endif + status = -1; +- while ((pid = waitpid(p->pid,&status,0)) == -1 && errno == EINTR) ++ while (waitpid(p->pid,&status,0) == -1 && errno == EINTR) + ; + #if _PACKAGE_ast + status = status == -1 ? +@@ -405,12 +405,16 @@ reg int local; /* a local call */ + if(f->mode&SF_GETR) + { f->mode &= ~SF_GETR; + #ifdef MAP_TYPE +- if((f->bits&SF_MMAP) && (f->tiny[0] += 1) >= (4*SF_NMAP) ) +- { /* turn off mmap to avoid page faulting */ +- sfsetbuf(f,(Void_t*)f->tiny,(size_t)SF_UNBOUND); +- f->tiny[0] = 0; ++ if(f->bits&SF_MMAP) ++ { ++ if (!++f->ngetr) ++ f->tiny[0]++; ++ if(((f->tiny[0]<<8)|f->ngetr) >= (4*SF_NMAP) ) ++ { /* turn off mmap to avoid page faulting */ ++ sfsetbuf(f,(Void_t*)f->tiny,(size_t)SF_UNBOUND); ++ f->ngetr = f->tiny[0] = 0; ++ } + } +- else + #endif + if(f->getr) + { f->next[-1] = f->getr; +--- src/lib/libast/sfio/sfmove.c ++++ src/lib/libast/sfio/sfmove.c 2013-10-18 12:04:03.194735625 +0000 +@@ -113,7 +113,11 @@ reg int rc; /* record separator */ + + /* try reading a block of data */ + direct = 0; +- if((r = fr->endb - (next = fr->next)) <= 0) ++ if(fr->rsrv && (r = -fr->rsrv->slen) > 0) ++ { fr->rsrv->slen = 0; ++ next = fr->rsrv->data; ++ } ++ else if((r = fr->endb - (next = fr->next)) <= 0) + { /* amount of data remained to be read */ + if((w = n > MAX_SSIZE ? MAX_SSIZE : (ssize_t)n) < 0) + { if(fr->extent < 0) +--- src/lib/libast/sfio/sfpoll.c ++++ src/lib/libast/sfio/sfpoll.c 2013-10-18 11:59:50.778735232 +0000 +@@ -138,7 +138,7 @@ int tm; /* time in millisecs for select + while((np = SFPOLL(fds,m,tm)) < 0 ) + { if(errno == eintr || errno == EAGAIN) + errno = 0; +- else break; ++ else goto report; + } + if(np > 0) /* poll succeeded */ + np = c; +@@ -147,14 +147,14 @@ int tm; /* time in millisecs for select + { f = fa[check[r]]; + + if((f->flags&SF_WRITE) && !WRREADY(f) ) +- { if(fds[m].revents&POLLOUT) ++ { if(fds[m].revents&(POLLOUT|POLLHUP|POLLERR)) + status[check[r]] |= SF_WRITE; + } + + if((f->flags&SF_READ) && !RDREADY(f)) + { if((f->mode&SF_WRITE) && HASAUXFD(f)) + m += 1; +- if(fds[m].revents&POLLIN) ++ if(fds[m].revents&(POLLIN|POLLHUP|POLLERR)) + status[check[r]] |= SF_READ; + } + } +@@ -200,7 +200,7 @@ int tm; /* time in millisecs for select + while((np = select(m+1,&rd,&wr,NIL(fd_set*),tmp)) < 0 ) + { if(errno == eintr) + errno = 0; +- else break; ++ else goto report; + } + if(np > 0) + np = c; +@@ -227,6 +227,7 @@ int tm; /* time in millisecs for select + } + #endif /*_lib_select*/ + ++ report: + for(r = c = 0; c < n; ++c) + { if(status[c] == 0) + continue; +--- src/lib/libast/sfio/sfpool.c ++++ src/lib/libast/sfio/sfpool.c 2013-10-18 11:49:25.614237061 +0000 +@@ -138,7 +138,7 @@ int n; /* current position in pool */ + else /* write failed, recover buffer then quit */ + { if(w > 0) + { v -= w; +- memcpy(head->data,(head->data+w),v); ++ memmove(head->data,(head->data+w),v); + } + head->next = head->data+v; + goto done; +@@ -147,7 +147,7 @@ int n; /* current position in pool */ + + /* move data from head to f */ + if((head->data+k) != f->data ) +- memcpy(f->data,(head->data+k),v); ++ memmove(f->data,(head->data+k),v); + f->next = f->data+v; + } + +--- src/lib/libast/sfio/sfsetbuf.c ++++ src/lib/libast/sfio/sfsetbuf.c 2013-10-18 12:02:37.534736056 +0000 +@@ -254,6 +254,15 @@ size_t size; /* buffer size, -1 for defa + #endif + } + ++ /* set page size, this is also the desired default buffer size */ ++ if(_Sfpage <= 0) ++ { ++#if _lib_getpagesize ++ if((_Sfpage = (size_t)getpagesize()) <= 0) ++#endif ++ _Sfpage = SF_PAGE; ++ } ++ + #if SFSETLINEMODE + if(init) + f->flags |= sfsetlinemode(); +@@ -308,15 +317,6 @@ size_t size; /* buffer size, -1 for defa + (void)_sfpopen(f,-1,-1,1); + } + } +- +- /* set page size, this is also the desired default buffer size */ +- if(_Sfpage <= 0) +- { +-#if _lib_getpagesize +- if((_Sfpage = (size_t)getpagesize()) <= 0) +-#endif +- _Sfpage = SF_PAGE; +- } + } + + #ifdef MAP_TYPE +--- src/lib/libast/string/stropt.c ++++ src/lib/libast/string/stropt.c 2013-01-03 17:20:37.000000000 +0100 +@@ -90,7 +90,7 @@ stropt(const char* as, const void* tab, + { + for (p = (char**)tab; t = *p; p = (char**)((char*)p + siz)) + { +- for (v = s; *t && *t++ == *v; v++); ++ for (v = s; *t && *t == *v; t++, v++); + if (!*t || isspace(*v) || *v == ',' || *v == '=') + break; + if (*v == ':' && *(v + 1) == '=') +--- src/lib/libast/vmalloc/vmopen.c ++++ src/lib/libast/vmalloc/vmopen.c 2013-10-18 13:54:50.918235639 +0000 +@@ -68,19 +68,22 @@ int mode; /* type of region */ + Block_t *bp, *np; + Seg_t *seg; + Vmuchar_t *addr; +- int rv; ++ int rv, mt; + + if(!meth || !disc || !disc->memoryf ) + return NIL(Vmalloc_t*); + + GETPAGESIZE(_Vmpagesize); + ++ mode = (mode&VM_FLAGS) | meth->meth; /* start with user-settable flags */ ++ + vmp = &vmproto; /* avoid memory allocation here! */ + memset(vmp, 0, sizeof(Vmalloc_t)); + memcpy(&vmp->meth, meth, sizeof(Vmethod_t)); ++ mt = vmp->meth.meth; ++ vmp->meth.meth = 0; + vmp->disc = disc; + +- mode &= VM_FLAGS; /* start with user-settable flags */ + size = 0; + + if(disc->exceptf) +@@ -155,6 +158,8 @@ int mode; /* type of region */ + seg->free = bp; + else vd->wild = bp; + ++ vmp->meth.meth = mt; ++ + done: /* now make the region handle */ + if(vd->mode&VM_MEMORYF) + vm = &init->vm.vm; diff --git a/ksh93-uninitialized.dif b/ksh93-uninitialized.dif new file mode 100644 index 0000000..39cd9d0 --- /dev/null +++ b/ksh93-uninitialized.dif @@ -0,0 +1,361 @@ +--- src/cmd/builtin/pty.c ++++ src/cmd/builtin/pty.c 2013-10-25 13:30:22.019295258 +0000 +@@ -503,7 +503,7 @@ masterline(Sfio_t* mp, Sfio_t* lp, char* + char* t; + ssize_t n; + ssize_t a; +- size_t promptlen; ++ size_t promptlen = 0; + ptrdiff_t d; + char promptbuf[64]; + +@@ -773,6 +773,8 @@ dialogue(Sfio_t* mp, Sfio_t* lp, int del + !(master->buf = vmnewof(vm, 0, char, 2 * SF_BUFSIZE, 0))) + { + error(ERROR_SYSTEM|2, "out of space"); ++ id = 0; ++ line = 0; + goto done; + } + master->vm = vm; +--- src/cmd/ksh93/edit/edit.c ++++ src/cmd/ksh93/edit/edit.c 2013-10-25 13:30:22.020295166 +0000 +@@ -1414,12 +1414,12 @@ int ed_internal(const char *src, genchar + int ed_external(const genchar *src, char *dest) + { + register genchar wc; +- register int c,size; + register char *dp = dest; + char *dpmax = dp+sizeof(genchar)*MAXLINE-2; + if((char*)src == dp) + { +- char buffer[MAXLINE*sizeof(genchar)]; ++ int c; ++ char buffer[MAXLINE*sizeof(genchar)] = ""; + c = ed_external(src,buffer); + + #ifdef _lib_wcscpy +@@ -1431,6 +1431,7 @@ int ed_external(const genchar *src, char + } + while((wc = *src++) && dpsh_name;tp++) + n++; + np = (Namval_t*)calloc(n,sizeof(Namval_t)); +--- src/cmd/ksh93/sh/macro.c ++++ src/cmd/ksh93/sh/macro.c 2013-10-25 13:30:22.021295073 +0000 +@@ -1794,7 +1794,7 @@ retry2: + register int d = (mode=='@'?' ':mp->ifs); + regoff_t match[2*(MATCH_MAX+1)]; + int nmatch, nmatch_prev, vsize_last; +- char *vlast; ++ char *vlast=NULL; + while(1) + { + if(!v) +--- src/cmd/ksh93/sh/name.c ++++ src/cmd/ksh93/sh/name.c 2013-10-25 13:30:22.022294981 +0000 +@@ -1344,7 +1344,7 @@ Namval_t *nv_open(const char *name, Dt_t + const char *msg = e_varname; + char *fname = 0; + int offset = staktell(); +- Dt_t *funroot; ++ Dt_t *funroot = NIL(Dt_t*); + #if NVCACHE + struct Cache_entry *xp; + #endif +@@ -1820,7 +1820,7 @@ void nv_putval(register Namval_t *np, co + else + { + const char *tofree=0; +- int offset,append; ++ int offset=0,append; + #if _lib_pathnative + char buff[PATH_MAX]; + #endif /* _lib_pathnative */ +--- src/cmd/ksh93/sh/nvdisc.c ++++ src/cmd/ksh93/sh/nvdisc.c 2013-10-25 13:30:22.022294981 +0000 +@@ -449,7 +449,7 @@ static Sfdouble_t lookupn(Namval_t *np, + char *nv_setdisc(register Namval_t* np,register const char *event,Namval_t *action,register Namfun_t *fp) + { + register struct vardisc *vp = (struct vardisc*)np->nvfun; +- register int type; ++ register int type = -1; + char *empty = ""; + while(vp) + { +@@ -505,6 +505,8 @@ char *nv_setdisc(register Namval_t* np,r + } + return(NIL(char*)); + } ++ if (type < 0) ++ return(NIL(char*)); + /* Handle GET/SET/APPEND/UNSET disc */ + if(vp && vp->fun.disc->putval!=assign) + vp = 0; +--- src/cmd/ksh93/sh/nvtree.c ++++ src/cmd/ksh93/sh/nvtree.c 2013-10-25 13:30:22.023294889 +0000 +@@ -583,7 +583,7 @@ void nv_outnode(Namval_t *np, Sfio_t* ou + char *fmtq,*ep,*xp; + Namval_t *mp; + Namarr_t *ap = nv_arrayptr(np); +- int scan,tabs=0,c,more,associative = 0; ++ int scan=0,tabs=0,c,more,associative = 0; + int saveI = Indent; + Indent = indent; + if(ap) +@@ -696,7 +696,7 @@ void nv_outnode(Namval_t *np, Sfio_t* ou + + static void outval(char *name, const char *vname, struct Walk *wp) + { +- register Namval_t *np, *nq, *last_table=wp->shp->last_table; ++ register Namval_t *np, *nq=0, *last_table=wp->shp->last_table; + register Namfun_t *fp; + int isarray=0, special=0,mode=0; + if(*name!='.' || vname[strlen(vname)-1]==']') +--- src/cmd/ksh93/sh/nvtype.c ++++ src/cmd/ksh93/sh/nvtype.c 2013-10-25 13:30:22.023294889 +0000 +@@ -854,9 +854,10 @@ void nv_newtype(Namval_t *mp) + Namval_t *nv_mktype(Namval_t **nodes, int numnodes) + { + Namval_t *mp=nodes[0], *bp=0, *np, *nq, **mnodes=nodes; +- int i,j,k,m,n,nd=0,nref=0,iref=0,inherit=0; ++ int i,j,k,nd=0,nref=0,iref=0,inherit=0; + int size=sizeof(NV_DATA), dsize=0, nnodes; +- size_t offset=0; ++ size_t offset=0,m; ++ ssize_t n; + char *name=0, *cp, *sp, **help; + Namtype_t *pp,*qp=0,*dp,*tp; + Dt_t *root = nv_dict(mp); +@@ -869,6 +870,7 @@ Namval_t *nv_mktype(Namval_t **nodes, in + _nv_unset(nodes[0],NV_RDONLY); + errormsg(SH_DICT,ERROR_exit(1),e_badtypedef,cp); + } ++ n=strlen(nodes[1]->nvname); + for(nnodes=1,i=1; i childfun.fun, NV_LAST); + if(tp = (Namtype_t*)nv_hasdisc(nq, &type_disc)) + tp->strsize = -tp->strsize; +-else sfprintf(sfstderr,"tp==NULL\n"); + for(r=0; r < dp->numnodes; r++) + { + Namval_t *nr = nv_namptr(dp->nodes,r); +--- src/cmd/ksh93/sh/parse.c ++++ src/cmd/ksh93/sh/parse.c 2013-10-25 13:30:22.024294796 +0000 +@@ -301,7 +301,7 @@ static Shnode_t *getanode(Lex_t *lp, str + */ + static Shnode_t *makelist(Lex_t *lexp, int type, Shnode_t *l, Shnode_t *r) + { +- register Shnode_t *t; ++ register Shnode_t *t = NIL(Shnode_t*); + if(!l || !r) + sh_syntax(lexp); + else +@@ -742,7 +742,7 @@ static Shnode_t *funct(Lex_t *lexp) + register Shnode_t *t; + register int flag; + struct slnod *volatile slp=0; +- Stak_t *savstak; ++ Stak_t *savstak = NIL(Stak_t*); + Sfoff_t first, last; + struct functnod *volatile fp; + Sfio_t *iop; +@@ -815,7 +815,7 @@ static Shnode_t *funct(Lex_t *lexp) + { + struct comnod *ac; + char *cp, **argv, **argv0; +- int c; ++ int c=-1; + t->funct.functargs = ac = (struct comnod*)simple(lexp,SH_NOIO|SH_FUNDEF,NIL(struct ionod*)); + if(ac->comset || (ac->comtyp&COMSCAN)) + errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax4,lexp->sh->inlineno); +--- src/cmd/ksh93/sh/xec.c ++++ src/cmd/ksh93/sh/xec.c 2013-10-25 13:30:22.025294704 +0000 +@@ -1507,7 +1507,7 @@ int sh_exec(register const Shnode_t *t, + Namval_t node; + #endif /* SHOPT_NAMESPACE */ + struct Namref nr; +- long mode; ++ long mode = 0; + register struct slnod *slp; + if(!np->nvalue.ip) + { +@@ -1916,8 +1916,8 @@ int sh_exec(register const Shnode_t *t, + * don't create a new process, just + * save and restore io-streams + */ +- pid_t pid; +- int jmpval, waitall; ++ pid_t pid = 0; ++ int jmpval, waitall = 0; + int simple = (t->fork.forktre->tre.tretyp&COMMSK)==TCOM; + struct checkpt *buffp = (struct checkpt*)stkalloc(shp->stk,sizeof(struct checkpt)); + #if SHOPT_COSHELL +@@ -2409,7 +2409,7 @@ int sh_exec(register const Shnode_t *t, + Shnode_t *tt = t->wh.whtre; + #if SHOPT_FILESCAN + Sfio_t *iop=0; +- int savein; ++ int savein=-1; + #endif /*SHOPT_FILESCAN*/ + #if SHOPT_OPTIMIZE + int jmpval = ((struct checkpt*)shp->jmplist)->mode; +@@ -2877,7 +2877,7 @@ int sh_exec(register const Shnode_t *t, + else + { + register int traceon=0; +- register char *right; ++ register char *right = 0; + register char *trap; + char *argv[6]; + n = type>>TSHIFT; +@@ -2911,7 +2911,7 @@ int sh_exec(register const Shnode_t *t, + } + else if(type&TBINARY) + { +- char *op; ++ char *op = 0; + int pattern = 0; + if(trap || traceon) + op = (char*)(shtab_testops+(n&037)-1)->sh_name; +@@ -3376,7 +3376,7 @@ int sh_funscope(int argn, char *argv[],i + int jmpval; + volatile int r = 0; + int n; +- char *savstak; ++ char *savstak = 0; + struct funenv *fp = 0; + struct checkpt *buffp = (struct checkpt*)stkalloc(shp->stk,sizeof(struct checkpt)); + Namval_t *nspace = shp->namespace; +@@ -3492,10 +3492,10 @@ int sh_funscope(int argn, char *argv[],i + shp->st = *prevscope; + shp->topscope = (Shscope_t*)prevscope; + nv_getval(sh_scoped(shp,IFSNOD)); +- if(nsig) ++ if(nsig && savstak) + memcpy((char*)&shp->st.trapcom[0],savstak,nsig); + shp->trapnote=0; +- if(nsig) ++ if(nsig && savstak) + stakset(savstak,0); + shp->options = options; + shp->last_root = last_root; +@@ -3584,11 +3584,11 @@ static void sh_funct(Shell_t *shp,Namval + int sh_fun(Namval_t *np, Namval_t *nq, char *argv[]) + { + Shell_t *shp = sh_getinterp(); +- register int offset; ++ register int offset = 0; + register char *base; + Namval_t node; + struct Namref nr; +- long mode; ++ long mode = 0; + char *prefix = shp->prefix; + int n=0; + char *av[3]; +--- src/lib/libast/sfio/sfstrtof.h ++++ src/lib/libast/sfio/sfstrtof.h 2013-10-25 13:30:22.025294704 +0000 +@@ -211,8 +211,8 @@ S2F_function(str, end) char* str; char** + int decimal = 0; + int thousand = 0; + int part = 0; +- int back_part; +- S2F_batch back_n; ++ int back_part = 0; ++ S2F_batch back_n = 0; + S2F_number v; + S2F_number p; + S2F_part_t parts[16]; +--- src/lib/libast/sfio/sftable.c ++++ src/lib/libast/sfio/sftable.c 2013-10-25 13:30:22.026294612 +0000 +@@ -53,7 +53,7 @@ int type; /* >0: scanf, =0: printf, -1: + #endif + { + int base, fmt, flags, dot, width, precis; +- ssize_t n_str, size; ++ ssize_t n_str, size = 0; + char *t_str, *sp; + int v, n, skip, dollar, decimal, thousand; + Sffmt_t savft; +--- src/lib/libast/sfio/sfvprintf.c ++++ src/lib/libast/sfio/sfvprintf.c 2013-10-25 13:30:22.026294612 +0000 +@@ -101,7 +101,7 @@ char* form; /* format to use */ + va_list args; /* arg list if !argf */ + #endif + { +- int n, v, w, k, n_s, base, fmt, flags; ++ int n, v=0, w, k, n_s, base, fmt, flags; + Sflong_t lv; + char *sp, *ssp, *endsp, *ep, *endep; + int dot, width, precis, sign, decpt; +@@ -129,7 +129,7 @@ va_list args; /* arg list if !argf */ + int decimal = 0, thousand = 0; + + #if _has_multibyte +- wchar_t* wsp; ++ wchar_t* wsp = 0; + SFMBDCL(fmbs) /* state of format string */ + SFMBDCL(mbs) /* state of some string */ + #ifdef mbwidth +--- src/lib/libast/string/stropt.c ++++ src/lib/libast/string/stropt.c 2013-10-25 13:30:22.033293966 +0000 +@@ -60,13 +60,13 @@ stropt(const char* as, const void* tab, + register char* v; + register char* t; + char** p; +- char* u; ++ char* u = 0; + char* x; + char* e; + int n; + int ql; + int qr; +- int qc; ++ int qc = 0; + + if (!as) n = 0; + else if (!(x = s = strdup(as))) n = -1; +--- src/lib/libast/string/strtoi.h ++++ src/lib/libast/string/strtoi.h 2013-10-25 13:30:22.027294520 +0000 +@@ -230,13 +230,13 @@ S2I_function(a, e, base) const char* a; + #endif + register S2I_unumber n; + register S2I_unumber x; +- register int c; ++ register int c = 0; + register int shift; + register unsigned char* p; + register unsigned char* cv; + unsigned char* b; + unsigned char* k; +- S2I_unumber v; ++ S2I_unumber v = 0; + #if S2I_multiplier + register int base; + #endif diff --git a/sigexec.c b/sigexec.c index 1b2c0bb..51f5d0c 100644 --- a/sigexec.c +++ b/sigexec.c @@ -56,8 +56,16 @@ int main(int argc, char* argv[]) errno = 0; } if (tcgetattr(0, &o) < 0) { +#ifdef B115200 + cfsetispeed(&o, B115200); + cfsetospeed(&o, B115200); +#elif defined(B57600) + cfsetispeed(&o, B57600); + cfsetospeed(&o, B57600); +#elif defined(B38400) cfsetispeed(&o, B38400); cfsetospeed(&o, B38400); +#endif } o.c_iflag = TTYDEF_IFLAG; @@ -66,7 +74,13 @@ int main(int argc, char* argv[]) # ifdef CBAUD o.c_lflag &= ~CBAUD; # endif +#ifdef B115200 + o.c_cflag = B115200; +#elif defined(B57600) + o.c_cflag = B57600; +#elif defined(B38400) o.c_cflag = B38400; +#endif o.c_cflag |= TTYDEF_CFLAG; /* Sane setting, allow eight bit characters, no carriage return delay