d6ea3b
diff --git a/include/typemax.h b/include/typemax.h
d6ea3b
--- a/include/typemax.h
d6ea3b
+++ b/include/typemax.h
d6ea3b
@@ -35,14 +35,23 @@
d6ea3b
 #  define TYPE_SIGNED(t)	(! ((t) 0 < (t) -1))
d6ea3b
 #endif
d6ea3b
 
d6ea3b
+#ifndef TYPE_SIGNED_MAGNITUDE
d6ea3b
+#  define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)
d6ea3b
+#endif
d6ea3b
+
d6ea3b
+#ifndef TYPE_WIDTH
d6ea3b
+#  define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)
d6ea3b
+#endif
d6ea3b
+
d6ea3b
 #ifndef TYPE_MINIMUM
d6ea3b
-#  define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
d6ea3b
-				? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) \
d6ea3b
-				: (t) 0))
d6ea3b
+#  define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t))
d6ea3b
 #endif
d6ea3b
 
d6ea3b
 #ifndef TYPE_MAXIMUM
d6ea3b
-#  define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
d6ea3b
+#  define TYPE_MAXIMUM(t)  \
d6ea3b
+  ((t) (! TYPE_SIGNED (t) \
d6ea3b
+        ? (t) -1 \
d6ea3b
+        : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1)))
d6ea3b
 #endif
d6ea3b
 
d6ea3b
 #ifdef HAVE_LONG_LONG
d6ea3b
diff --git a/jobs.c b/jobs.c
d6ea3b
--- a/jobs.c
d6ea3b
+++ b/jobs.c
d6ea3b
@@ -72,6 +72,8 @@
d6ea3b
 #include "execute_cmd.h"
d6ea3b
 #include "flags.h"
d6ea3b
 
d6ea3b
+#include "typemax.h"
d6ea3b
+
d6ea3b
 #include "builtins/builtext.h"
d6ea3b
 #include "builtins/common.h"
d6ea3b
 
d6ea3b
@@ -92,7 +94,7 @@ extern int killpg __P((pid_t, int));
d6ea3b
 #endif
d6ea3b
 
d6ea3b
 #if !MAX_CHILD_MAX
d6ea3b
-#  define MAX_CHILD_MAX 8192
d6ea3b
+#  define MAX_CHILD_MAX 32768
d6ea3b
 #endif
d6ea3b
 
d6ea3b
 #if !defined (DEBUG)
d6ea3b
@@ -751,7 +753,7 @@ stop_pipeline (async, deferred)
d6ea3b
 static void
d6ea3b
 bgp_resize ()
d6ea3b
 {
d6ea3b
-  ps_index_t nsize;
d6ea3b
+  ps_index_t nsize, nsize_cur, nsize_max;
d6ea3b
   ps_index_t psi;
d6ea3b
 
d6ea3b
   if (bgpids.nalloc == 0)
d6ea3b
@@ -765,11 +767,20 @@ bgp_resize ()
d6ea3b
   else
d6ea3b
     nsize = bgpids.nalloc;
d6ea3b
 
d6ea3b
-  while (nsize < js.c_childmax)
d6ea3b
-    nsize *= 2;
d6ea3b
+  nsize_max = TYPE_MAXIMUM (ps_index_t);
d6ea3b
+  nsize_cur = (ps_index_t)js.c_childmax;
d6ea3b
+  if (nsize_cur < 0)				/* overflow */
d6ea3b
+    nsize_cur = MAX_CHILD_MAX;
d6ea3b
 
d6ea3b
-  if (bgpids.nalloc < js.c_childmax)
d6ea3b
-    {
d6ea3b
+  while (nsize > 0 && nsize < nsize_cur)	/* > 0 should catch overflow */
d6ea3b
+    nsize <<= 1;
d6ea3b
+  if (nsize > nsize_max || nsize <= 0)		/* overflow? */
d6ea3b
+    nsize = nsize_max;
d6ea3b
+  if (nsize > MAX_CHILD_MAX)
d6ea3b
+    nsize = nsize_max = MAX_CHILD_MAX;		/* hard cap */
d6ea3b
+
d6ea3b
+  if (bgpids.nalloc < nsize_cur && bgpids.nalloc < nsize_max)
d6ea3b
+  {
d6ea3b
       bgpids.storage = (struct pidstat *)xrealloc (bgpids.storage, nsize * sizeof (struct pidstat));
d6ea3b
 
d6ea3b
       for (psi = bgpids.nalloc; psi < nsize; psi++)
d6ea3b
@@ -787,7 +798,7 @@ bgp_getindex ()
d6ea3b
 {
d6ea3b
   ps_index_t psi;
d6ea3b
 
d6ea3b
-  if (bgpids.nalloc < js.c_childmax || bgpids.head >= bgpids.nalloc)
d6ea3b
+  if (bgpids.nalloc < (ps_index_t)js.c_childmax || bgpids.head >= bgpids.nalloc)
d6ea3b
     bgp_resize ();
d6ea3b
 
d6ea3b
   pshash_delindex (bgpids.head);		/* XXX - clear before reusing */