diff --git a/check.t b/check.t index 7de6af9..c3c7c58 100644 --- a/check.t +++ b/check.t @@ -1,4 +1,4 @@ -# $MirOS: src/bin/mksh/check.t,v 1.722 2016/01/21 18:24:35 tg Exp $ +# $MirOS: src/bin/mksh/check.t,v 1.724 2016/02/24 01:47:30 tg Exp $ # -*- mode: sh -*- #- # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, @@ -30,7 +30,7 @@ # (2013/12/02 20:39:44) http://openbsd.cs.toronto.edu/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date expected-stdout: - @(#)MIRBSD KSH R52 2016/01/21 + @(#)MIRBSD KSH R52 2016/02/23 description: Check version of shell. stdin: @@ -39,7 +39,7 @@ name: KSH_VERSION category: shell:legacy-no --- expected-stdout: - @(#)LEGACY KSH R52 2016/01/21 + @(#)LEGACY KSH R52 2016/02/23 description: Check version of legacy shell. stdin: @@ -1858,7 +1858,7 @@ stdin: [[ -n $BASH_VERSION ]] && shopt -s extglob x=1222321_ab/cde_b/c_1221 y=xyz - echo 1: ${x/2} + echo 1: ${x/2} . ${x/} echo 2: ${x//2} echo 3: ${x/+(2)} echo 4: ${x//+(2)} @@ -1890,7 +1890,7 @@ stdin: echo 30: ${x//\\a/9} echo 31: ${x/2/$y} expected-stdout: - 1: 122321_ab/cde_b/c_1221 + 1: 122321_ab/cde_b/c_1221 . 1222321_ab/cde_b/c_1221 2: 131_ab/cde_b/c_11 3: 1321_ab/cde_b/c_1221 4: 131_ab/cde_b/c_11 @@ -12183,7 +12183,7 @@ stdin: Copyright (C) 2002 Free Software Foundation, Inc.' EOF chmod +x bash - "$__progname" -xc 'foo=$(./bash --version 2>&1 | head -1); echo "=$foo="' + "$__progname" -xc 'foo=$(./bash --version 2>&1 | sed 1q); echo "=$foo="' expected-stdout: =GNU bash, version 2.05b.0(1)-release (i386-ecce-mirbsd10)= expected-stderr-pattern: diff --git a/eval.c b/eval.c index e3a9c5d..edd3003 100644 --- a/eval.c +++ b/eval.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.181 2016/01/21 18:24:38 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.182 2016/02/24 01:47:32 tg Exp $"); /* * string expansion @@ -1151,7 +1151,7 @@ varsub(Expand *xp, const char *sp, const char *word, if (!stype && c == '/') { slen += 2; stype = c; - if (word[slen] == ADELIM) { + if (word[slen] == ADELIM && word[slen + 1] == c) { slen += 2; stype |= 0x80; } diff --git a/histrap.c b/histrap.c index 4c16fb8..5932ea3 100644 --- a/histrap.c +++ b/histrap.c @@ -27,7 +27,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.153 2016/01/21 18:24:40 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.154 2016/02/24 01:45:59 tg Exp $"); Trap sigtraps[ksh_NSIG + 1]; static struct sigaction Sigact_ign; @@ -658,7 +658,9 @@ histsave(int *lnp, const char *cmd, int svmode, bool ignoredups) strndupx(c, cmd, ccp - cmd, APERM); if (svmode != HIST_APPEND) { - if (ignoredups && !strcmp(c, *histptr) + if (ignoredups && + histptr >= history && + !strcmp(c, *histptr) #if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY && !histsync() #endif diff --git a/jobs.c b/jobs.c index 6c2ca13..38e7b39 100644 --- a/jobs.c +++ b/jobs.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.118 2016/01/21 18:24:41 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.119 2016/02/24 01:44:45 tg Exp $"); #if HAVE_KILLPG #define mksh_killpg killpg @@ -45,8 +45,8 @@ struct proc { int state; int status; /* wait status */ /* process command string from vistree */ - char command[256 - (ALLOC_SIZE + sizeof(Proc *) + sizeof(pid_t) + - 2 * sizeof(int))]; + char command[256 - (ALLOC_OVERHEAD + sizeof(Proc *) + + sizeof(pid_t) + 2 * sizeof(int))]; }; /* Notify/print flag - j_print() argument */ diff --git a/lalloc.c b/lalloc.c index 4eca6a5..a120760 100644 --- a/lalloc.c +++ b/lalloc.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009, 2010, 2011, 2013, 2014 + * Copyright (c) 2009, 2010, 2011, 2013, 2014, 2016 * mirabilos * * Provided that these terms and disclaimer and all copyright notices @@ -19,8 +19,11 @@ */ #include "sh.h" +#ifdef MKSH_ALLOC_CATCH_UNDERRUNS +#include +#endif -__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.23 2015/11/29 17:05:01 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.25 2016/02/24 02:08:39 tg Exp $"); /* build with CPPFLAGS+= -DUSE_REALLOC_MALLOC=0 on ancient systems */ #if defined(USE_REALLOC_MALLOC) && (USE_REALLOC_MALLOC == 0) @@ -29,19 +32,72 @@ __RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.23 2015/11/29 17:05:01 tg Exp $"); #define remalloc(p,n) realloc_osi((p), (n)) #endif -#define ALLOC_ISUNALIGNED(p) (((size_t)(p)) % ALLOC_SIZE) -static ALLOC_ITEM *findptr(ALLOC_ITEM **, char *, Area *); +static struct lalloc_common *findptr(struct lalloc_common **, char *, Area *); + +#ifndef MKSH_ALLOC_CATCH_UNDERRUNS +#define ALLOC_ISUNALIGNED(p) (((size_t)(p)) % ALLOC_SIZE) +#else +#define ALLOC_ISUNALIGNED(p) (((size_t)(p)) & 4095) +#undef remalloc +#undef free_osimalloc + +static void +free_osimalloc(void *ptr) +{ + struct lalloc_item *lp = ptr; + + if (munmap(lp, lp->len)) + err(1, "free_osimalloc"); +} + +static void * +remalloc(void *ptr, size_t size) +{ + struct lalloc_item *lp, *lold = ptr; + + size = (size + 4095) & ~(size_t)4095; + + if (lold && lold->len >= size) + return (ptr); + + if ((lp = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, (off_t)0)) == MAP_FAILED) + err(1, "remalloc: mmap(%zu)", size); + if (ALLOC_ISUNALIGNED(lp)) + errx(1, "remalloc: unaligned(%p)", lp); + if (mprotect(((char *)lp) + 4096, 4096, PROT_NONE)) + err(1, "remalloc: mprotect"); + lp->len = size; + + if (lold) { + memcpy(((char *)lp) + 8192, ((char *)lold) + 8192, + lold->len - 8192); + if (munmap(lold, lold->len)) + err(1, "remalloc: munmap"); + } + + return (lp); +} +#endif void ainit(Area *ap) { - /* area pointer is an ALLOC_ITEM, just the head of the list */ +#ifdef MKSH_ALLOC_CATCH_UNDERRUNS + if (sysconf(_SC_PAGESIZE) != 4096) { + fprintf(stderr, "mksh: fatal: pagesize %lu not 4096!\n", + sysconf(_SC_PAGESIZE)); + fflush(stderr); + abort(); + } +#endif + /* area pointer and items share struct lalloc_common */ ap->next = NULL; } -static ALLOC_ITEM * -findptr(ALLOC_ITEM **lpp, char *ptr, Area *ap) +static struct lalloc_common * +findptr(struct lalloc_common **lpp, char *ptr, Area *ap) { void *lp; @@ -70,7 +126,7 @@ findptr(ALLOC_ITEM **lpp, char *ptr, Area *ap) internal_errorf("rogue pointer %zX", (size_t)ptr); #endif } - return (ap); + return ((void *)ap); } void * @@ -84,11 +140,11 @@ aresize2(void *ptr, size_t fac1, size_t fac2, Area *ap) void * aresize(void *ptr, size_t numb, Area *ap) { - ALLOC_ITEM *lp = NULL; + struct lalloc_common *lp = NULL; /* resizing (true) or newly allocating? */ if (ptr != NULL) { - ALLOC_ITEM *pp; + struct lalloc_common *pp; pp = findptr(&lp, ptr, ap); pp->next = lp->next; @@ -101,7 +157,7 @@ aresize(void *ptr, size_t numb, Area *ap) #endif ) internal_errorf(Toomem, numb); - /* this only works because Area is an ALLOC_ITEM */ + /* this only works because Area and ALLOC_ITEM share lalloc_common */ lp->next = ap->next; ap->next = lp; /* return user item address */ @@ -112,7 +168,7 @@ void afree(void *ptr, Area *ap) { if (ptr != NULL) { - ALLOC_ITEM *lp, *pp; + struct lalloc_common *lp, *pp; pp = findptr(&lp, ptr, ap); /* unhook */ @@ -125,7 +181,7 @@ afree(void *ptr, Area *ap) void afreeall(Area *ap) { - ALLOC_ITEM *lp; + struct lalloc_common *lp; /* traverse group (linked list) */ while ((lp = ap->next) != NULL) { diff --git a/lksh.1 b/lksh.1 index 8b26166..a1a8337 100644 --- a/lksh.1 +++ b/lksh.1 @@ -1,6 +1,6 @@ -.\" $MirOS: src/bin/mksh/lksh.1,v 1.16 2015/12/12 22:25:14 tg Exp $ +.\" $MirOS: src/bin/mksh/lksh.1,v 1.17 2016/02/11 20:12:09 tg Exp $ .\"- -.\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015 +.\" Copyright (c) 2008, 2009, 2010, 2012, 2013, 2015, 2016 .\" mirabilos .\" .\" Provided that these terms and disclaimer and all copyright notices @@ -27,7 +27,9 @@ .\" * ^ is size-reduced and placed atop in groff, so use \*(ha .\" * \(en does not work in nroff, so use \*(en .\" * <>| are problematic, so redefine and use \*(Lt\*(Gt\*(Ba -.\" Also make sure to use \& especially with two-letter words. +.\" Also make sure to use \& *before* a punctuation char that is to not +.\" be interpreted as punctuation, and especially with two-letter words +.\" but also (after) a period that does not end a sentence (“e.g.\&”). .\" The section after the "doc" macropackage has been loaded contains .\" additional code to convene between the UCB mdoc macropackage (and .\" its variant as BSD mdoc in groff) and the GNU mdoc macropackage. @@ -72,7 +74,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: December 12 2015 $ +.Dd $Mdocdate: February 11 2016 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" diff --git a/main.c b/main.c index 7ec7875..2cdb1d5 100644 --- a/main.c +++ b/main.c @@ -34,7 +34,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.307 2016/01/21 18:24:42 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.308 2016/02/24 01:44:46 tg Exp $"); extern char **environ; @@ -130,6 +130,9 @@ rndsetup(void) /* introduce variation (and yes, second arg MBZ for portability) */ mksh_TIME(bufptr->tv); +#ifdef MKSH_ALLOC_CATCH_UNDERRUNS + mprotect(((char *)bufptr) + 4096, 4096, PROT_READ | PROT_WRITE); +#endif h = chvt_rndsetup(bufptr, sizeof(*bufptr)); afree(cp, APERM); diff --git a/mksh.1 b/mksh.1 index 923c721..c6f9736 100644 --- a/mksh.1 +++ b/mksh.1 @@ -1,4 +1,4 @@ -.\" $MirOS: src/bin/mksh/mksh.1,v 1.388 2016/01/20 22:04:54 tg Exp $ +.\" $MirOS: src/bin/mksh/mksh.1,v 1.389 2016/02/11 19:00:50 tg Exp $ .\" $OpenBSD: ksh.1,v 1.160 2015/07/04 13:27:04 feinerer Exp $ .\"- .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, @@ -29,7 +29,9 @@ .\" * ^ is size-reduced and placed atop in groff, so use \*(ha .\" * \(en does not work in nroff, so use \*(en .\" * <>| are problematic, so redefine and use \*(Lt\*(Gt\*(Ba -.\" Also make sure to use \& especially with two-letter words. +.\" Also make sure to use \& *before* a punctuation char that is to not +.\" be interpreted as punctuation, and especially with two-letter words +.\" but also (after) a period that does not end a sentence (“e.g.\&”). .\" The section after the "doc" macropackage has been loaded contains .\" additional code to convene between the UCB mdoc macropackage (and .\" its variant as BSD mdoc in groff) and the GNU mdoc macropackage. @@ -74,7 +76,7 @@ .\" with -mandoc, it might implement .Mx itself, but we want to .\" use our own definition. And .Dd must come *first*, always. .\" -.Dd $Mdocdate: January 20 2016 $ +.Dd $Mdocdate: February 11 2016 $ .\" .\" Check which macro package we use, and do other -mdoc setup. .\" @@ -431,7 +433,7 @@ statements; .Ql \&(( .. )) is used in arithmetic expressions; and lastly, -.Ql \&( .. )\& +.Ql \&( .. \&) is used to create subshells. .Pp Whitespace and meta-characters can be quoted individually using a backslash @@ -1943,7 +1945,7 @@ Time since the epoch, as returned by formatted as decimal .Va tv_sec followed by a dot -.Pq Sq .\& +.Pq Sq \&. and .Va tv_usec padded to exactly six decimal digits. @@ -3979,14 +3981,14 @@ becomes unusable, and directly calls .Pp .It Ic return Op Ar status Returns from a function or -.Ic .\& +.Ic \&. script, with exit status .Ar status . If no .Ar status is given, the exit status of the last executed command is used. If used outside of a function or -.Ic .\& +.Ic \&. script, it has the same effect as .Ic exit . Note that @@ -3994,9 +3996,9 @@ Note that treats both profile and .Ev ENV files as -.Ic .\& +.Ic \&. scripts, while the original Korn shell only treats profiles as -.Ic .\& +.Ic \&. scripts. .Pp .It Xo @@ -4074,7 +4076,7 @@ explicitly tested by a shell construct such as .Ic until , .Ic while , or -.Ic !\& +.Ic \&! statements. For .Ic && diff --git a/sh.h b/sh.h index 91ce8ad..7ea718b 100644 --- a/sh.h +++ b/sh.h @@ -175,9 +175,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.760 2016/01/21 19:58:13 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.762 2016/02/24 02:08:39 tg Exp $"); #endif -#define MKSH_VERSION "R52 2016/01/21" +#define MKSH_VERSION "R52 2016/02/23" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES @@ -699,16 +699,29 @@ im_sorry_dave(void) /* 1. internal structure */ -struct lalloc { - struct lalloc *next; +struct lalloc_common { + struct lalloc_common *next; +}; + +struct lalloc_item { + struct lalloc_common *next; +#ifdef MKSH_ALLOC_CATCH_UNDERRUNS + size_t len; + char dummy[8192 - sizeof(struct lalloc_common *) - sizeof(size_t)]; +#endif }; /* 2. sizes */ -#define ALLOC_ITEM struct lalloc +#define ALLOC_ITEM struct lalloc_item #define ALLOC_SIZE (sizeof(ALLOC_ITEM)) +#ifndef MKSH_ALLOC_CATCH_UNDERRUNS +#define ALLOC_OVERHEAD ALLOC_SIZE +#else +#define ALLOC_OVERHEAD 0 +#endif -/* 3. group structure (only the same for lalloc.c) */ -typedef struct lalloc Area; +/* 3. group structure */ +typedef struct lalloc_common Area; EXTERN Area aperm; /* permanent object space */ @@ -1073,7 +1086,7 @@ EXTERN bool builtin_spec; EXTERN char *current_wd; /* input line size */ -#define LINE (4096 - ALLOC_SIZE) +#define LINE (4096 - ALLOC_OVERHEAD) /* * Minimum required space to work with on a line - if the prompt leaves * less space than this on a line, the prompt is truncated.