This can be hard to debug, and could indeed prevent debugging, since
it can take out the ability to run /bin/sh, depending on how you've
set up your environment.

Before:
$ HISTSIZE=1000000000 /bin/sh
/bin/sh: internal error: unable to allocate memory
<crashes>          <--- no ksh

With this pa
$ HISTSIZE=1000000000 ./ksh
./ksh: internal error: unable to allocate 16+8000000008 bytes of memory
Unable to set the history size to 1000000000
hostname$ ^D       <--- ksh running

diff --git a/bin/ksh/alloc.c b/bin/ksh/alloc.c
index 204e835890c..6e29e2eb3fe 100644
--- a/bin/ksh/alloc.c
+++ b/bin/ksh/alloc.c
@@ -97,7 +97,7 @@ aresize(void *ptr, size_t size, Area *ap)

        l2 = realloc(l, sizeof(struct link) + size);
        if (l2 == NULL)
-               internal_errorf("unable to allocate memory");
+               internal_errorf("unable to allocate %lu+%lu bytes of memory",
sizeof(struct link), size);
        if (lprev)
                lprev->next = l2;
        else
diff --git a/bin/ksh/history.c b/bin/ksh/history.c
index a3a8b60cc76..3bd6444d7a9 100644
--- a/bin/ksh/history.c
+++ b/bin/ksh/history.c
@@ -549,10 +549,17 @@ sethistcontrol(const char *str)
 /*
  *     set history
  *     this means reallocating the dataspace
+ *     if memory allocation fails then history size will remain unchanged
  */
 void
 sethistsize(int n)
 {
+       newenv(E_FUNC);
+       if (sigsetjmp(genv->jbuf, 0)) {
+               fprintf(stderr, "Unable to set the history size to %d\n", n);
+               quitenv(NULL);
+               return;
+       }
        if (n > 0 && (uint32_t)n != histsize) {
                int offset = histptr - history;

@@ -566,8 +573,8 @@ sethistsize(int n)
                        memmove(history, histptr - offset, n * sizeof(char *));
                }

-               histsize = n;
                histbase = areallocarray(histbase, n + 1, sizeof(char *), 
APERM);
+               histsize = n;
                history = histbase + 1;
                histptr = history + offset;
        }

Reply via email to