diff options
Diffstat (limited to 'system/pdksh/patches/010_OpenBSD-patches.patch')
-rw-r--r-- | system/pdksh/patches/010_OpenBSD-patches.patch | 1112 |
1 files changed, 0 insertions, 1112 deletions
diff --git a/system/pdksh/patches/010_OpenBSD-patches.patch b/system/pdksh/patches/010_OpenBSD-patches.patch deleted file mode 100644 index ebb3c9e64c..0000000000 --- a/system/pdksh/patches/010_OpenBSD-patches.patch +++ /dev/null @@ -1,1112 +0,0 @@ - * Applied some patches from OpenBSD: - + Use mkstemp to create temporary files - + Kill -s now works - + Escapes special characters in tab completitions - + Introduce FSH flag, which is set when the shell is called as `sh'. - + tree.c: Fix three off-by-one errors. - + c_sh.c: don't set close-on-exec flag on file descriptors in FSH mode - (closes: #154540). Documented the change in ksh(1). - + history.c: Compare the return from mmap with MAP_FAILED, do not cast it - to int and compare with -1. - + main.c: set edit mode to emacs by default, may be overridden by the - environment or the user. Also, we want tab completion in vi by default. - + misc.c: use strtol() in getn(). - + emacs.c: - - bind TAB (^I) to complete-list by default - - complete-list first completes; if that does not work, it lists - - fix a memleak in do_complete() - + edit.c: - - completion now works after '=' (dd), and ':' (ssh) and ` (backtick) - - add '#' to the list of escaped characters during vi/emacs filename - completion - - + exec.c: Found and fixed yet another problem with `set -e' scripts - (see a changelog entry for 5.2.14-3), which caused `dpkg-buildpackage -B' - to fail on systems where /bin/sh is ksh. - - + c_sh.c: Make `set' command return 0 always, not only in the POSIX mode. - According to Jeff Sheinberg <jeffsh@localnet.com>, this new behaviour - is more compatible with SUSv2 standard and other shells (esp. ksh93) - (closes: #118476). Documented the change in ksh(1) man page. - - + c_test.c: The special case code for "test -x" over NFS was - incorrect. The right thing to do is to try access(2) first - (since that occurs on the NFS server side) and only check for the - absence of an execute bit when access(2) succeeds. - + edit.c: in word location, fix forward scanning so it correctly - account for any escaped char and not only spaces. for "foo - (bar.a)" and "foo (bar a)", cd foo\ \(bar.<tab> will correctly - expand to foo\ \(bar.a\). - - + vi.c: Buffers are not strings so use memcpy(), not strlcpy() to copy - them. Also add some further bounds checks in the name of paranoia. - + exec.c: Unbreak parameter assignment when calling bourne style - functions. - + exec.c: For the >& and <& operators, add a check for "dup from" == - "dup to" and just return success if they are the same. Fixes the - "ls 2>&2" problem. - + eval.c, exec.c, io.c, jobs.c: If "from fd" == "to fd" don't call - dup2() or close "from fd". - -Index: pdksh-5.2.14/c_ksh.c -=================================================================== ---- pdksh-5.2.14.orig/c_ksh.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/c_ksh.c 2009-09-17 00:32:08.000000000 +0200 -@@ -1208,6 +1208,7 @@ - builtin_opt.optarg); - return 1; - } -+ break; - case '?': - return 1; - } -Index: pdksh-5.2.14/edit.c -=================================================================== ---- pdksh-5.2.14.orig/edit.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/edit.c 2009-09-17 00:32:08.000000000 +0200 -@@ -15,6 +15,9 @@ - # include <sys/stream.h> /* needed for <sys/ptem.h> */ - # include <sys/ptem.h> /* needed for struct winsize */ - #endif /* OS_SCO */ -+#ifdef DEBIAN -+#include <sys/ioctl.h> -+#endif /* DEBIAN */ - #include <ctype.h> - #include "ksh_stat.h" - -@@ -552,7 +555,11 @@ - { - char *toglob; - char **words; -+#ifndef DEBIAN - int nwords; -+#else /* DEBIAN */ /* patch from OpenBSD */ -+ int nwords, i, idx, escaping; -+#endif /* DEBIAN */ - XPtrV w; - struct source *s, *sold; - -@@ -561,6 +568,22 @@ - - toglob = add_glob(str, slen); - -+#ifdef DEBIAN /* patch from OpenBSD */ -+ /* remove all escaping backward slashes */ -+ escaping = 0; -+ for(i = 0, idx = 0; toglob[i]; i++) { -+ if (toglob[i] == '\\' && !escaping) { -+ escaping = 1; -+ continue; -+ } -+ -+ toglob[idx] = toglob[i]; -+ idx++; -+ if (escaping) escaping = 0; -+ } -+ toglob[idx] = '\0'; -+ -+#endif /* DEBIAN */ - /* - * Convert "foo*" (toglob) to an array of strings (words) - */ -@@ -722,7 +745,12 @@ - return nwords; - } - -+#ifndef DEBIAN - #define IS_WORDC(c) !(ctype(c, C_LEX1) || (c) == '\'' || (c) == '"') -+#else /* patch from OpenBSD */ -+#define IS_WORDC(c) !( ctype(c, C_LEX1) || (c) == '\'' || (c) == '"' \ -+ || (c) == '`' || (c) == '=' || (c) == ':' ) -+#endif - - static int - x_locate_word(buf, buflen, pos, startp, is_commandp) -@@ -747,11 +775,23 @@ - /* Keep going backwards to start of word (has effect of allowing - * one blank after the end of a word) - */ -+#ifndef DEBIAN - for (; start > 0 && IS_WORDC(buf[start - 1]); start--) -+#else /* DEBIAN */ /* patch from OpenBSD */ -+ for (; (start > 0 && IS_WORDC(buf[start - 1])) -+ || (start > 1 && buf[start-2] == '\\'); start--) -+#endif /* DEBIAN */ - ; - /* Go forwards to end of word */ -+#ifndef DEBIAN - for (end = start; end < buflen && IS_WORDC(buf[end]); end++) - ; -+#else /* DEBIAN */ /* patch from OpenBSD */ -+ for (end = start; end < buflen && IS_WORDC(buf[end]); end++) { -+ if (buf[end] == '\\' && (end+1) < buflen) -+ end++; -+ } -+#endif /* DEBIAN */ - - if (is_commandp) { - int iscmd; -@@ -759,7 +799,11 @@ - /* Figure out if this is a command */ - for (p = start - 1; p >= 0 && isspace(buf[p]); p--) - ; -+#ifndef DEBIAN - iscmd = p < 0 || strchr(";|&()", buf[p]); -+#else /* DEBIAN */ /* patch from OpenBSD */ -+ iscmd = p < 0 || strchr(";|&()`", buf[p]); -+#endif - if (iscmd) { - /* If command has a /, path, etc. is not searched; - * only current directory is searched, which is just -@@ -961,6 +1005,9 @@ - { - const char *sp, *p; - char *xp; -+#ifdef DEBIAN /* patch from OpenBSD */ -+ int staterr; -+#endif /* DEBIAN */ - int pathlen; - int patlen; - int oldsize, newsize, i, j; -@@ -995,13 +1042,23 @@ - memcpy(xp, pat, patlen); - - oldsize = XPsize(*wp); -+#ifndef DEBIAN - glob_str(Xstring(xs, xp), wp, 0); -+#else /* DEBIAN */ /* patch from OpenBSD */ -+ glob_str(Xstring(xs, xp), wp, 1); /* mark dirs */ -+#endif - newsize = XPsize(*wp); - - /* Check that each match is executable... */ - words = (char **) XPptrv(*wp); - for (i = j = oldsize; i < newsize; i++) { -+#ifndef DEBIAN - if (search_access(words[i], X_OK, (int *) 0) >= 0) { -+#else /* DEBIAN */ /* patch from OpenBSD */ -+ staterr = 0; -+ if ((search_access(words[i], X_OK, &staterr) >= 0) -+ || (staterr == EISDIR)) { -+#endif - words[j] = words[i]; - if (!(flags & XCF_FULLPATH)) - memmove(words[j], words[j] + pathlen, -@@ -1018,4 +1075,42 @@ - Xfree(xs, xp); - } - -+#ifdef DEBIAN /* patch from OpenBSD */ -+/* -+ * if argument string contains any special characters, they will -+ * be escaped and the result will be put into edit buffer by -+ * keybinding-specific function -+ */ -+int -+x_escape(s, len, putbuf_func) -+ const char *s; -+ size_t len; -+ int putbuf_func ARGS((const char *s, size_t len)); -+{ -+ size_t add, wlen; -+ const char *ifs = str_val(local("IFS", 0)); -+ int rval=0; -+ -+ for (add = 0, wlen = len; wlen - add > 0; add++) { -+ if (strchr("\\$(){}*&;#|<>\"'`", s[add]) || strchr(ifs, s[add])) { -+ if (putbuf_func(s, add) != 0) { -+ rval = -1; -+ break; -+ } -+ -+ putbuf_func("\\", 1); -+ putbuf_func(&s[add], 1); -+ -+ add++; -+ wlen -= add; -+ s += add; -+ add = -1; /* after the increment it will go to 0 */ -+ } -+ } -+ if (wlen > 0 && rval == 0) -+ rval = putbuf_func(s, wlen); -+ -+ return (rval); -+} -+#endif /* DEBIAN */ - #endif /* EDIT */ -Index: pdksh-5.2.14/edit.h -=================================================================== ---- pdksh-5.2.14.orig/edit.h 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/edit.h 2009-09-17 00:32:08.000000000 +0200 -@@ -55,6 +55,9 @@ - int x_longest_prefix ARGS((int nwords, char *const *words)); - int x_basename ARGS((const char *s, const char *se)); - void x_free_words ARGS((int nwords, char **words)); -+#ifdef DEBIAN /* patch from OpenBSD */ -+int x_escape ARGS((const char *, size_t, int (*)(const char *s, size_t len))); -+#endif /* DEBIAN */ - /* emacs.c */ - int x_emacs ARGS((char *buf, size_t len)); - void x_init_emacs ARGS((void)); -Index: pdksh-5.2.14/emacs.c -=================================================================== ---- pdksh-5.2.14.orig/emacs.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/emacs.c 2009-09-17 00:32:08.000000000 +0200 -@@ -138,6 +138,10 @@ - static int x_e_getc ARGS((void)); - static void x_e_putc ARGS((int c)); - static void x_e_puts ARGS((const char *s)); -+#ifdef DEBIAN /* patch from OpenBSD */ -+static int x_comment ARGS((int c)); -+static int x_emacs_putbuf ARGS((const char *s, size_t len)); -+#endif /* DEBIAN */ - static int x_fold_case ARGS((int c)); - static char *x_lastcp ARGS((void)); - static void do_complete ARGS((int flags, Comp_type type)); -@@ -269,6 +273,9 @@ - { XFUNC_transpose, 0, CTRL('T') }, - #endif - { XFUNC_complete, 1, CTRL('[') }, -+#ifdef DEBIAN /* patch from OpenBSD */ -+ { XFUNC_comp_list, 0, CTRL('I') }, -+#endif /* DEBIAN */ - { XFUNC_comp_list, 1, '=' }, - { XFUNC_enumerate, 1, '?' }, - { XFUNC_expand, 1, '*' }, -@@ -313,6 +320,9 @@ - * entries. - */ - { XFUNC_meta2, 1, '[' }, -+#ifdef DEBIAN /* patch from OpenBSD */ -+ { XFUNC_meta2, 1, 'O' }, -+#endif /* DEBIAN */ - { XFUNC_prev_com, 2, 'A' }, - { XFUNC_next_com, 2, 'B' }, - { XFUNC_mv_forw, 2, 'C' }, -@@ -468,6 +478,23 @@ - return 0; - } - -+#ifdef DEBIAN /* patch from OpenBSD */ -+/* -+ * this is used for x_escape() in do_complete() -+ */ -+static int -+x_emacs_putbuf(s, len) -+ const char *s; -+ size_t len; -+{ -+ int rval; -+ -+ if ((rval = x_do_ins(s, len)) != 0) -+ return (rval); -+ return (rval); -+} -+ -+#endif /* DEBIAN */ - static int - x_del_back(c) - int c; -@@ -1485,7 +1512,11 @@ - for (j = 0; j < X_TABSZ; j++) - x_tab[i][j] = XFUNC_error; - for (i = 0; i < NELEM(x_defbindings); i++) -+#ifndef DEBIAN - x_tab[x_defbindings[i].xdb_tab][x_defbindings[i].xdb_char] -+#else /* DEBIAN */ /* patch from OpenBSD */ -+ x_tab[(unsigned char)x_defbindings[i].xdb_tab][x_defbindings[i].xdb_char] -+#endif /* DEBIAN */ - = x_defbindings[i].xdb_func; - - x_atab = (char *(*)[X_TABSZ]) alloc(sizeofN(*x_atab, X_NTABS), AEDIT); -@@ -1754,6 +1785,7 @@ - int flags; /* XCF_{COMMAND,FILE,COMMAND_FILE} */ - Comp_type type; - { -+#ifndef DEBIAN - char **words; - int nwords = 0; - int start, end; -@@ -1828,8 +1860,13 @@ - if (nlen > 0) { - x_goto(xbuf + start); - x_delete(end - start, FALSE); -+#ifndef DEBIAN - words[0][nlen] = '\0'; - x_ins(words[0]); -+#else /* DEBIAN */ /* patch from OpenBSD */ -+ x_escape(words[0], nlen, x_emacs_putbuf); -+ x_adjust(); -+#endif /* DEBIAN */ - /* If single match is not a directory, add a - * space to the end... - */ -@@ -1841,6 +1878,54 @@ - } - break; - } -+#else /* patch from OpenBSD */ -+ char **words; -+ int nwords; -+ int start, end, nlen, olen; -+ int is_command; -+ int completed = 0; -+ -+ nwords = x_cf_glob(flags, xbuf, xep - xbuf, xcp - xbuf, -+ &start, &end, &words, &is_command); -+ /* no match */ -+ if (nwords == 0) { -+ x_e_putc(BEL); -+ return; -+ } -+ -+ if (type == CT_LIST) { -+ x_print_expansions(nwords, words, is_command); -+ x_redraw(0); -+ x_free_words(nwords, words); -+ return; -+ } -+ -+ olen = end - start; -+ nlen = x_longest_prefix(nwords, words); -+ /* complete */ -+ if (nlen > olen) { -+ x_goto(xbuf + start); -+ x_delete(olen, FALSE); -+ x_escape(words[0], nlen, x_emacs_putbuf); -+ x_adjust(); -+ completed = 1; -+ } -+ /* add space if single non-dir match */ -+ if ((nwords == 1) && (!ISDIRSEP(words[0][nlen - 1]))) { -+ x_ins(space); -+ completed = 1; -+ } -+ -+ if (type == CT_COMPLIST && !completed) { -+ x_print_expansions(nwords, words, is_command); -+ completed = 1; -+ } -+ -+ if (completed) -+ x_redraw(0); -+ -+ x_free_words(nwords, words); -+#endif /* DEBIAN */ - } - - /* NAME: -Index: pdksh-5.2.14/io.c -=================================================================== ---- pdksh-5.2.14.orig/io.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/io.c 2009-09-17 00:32:08.000000000 +0200 -@@ -318,7 +318,7 @@ - shf_flush(&shf_iob[fd]); - if (ofd < 0) /* original fd closed */ - close(fd); -- else { -+ else if (fd != ofd) { - ksh_dup2(ofd, fd, TRUE); /* XXX: what to do if this fails? */ - close(ofd); - } -@@ -502,7 +502,9 @@ - Temp_type type; - struct temp **tlist; - { -+#ifndef DEBIAN - static unsigned int inc; -+#endif - struct temp *tp; - int len; - int fd; -@@ -516,6 +518,14 @@ - tp->name = path = (char *) &tp[1]; - tp->shf = (struct shf *) 0; - tp->type = type; -+#ifdef DEBIAN /* based on patch from OpenBSD */ -+ shf_snprintf(path, len, "%s/kshXXXXXX", dir); -+ fd = mkstemp(path); -+ if (fd >= 0) -+ tp->shf = shf_fdopen(fd, SHF_WR, (struct shf *) 0); -+ if (fd >= 0) -+ fchmod(fd, 0600); -+#else /* DEBIAN */ - while (1) { - /* Note that temp files need to fit 8.3 DOS limits */ - shf_snprintf(path, len, "%s/sh%05u.%03x", -@@ -542,6 +552,7 @@ - break; - } - tp->next = NULL; -+#endif /* DEBIAN */ - tp->pid = procpid; - - tp->next = *tlist; -Index: pdksh-5.2.14/vi.c -=================================================================== ---- pdksh-5.2.14.orig/vi.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/vi.c 2009-09-17 00:32:08.000000000 +0200 -@@ -63,6 +63,9 @@ - static void vi_pprompt ARGS((int full)); - static void vi_error ARGS((void)); - static void vi_macro_reset ARGS((void)); -+#ifdef DEBIAN /* patch from OpenBSD */ -+static int x_vi_putbuf ARGS((const char *s, size_t len)); -+#endif /* DEBIAN */ - - #define C_ 0x1 /* a valid command that isn't a M_, E_, U_ */ - #define M_ 0x2 /* movement command (h, l, etc.) */ -@@ -235,7 +238,7 @@ - - x_putc('\r'); x_putc('\n'); x_flush(); - -- if (c == -1) -+ if (c == -1 || len <= es->linelen) - return -1; - - if (es->cbuf != buf) -@@ -459,15 +462,22 @@ - else { - locpat[srchlen++] = ch; - if ((ch & 0x80) && Flag(FVISHOW8)) { -+ if (es->linelen + 2 > es->cbufsize) -+ vi_error(); - es->cbuf[es->linelen++] = 'M'; - es->cbuf[es->linelen++] = '-'; - ch &= 0x7f; - } - if (ch < ' ' || ch == 0x7f) { -+ if (es->linelen + 2 > es->cbufsize) -+ vi_error(); - es->cbuf[es->linelen++] = '^'; - es->cbuf[es->linelen++] = ch ^ '@'; -- } else -+ } else { -+ if (es->linelen >= es->cbufsize) -+ vi_error(); - es->cbuf[es->linelen++] = ch; -+ } - es->cursor = es->linelen; - refresh(0); - } -@@ -690,7 +700,7 @@ - /* End nonstandard vi commands } */ - - default: -- if (es->linelen == es->cbufsize - 1) -+ if (es->linelen >= es->cbufsize - 1) - return -1; - ibuf[inslen++] = ch; - if (insert == INSERT) { -@@ -1403,7 +1413,7 @@ - new = (struct edstate *)alloc(sizeof(struct edstate), APERM); - new->cbuf = alloc(old->cbufsize, APERM); - new->cbufsize = old->cbufsize; -- strcpy(new->cbuf, old->cbuf); -+ memcpy(new->cbuf, old->cbuf, old->linelen); - new->linelen = old->linelen; - new->cursor = old->cursor; - new->winleft = old->winleft; -@@ -1414,7 +1424,7 @@ - restore_edstate(new, old) - struct edstate *old, *new; - { -- strncpy(new->cbuf, old->cbuf, old->linelen); -+ memcpy(new->cbuf, old->cbuf, old->linelen); - new->linelen = old->linelen; - new->cursor = old->cursor; - new->winleft = old->winleft; -@@ -1470,6 +1480,19 @@ - holdlen = 0; - } - -+#ifdef DEBIAN /* patch from OpenBSD */ -+/* -+ * this is used for calling x_escape() in complete_word() -+ */ -+static int -+x_vi_putbuf(s, len) -+ const char *s; -+ size_t len; -+{ -+ return putbuf(s, len, 0); -+} -+ -+#endif /* DEBIAN */ - static int - putbuf(buf, len, repl) - const char *buf; -@@ -1965,7 +1988,11 @@ - del_range(start, end); - es->cursor = start; - for (i = 0; i < nwords; ) { -+#ifndef DEBIAN - if (putbuf(words[i], (int) strlen(words[i]), 0) != 0) { -+#else /* DEBIAN */ /* patch from OpenBSD */ -+ if (x_escape(words[i], strlen(words[i]), x_vi_putbuf) != 0) { -+#endif /* DEBIAN */ - rval = -1; - break; - } -@@ -2068,9 +2095,18 @@ - buf = save_edstate(es); - del_range(start, end); - es->cursor = start; -+#ifndef DEBIAN - if (putbuf(match, match_len, 0) != 0) - rval = -1; - else if (is_unique) { -+#else /* DEBIAN */ /* patch from OpenBSD */ -+ -+ /* escape all shell-sensitive characters and put the result into -+ * command buffer */ -+ rval = x_escape(match, match_len, x_vi_putbuf); -+ -+ if (rval == 0 && is_unique) { -+#endif /* DEBIAN */ - /* If exact match, don't undo. Allows directory completions - * to be used (ie, complete the next portion of the path). - */ -Index: pdksh-5.2.14/c_sh.c -=================================================================== ---- pdksh-5.2.14.orig/c_sh.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/c_sh.c 2009-09-17 00:32:08.000000000 +0200 -@@ -643,6 +643,7 @@ - for (wp = l->argv; (*wp++ = *owp++) != NULL; ) - ; - } -+#ifndef DEBIAN - /* POSIX says set exit status is 0, but old scripts that use - * getopt(1), use the construct: set -- `getopt ab:c "$@"` - * which assumes the exit value set will be that of the `` -@@ -650,6 +651,12 @@ - * if there are no command substitutions). - */ - return Flag(FPOSIX) ? 0 : subst_exstat; -+#else -+ /* On Debian we always want set to return 0 like ksh93 does. -+ * See: Bug#118476. -+ */ -+ return 0; -+#endif /* DEBIAN */ - } - - int -@@ -844,7 +851,7 @@ - * keeps them open). - */ - #ifdef KSH -- if (i > 2 && e->savefd[i]) -+ if (!Flag(FSH) &&i > 2 && e->savefd[i]) - fd_clexec(i); - #endif /* KSH */ - } -Index: pdksh-5.2.14/exec.c -=================================================================== ---- pdksh-5.2.14.orig/exec.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/exec.c 2009-09-17 00:32:31.000000000 +0200 -@@ -228,8 +228,10 @@ - e->savefd[1] = savefd(1, 0); - - openpipe(pv); -- ksh_dup2(pv[0], 0, FALSE); -- close(pv[0]); -+ if (pv[0] != 0) { -+ ksh_dup2(pv[0], 0, FALSE); -+ close(pv[0]); -+ } - coproc.write = pv[1]; - coproc.job = (void *) 0; - -@@ -448,18 +450,19 @@ - int volatile flags; - { - int i; -- int rv = 0; -+ volatile int rv = 0; - register char *cp; - register char **lastp; - static struct op texec; /* Must be static (XXX but why?) */ - int type_flags; - int keepasn_ok; - int fcflags = FC_BI|FC_FUNC|FC_PATH; -+ int bourne_function_call = 0; - - #ifdef KSH - /* snag the last argument for $_ XXX not the same as at&t ksh, - * which only seems to set $_ after a newline (but not in -- * functions/dot scripts, but in interactive and scipt) - -+ * functions/dot scripts, but in interactive and script) - - * perhaps save last arg here and set it in shell()?. - */ - if (Flag(FTALKING) && *(lastp = ap)) { -@@ -544,9 +547,10 @@ - newblock(); - /* ksh functions don't keep assignments, POSIX functions do. */ - if (keepasn_ok && tp && tp->type == CFUNC -- && !(tp->flag & FKSH)) -- type_flags = 0; -- else -+ && !(tp->flag & FKSH)) { -+ bourne_function_call = 1; -+ type_flags = 0; -+ } else - type_flags = LOCAL|LOCAL_COPY|EXPORT; - } - if (Flag(FEXPORT)) -@@ -563,6 +567,8 @@ - shf_flush(shl_out); - } - typeset(cp, type_flags, 0, 0, 0); -+ if (bourne_function_call && !(type_flags & EXPORT)) -+ typeset(cp, LOCAL|LOCAL_COPY|EXPORT, 0, 0, 0); - } - - if ((cp = *ap) == NULL) { -@@ -710,10 +716,12 @@ - } - - #ifdef KSH -- /* set $_ to program's full path */ -- /* setstr() can't fail here */ -- setstr(typeset("_", LOCAL|EXPORT, 0, INTEGER, 0), tp->val.s, -- KSH_RETURN_ERROR); -+ if (!Flag(FSH)) { -+ /* set $_ to program's full path */ -+ /* setstr() can't fail here */ -+ setstr(typeset("_", LOCAL|EXPORT, 0, INTEGER, 0), tp->val.s, -+ KSH_RETURN_ERROR); -+ } - #endif /* KSH */ - - if (flags&XEXEC) { -@@ -1351,6 +1359,8 @@ - snptreef((char *) 0, 32, "%R", &iotmp), emsg); - return -1; - } -+ if (u == iop->unit) -+ return 0; /* "dup from" == "dup to" */ - break; - } - } -@@ -1375,13 +1385,20 @@ - return -1; - } - /* Do not save if it has already been redirected (i.e. "cat >x >y"). */ -- if (e->savefd[iop->unit] == 0) -- /* c_exec() assumes e->savefd[fd] set for any redirections. -- * Ask savefd() not to close iop->unit - allows error messages -- * to be seen if iop->unit is 2; also means we can't lose -- * the fd (eg, both dup2 below and dup2 in restfd() failing). -- */ -- e->savefd[iop->unit] = savefd(iop->unit, 1); -+ if (e->savefd[iop->unit] == 0) { -+#ifdef DEBIAN /* patch from OpenBSD */ -+ /* If these are the same, it means unit was previously closed */ -+ if (u == iop->unit) -+ e->savefd[iop->unit] = -1; -+ else -+#endif -+ /* c_exec() assumes e->savefd[fd] set for any redirections. -+ * Ask savefd() not to close iop->unit - allows error messages -+ * to be seen if iop->unit is 2; also means we can't lose -+ * the fd (eg, both dup2 below and dup2 in restfd() failing). -+ */ -+ e->savefd[iop->unit] = savefd(iop->unit, 1); -+ } - - if (do_close) - close(iop->unit); -Index: pdksh-5.2.14/history.c -=================================================================== ---- pdksh-5.2.14.orig/history.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/history.c 2009-09-17 00:32:08.000000000 +0200 -@@ -858,8 +858,8 @@ - /* - * check on its validity - */ -- if ((int)base == -1 || *base != HMAGIC1 || base[1] != HMAGIC2) { -- if ((int)base != -1) -+ if (base == MAP_FAILED || *base != HMAGIC1 || base[1] != HMAGIC2) { -+ if (base != MAP_FAILED) - munmap((caddr_t)base, hsize); - hist_finish(); - unlink(hname); -@@ -893,7 +893,7 @@ - static int - hist_count_lines(base, bytes) - register unsigned char *base; -- register int bytes; -+ int bytes; - { - State state = shdr; - register lines = 0; -@@ -1015,8 +1015,8 @@ - register int bytes; - { - State state; -- int lno; -- unsigned char *line; -+ int lno = -1; -+ unsigned char *line = NULL; - - for (state = shdr; bytes-- > 0; base++) { - switch (state) { -@@ -1105,7 +1105,7 @@ - /* someone has added some lines */ - bytes = sizenow - hsize; - base = (unsigned char *)mmap(0, sizenow, PROT_READ, MAP_FLAGS, histfd, 0); -- if ((int)base == -1) -+ if (base == MAP_FAILED) - goto bad; - new = base + hsize; - if (*new != COMMAND) { -Index: pdksh-5.2.14/jobs.c -=================================================================== ---- pdksh-5.2.14.orig/jobs.c 2009-09-17 00:32:06.000000000 +0200 -+++ pdksh-5.2.14/jobs.c 2009-09-17 00:32:08.000000000 +0200 -@@ -627,8 +627,10 @@ - SS_RESTORE_IGN|SS_FORCE); - if (!(flags & (XPIPEI | XCOPROC))) { - int fd = open("/dev/null", 0); -- (void) ksh_dup2(fd, 0, TRUE); -- close(fd); -+ if (fd != 0) { -+ (void) ksh_dup2(fd, 0, TRUE); -+ close(fd); -+ } - } - } - remove_job(j, "child"); /* in case of `jobs` command */ -@@ -811,7 +813,7 @@ - int sig; - { - Job *j; -- Proc *p; -+/* Proc *p; */ /* unused */ - int rv = 0; - int ecode; - #ifdef JOB_SIGS -Index: pdksh-5.2.14/lex.c -=================================================================== ---- pdksh-5.2.14.orig/lex.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/lex.c 2009-09-17 00:32:08.000000000 +0200 -@@ -699,11 +699,13 @@ - - case '(': /*)*/ - #ifdef KSH -- if ((c2 = getsc()) == '(') /*)*/ -- /* XXX need to handle ((...); (...)) */ -- c = MDPAREN; -- else -- ungetsc(c2); -+ if (!Flag(FSH)) { -+ if ((c2 = getsc()) == '(') /*)*/ -+ /* XXX need to handle ((...); (...)) */ -+ c = MDPAREN; -+ else -+ ungetsc(c2); -+ } - #endif /* KSH */ - return c; - /*(*/ -@@ -1119,7 +1121,7 @@ - */ - { - struct shf *shf; -- char *ps1; -+ char * volatile ps1; - Area *saved_atemp; - - ps1 = str_val(global("PS1")); -Index: pdksh-5.2.14/main.c -=================================================================== ---- pdksh-5.2.14.orig/main.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/main.c 2009-09-17 00:32:08.000000000 +0200 -@@ -201,7 +201,24 @@ - change_flag(FPOSIX, OF_SPECIAL, 1); - #endif /* POSIXLY_CORRECT */ - -- /* import enviroment */ -+#ifdef DEBIAN /* patch from OpenBSD */ -+ /* Check to see if we're /bin/sh. */ -+ if (!strcmp(&kshname[strlen(kshname) - 3], "/sh") -+ || !strcmp(kshname, "sh") || !strcmp(kshname, "-sh")) -+ Flag(FSH) = 1; -+ -+ /* Set edit mode to emacs by default, may be overridden -+ * by the environment or the user. Also, we want tab completion -+ * on in vi by default. */ -+#if defined(EDIT) && defined(EMACS) -+ change_flag(FEMACS, OF_SPECIAL, 1); -+#endif /* EDIT && EMACS */ -+ #if defined(EDIT) && defined(VI) -+ Flag(FVITABCOMPLETE) = 1; -+#endif /* EDIT && VI */ -+#endif /* DEBIAN */ -+ -+ /* import environment */ - if (environ != NULL) - for (wp = environ; *wp != NULL; wp++) - typeset(*wp, IMPORT|EXPORT, 0, 0, 0); -Index: pdksh-5.2.14/misc.c -=================================================================== ---- pdksh-5.2.14.orig/misc.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/misc.c 2009-09-17 00:32:08.000000000 +0200 -@@ -159,6 +159,7 @@ - { "posix", 0, OF_ANY }, /* non-standard */ - { "privileged", 'p', OF_ANY }, - { "restricted", 'r', OF_CMDLINE }, -+ { "sh", 0, OF_ANY }, /* non-standard */ /* from OpenBSD */ - { "stdin", 's', OF_CMDLINE }, /* pseudo non-standard */ - { "trackall", 'h', OF_ANY }, - { "verbose", 'v', OF_ANY }, -@@ -309,8 +310,15 @@ - #ifdef OS2 - ; - #else /* OS2 */ -+#ifndef DEBIAN - setuid(ksheuid = getuid()); - setgid(getgid()); -+#else /* patch from OpenBSD */ -+ seteuid(ksheuid = getuid()); -+ setuid(ksheuid); -+ setegid(getgid()); -+ setgid(getgid()); -+#endif /* DEBIAN */ - #endif /* OS2 */ - } else if (f == FPOSIX && newval) { - #ifdef BRACE_EXPAND -@@ -471,6 +479,7 @@ - const char *as; - int *ai; - { -+#ifndef DEBIAN - const char *s; - register int n; - int sawdigit = 0; -@@ -484,6 +493,19 @@ - if (*s || !sawdigit) - return 0; - return 1; -+#else /* patch from OpenBSD */ -+ char *p; -+ long n; -+ -+ n = strtol(as, &p, 10); -+ -+ if (!*as || *p || INT_MIN >= n || n >= INT_MAX) -+ return 0; -+ -+ *ai = (int)n; -+ return 1; -+#endif -+ - } - - /* getn() that prints error */ -Index: pdksh-5.2.14/sh.h -=================================================================== ---- pdksh-5.2.14.orig/sh.h 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/sh.h 2009-09-17 00:32:08.000000000 +0200 -@@ -382,7 +382,11 @@ - */ - - typedef struct Area { -+#ifndef DEBIAN - struct Block *freelist; /* free list */ -+#else /* patch from OpenBSD */ -+ struct link *freelist; /* free list */ -+#endif - } Area; - - EXTERN Area aperm; /* permanent object space */ -@@ -501,6 +505,7 @@ - FPOSIX, /* -o posix: be posixly correct */ - FPRIVILEGED, /* -p: use suid_profile */ - FRESTRICTED, /* -r: restricted shell */ -+ FSH, /* -o sh: favor sh behavour */ - FSTDIN, /* -s: (invocation) parse stdin */ - FTRACKALL, /* -h: create tracked aliases for all commands */ - FVERBOSE, /* -v: echo input */ -Index: pdksh-5.2.14/tests/th -=================================================================== ---- pdksh-5.2.14.orig/tests/th 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/tests/th 2009-09-17 00:32:08.000000000 +0200 -@@ -1,4 +1,4 @@ --#!/usr/local/bin/perl -+#!/usr/bin/perl - - # - # Test harness for pdksh tests. -@@ -131,7 +131,7 @@ - $os = defined $^O ? $^O : 'unknown'; - - require 'signal.ph' unless $os eq 'os2'; --require 'errno.ph' unless $os eq 'os2'; -+# require 'errno.ph' unless $os eq 'os2'; - require 'getopts.pl'; - - ($prog = $0) =~ s#.*/##; -Index: pdksh-5.2.14/trap.c -=================================================================== ---- pdksh-5.2.14.orig/trap.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/trap.c 2009-09-17 00:32:08.000000000 +0200 -@@ -68,6 +68,8 @@ - alarm_catcher(sig) - int sig; - { -+ int errno_ = errno; -+ - if (ksh_tmout_state == TMOUT_READING) { - int left = alarm(0); - -@@ -77,6 +79,7 @@ - } else - alarm(left); - } -+ errno = errno_; - return RETSIGVAL; - } - #endif /* KSH */ -@@ -111,6 +114,7 @@ - int i; - { - Trap *p = &sigtraps[i]; -+ int errno_ = errno; - - trap = p->set = 1; - if (p->flags & TF_DFL_INTR) -@@ -125,6 +129,7 @@ - if (sigtraps[i].cursig == trapsig) /* this for SIGCHLD,SIGALRM */ - sigaction(i, &Sigact_trap, (struct sigaction *) 0); - #endif /* V7_SIGNALS */ -+ errno = errno_; - return RETSIGVAL; - } - -Index: pdksh-5.2.14/tree.c -=================================================================== ---- pdksh-5.2.14.orig/tree.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/tree.c 2009-09-17 00:32:08.000000000 +0200 -@@ -506,7 +506,7 @@ - for (tw = t->vars; *tw++ != NULL; ) - ; - rw = r->vars = (char **) -- alloc((int)(tw - t->vars) * sizeof(*tw), ap); -+ alloc((tw - t->vars + 1) * sizeof(*tw), ap); - for (tw = t->vars; *tw != NULL; ) - *rw++ = wdcopy(*tw++, ap); - *rw = NULL; -@@ -518,7 +518,7 @@ - for (tw = t->args; *tw++ != NULL; ) - ; - rw = r->args = (char **) -- alloc((int)(tw - t->args) * sizeof(*tw), ap); -+ alloc((tw - t->args + 1) * sizeof(*tw), ap); - for (tw = t->args; *tw != NULL; ) - *rw++ = wdcopy(*tw++, ap); - *rw = NULL; -@@ -679,7 +679,7 @@ - - for (ior = iow; *ior++ != NULL; ) - ; -- ior = (struct ioword **) alloc((int)(ior - iow) * sizeof(*ior), ap); -+ ior = (struct ioword **) alloc((ior - iow + 1) * sizeof(*ior), ap); - - for (i = 0; iow[i] != NULL; i++) { - register struct ioword *p, *q; -Index: pdksh-5.2.14/c_test.c -=================================================================== ---- pdksh-5.2.14.orig/c_test.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/c_test.c 2009-09-17 00:32:08.000000000 +0200 -@@ -124,10 +124,10 @@ - te.pos.wp = wp + 1; - te.wp_end = wp + argc; - -- /* -+ /* - * Handle the special cases from POSIX.2, section 4.62.4. -- * Implementation of all the rules isn't necessary since -- * our parser does the right thing for the ommited steps. -+ * Implementation of all the rules isn't necessary since -+ * our parser does the right thing for the omitted steps. - */ - if (argc <= 5) { - char **owp = wp; -@@ -238,7 +238,7 @@ - if (not) - res = !res; - } -- return res; -+ return res; - case TO_FILRD: /* -r */ - return test_eaccess(opnd1, R_OK) == 0; - case TO_FILWR: /* -w */ -@@ -456,10 +456,12 @@ - } - #endif /* !HAVE_DEV_FD */ - -- /* On most (all?) unixes, access() says everything is executable for -+ res = eaccess(path, mode); -+ /* -+ * On most (all?) unixes, access() says everything is executable for - * root - avoid this on files by using stat(). - */ -- if ((mode & X_OK) && ksheuid == 0) { -+ if (res == 0 && ksheuid == 0 && (mode & X_OK)) { - struct stat statb; - - if (stat(path, &statb) < 0) -@@ -469,13 +471,7 @@ - else - res = (statb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) - ? 0 : -1; -- /* Need to check other permissions? If so, use access() as -- * this will deal with root on NFS. -- */ -- if (res == 0 && (mode & (R_OK|W_OK))) -- res = eaccess(path, mode); -- } else -- res = eaccess(path, mode); -+ } - - return res; - } -Index: pdksh-5.2.14/eval.c -=================================================================== ---- pdksh-5.2.14.orig/eval.c 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/eval.c 2009-09-17 00:32:08.000000000 +0200 -@@ -870,8 +870,11 @@ - openpipe(pv); - shf = shf_fdopen(pv[0], SHF_RD, (struct shf *) 0); - ofd1 = savefd(1, 0); /* fd 1 may be closed... */ -- ksh_dup2(pv[1], 1, FALSE); -- close(pv[1]); -+ if (pv[1] != 1) { -+ ksh_dup2(pv[1], 1, FALSE); -+ close(pv[1]); -+ } -+ - execute(t, XFORK|XXCOM|XPIPEO); - restfd(1, ofd1); - startlast(); -Index: pdksh-5.2.14/tests/regress.t -=================================================================== ---- pdksh-5.2.14.orig/tests/regress.t 2009-09-17 00:31:58.000000000 +0200 -+++ pdksh-5.2.14/tests/regress.t 2009-09-17 00:32:08.000000000 +0200 -@@ -156,11 +156,12 @@ - echo $? - shoud not print 0. (according to /bin/sh, at&t ksh88, and the - getopt(1) man page - not according to POSIX) -+ For Debian - it should print 0, cf. bug#118476. - stdin: - set -- `false` - echo $? - expected-stdout: -- 1 -+ 0 - --- - - |