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