diff options
Diffstat (limited to 'missing')
| -rw-r--r-- | missing/dtoa.c | 325 | ||||
| -rw-r--r-- | missing/explicit_bzero.c | 5 | ||||
| -rw-r--r-- | missing/procstat_vm.c | 34 | ||||
| -rw-r--r-- | missing/setproctitle.c | 68 |
4 files changed, 262 insertions, 170 deletions
diff --git a/missing/dtoa.c b/missing/dtoa.c index b7a8302875..ba8cd46ebd 100644 --- a/missing/dtoa.c +++ b/missing/dtoa.c @@ -98,17 +98,6 @@ * if memory is available and otherwise does something you deem * appropriate. If MALLOC is undefined, malloc will be invoked * directly -- and assumed always to succeed. - * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making - * memory allocations from a private pool of memory when possible. - * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, - * unless #defined to be a different length. This default length - * suffices to get rid of MALLOC calls except for unusual cases, - * such as decimal-to-binary conversion of a very long string of - * digits. The longest string dtoa can return is about 751 bytes - * long. For conversions by strtod of strings of 800 digits and - * all dtoa conversions in single-threaded executions with 8-byte - * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte - * pointers, PRIVATE_MEM >= 7112 appears adequate. * #define INFNAN_CHECK on IEEE systems to cause strtod to check for * Infinity and NaN (case insensitively). On some systems (e.g., * some HP systems), it may be necessary to #define NAN_WORD0 @@ -183,7 +172,10 @@ #undef Long #undef ULong +#include <assert.h> #include <limits.h> +#include <stddef.h> +#include <stdint.h> #if (INT_MAX >> 30) && !(INT_MAX >> 31) #define Long int @@ -195,7 +187,7 @@ #error No 32bit integer #endif -#if HAVE_LONG_LONG +#if defined(HAVE_LONG_LONG) && (HAVE_LONG_LONG) #define Llong LONG_LONG #else #define NO_LONG_LONG @@ -218,28 +210,43 @@ #include <locale.h> #endif +#if defined(HAVE_STDCKDINT_H) || !defined(__has_include) +#elif __has_include(<stdckdint.h>) +# define HAVE_STDCKDINT_H 1 +#endif +#ifdef HAVE_STDCKDINT_H +# include <stdckdint.h> +#endif + +#if !defined(ckd_add) +static inline int /* bool */ +ckd_add(int *result, int x, int y) +{ + if (x < 0) { + if (y < INT_MIN - x) return 1; + } + else if (x > 0) { + if (y > INT_MAX - x) return 1; + } + *result = x + y; + return 0; +} +#endif + #ifdef MALLOC extern void *MALLOC(size_t); #else -#define MALLOC xmalloc +#define MALLOC malloc #endif #ifdef FREE extern void FREE(void*); #else -#define FREE xfree +#define FREE free #endif #ifndef NO_SANITIZE #define NO_SANITIZE(x, y) y #endif -#ifndef Omit_Private_Memory -#ifndef PRIVATE_MEM -#define PRIVATE_MEM 2304 -#endif -#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) -static double private_mem[PRIVATE_mem], *pmem_next = private_mem; -#endif - #undef IEEE_Arith #undef Avoid_Underflow #ifdef IEEE_BIG_ENDIAN @@ -502,7 +509,7 @@ extern double rnd_prod(double, double), rnd_quot(double, double); #endif #ifndef ATOMIC_PTR_CAS -#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (old)) +#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (void *)(old)) #endif #ifndef LIKELY #define LIKELY(x) (x) @@ -524,83 +531,29 @@ struct Bigint { typedef struct Bigint Bigint; -static Bigint *freelist[Kmax+1]; - -#define BLOCKING_BIGINT ((Bigint *)(-1)) - static Bigint * Balloc(int k) { int x; Bigint *rv; -#ifndef Omit_Private_Memory - size_t len; -#endif - - rv = 0; - ACQUIRE_DTOA_LOCK(0); - if (k <= Kmax) { - rv = freelist[k]; - while (rv) { - Bigint *rvn = rv; - rv = ATOMIC_PTR_CAS(freelist[k], rv, BLOCKING_BIGINT); - if (LIKELY(rv != BLOCKING_BIGINT && rvn == rv)) { - rvn = ATOMIC_PTR_CAS(freelist[k], BLOCKING_BIGINT, rv->next); - assert(rvn == BLOCKING_BIGINT); - ASSUME(rv); - break; - } - } - } - if (!rv) { - x = 1 << k; -#ifdef Omit_Private_Memory - rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); -#else - len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) - /sizeof(double); - if (k <= Kmax) { - double *pnext = pmem_next; - while (pnext - private_mem + len <= PRIVATE_mem) { - double *p = pnext; - pnext = ATOMIC_PTR_CAS(pmem_next, pnext, pnext + len); - if (LIKELY(p == pnext)) { - rv = (Bigint*)pnext; - ASSUME(rv); - break; - } - } - } - if (!rv) - rv = (Bigint*)MALLOC(len*sizeof(double)); -#endif - rv->k = k; - rv->maxwds = x; - } - FREE_DTOA_LOCK(0); + + x = 1 << k; + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); + if (!rv) return NULL; + rv->k = k; + rv->maxwds = x; rv->sign = rv->wds = 0; return rv; } static void -Bfree(Bigint *v) +Bclear(Bigint **vp) { - Bigint *vn; - if (v) { - if (v->k > Kmax) { - FREE(v); - return; - } - ACQUIRE_DTOA_LOCK(0); - do { - do { - vn = ATOMIC_PTR_CAS(freelist[v->k], 0, 0); - } while (UNLIKELY(vn == BLOCKING_BIGINT)); - v->next = vn; - } while (UNLIKELY(ATOMIC_PTR_CAS(freelist[v->k], vn, v) != vn)); - FREE_DTOA_LOCK(0); - } + Bigint *v = *vp; + *vp = NULL; + if (v) FREE(v); } +#define Bfree(v) Bclear(&(v)) #define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \ (y)->wds*sizeof(Long) + 2*sizeof(int)) @@ -646,6 +599,10 @@ multadd(Bigint *b, int m, int a) /* multiply by m and add a */ if (carry) { if (wds >= b->maxwds) { b1 = Balloc(b->k+1); + if (!b1) { + Bfree(b); + return NULL; + } Bcopy(b1, b); Bfree(b); b = b1; @@ -667,10 +624,12 @@ s2b(const char *s, int nd0, int nd, ULong y9) for (k = 0, y = 1; x > y; y <<= 1, k++) ; #ifdef Pack_32 b = Balloc(k); + if (!b) return NULL; b->x[0] = y9; b->wds = 1; #else b = Balloc(k+1); + if (!b) return NULL; b->x[0] = y9 & 0xffff; b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; #endif @@ -680,13 +639,16 @@ s2b(const char *s, int nd0, int nd, ULong y9) s += 9; do { b = multadd(b, 10, *s++ - '0'); + if (!b) return NULL; } while (++i < nd0); s++; } else s += 10; - for (; i < nd; i++) + for (; i < nd; i++) { b = multadd(b, 10, *s++ - '0'); + if (!b) return NULL; + } return b; } @@ -768,11 +730,14 @@ i2b(int i) Bigint *b; b = Balloc(1); + if (!b) return NULL; b->x[0] = i; b->wds = 1; return b; } +#define Bzero_p(b) (!(b)->x[0] && (b)->wds <= 1) + static Bigint * mult(Bigint *a, Bigint *b) { @@ -789,6 +754,14 @@ mult(Bigint *a, Bigint *b) #endif #endif + if (Bzero_p(a) || Bzero_p(b)) { + c = Balloc(0); + if (!c) return NULL; + c->wds = 1; + c->x[0] = 0; + return c; + } + if (a->wds < b->wds) { c = a; a = b; @@ -801,6 +774,7 @@ mult(Bigint *a, Bigint *b) if (wc > a->maxwds) k++; c = Balloc(k); + if (!c) return NULL; for (x = c->x, xa = x + wc; x < xa; x++) *x = 0; xa = a->x; @@ -880,50 +854,47 @@ static Bigint * pow5mult(Bigint *b, int k) { Bigint *b1, *p5, *p51; - Bigint *p5tmp; int i; static const int p05[3] = { 5, 25, 125 }; - if ((i = k & 3) != 0) + if ((i = k & 3) != 0) { b = multadd(b, p05[i-1], 0); + if (!b) return NULL; + } + +#define b_cache(var, addr, new_expr) \ + if ((var = addr) != 0) {} else { \ + Bigint *tmp = 0; \ + ACQUIRE_DTOA_LOCK(1); \ + if (!(var = addr) && (var = (new_expr)) != 0) { \ + var->next = 0; \ + tmp = ATOMIC_PTR_CAS(addr, NULL, var); \ + } \ + FREE_DTOA_LOCK(1); \ + if (UNLIKELY(tmp)) { \ + Bfree(var); \ + var = tmp; \ + } \ + else if (!var) { \ + Bfree(b); \ + return NULL; \ + } \ + } if (!(k >>= 2)) return b; - if (!(p5 = p5s)) { - /* first time */ - ACQUIRE_DTOA_LOCK(1); - if (!(p5 = p5s)) { - p5 = i2b(625); - p5->next = 0; - p5tmp = ATOMIC_PTR_CAS(p5s, NULL, p5); - if (UNLIKELY(p5tmp)) { - Bfree(p5); - p5 = p5tmp; - } - } - FREE_DTOA_LOCK(1); - } + /* first time */ + b_cache(p5, p5s, i2b(625)); for (;;) { if (k & 1) { b1 = mult(b, p5); Bfree(b); b = b1; + if (!b) return NULL; } if (!(k >>= 1)) break; - if (!(p51 = p5->next)) { - ACQUIRE_DTOA_LOCK(1); - if (!(p51 = p5->next)) { - p51 = mult(p5,p5); - p51->next = 0; - p5tmp = ATOMIC_PTR_CAS(p5->next, NULL, p51); - if (UNLIKELY(p5tmp)) { - Bfree(p51); - p51 = p5tmp; - } - } - FREE_DTOA_LOCK(1); - } + b_cache(p51, p5->next, mult(p5, p5)); p5 = p51; } return b; @@ -936,6 +907,8 @@ lshift(Bigint *b, int k) Bigint *b1; ULong *x, *x1, *xe, z; + if (!k || Bzero_p(b)) return b; + #ifdef Pack_32 n = k >> 5; #else @@ -946,6 +919,10 @@ lshift(Bigint *b, int k) for (i = b->maxwds; n1 > i; i <<= 1) k1++; b1 = Balloc(k1); + if (!b1) { + Bfree(b); + return NULL; + } x1 = b1->x; for (i = 0; i < n; i++) *x1++ = 0; @@ -1031,6 +1008,7 @@ diff(Bigint *a, Bigint *b) i = cmp(a,b); if (!i) { c = Balloc(0); + if (!c) return NULL; c->wds = 1; c->x[0] = 0; return c; @@ -1044,6 +1022,7 @@ diff(Bigint *a, Bigint *b) else i = 0; c = Balloc(a->k); + if (!c) return NULL; c->sign = i; wa = a->wds; xa = a->x; @@ -1229,6 +1208,7 @@ d2b(double d_, int *e, int *bits) #else b = Balloc(2); #endif + if (!b) return NULL; x = b->x; z = d0 & Frac_mask; @@ -1549,7 +1529,7 @@ break2: aadj = 1.0; nd0 = -4; - if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0; + if (!*++s || (!(s1 = strchr(hexdigit, *s)) && *s != '.')) goto ret0; if (*s == '0') { while (*++s == '0'); if (!*s) goto ret; @@ -1563,9 +1543,7 @@ break2: } while (*++s && (s1 = strchr(hexdigit, *s))); } - if (*s == '.') { - dsign = 1; - if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0; + if ((*s == '.') && *++s && (s1 = strchr(hexdigit, *s))) { if (nd0 < 0) { while (*s == '0') { s++; @@ -1580,9 +1558,6 @@ break2: } } } - else { - dsign = 0; - } if (*s == 'P' || *s == 'p') { dsign = 0x2C - *++s; /* +: 2B, -: 2D */ @@ -1605,9 +1580,6 @@ break2: } while ('0' <= c && c <= '9'); nd0 += nd * dsign; } - else { - if (dsign) goto ret0; - } dval(rv) = ldexp(adj, nd0); goto ret; } @@ -1644,9 +1616,9 @@ break2: } #endif if (c == '.') { - if (!ISDIGIT(s[1])) - goto dig_done; c = *++s; + if (!ISDIGIT(c)) + goto dig_done; if (!nd) { for (; c == '0'; c = *++s) nz++; @@ -1987,12 +1959,16 @@ undfl: /* Put digits into bd: true value = bd * 10^e */ bd0 = s2b(s0, nd0, nd, y); + if (!bd0) goto ret; for (;;) { bd = Balloc(bd0->k); + if (!bd) goto retfree; Bcopy(bd, bd0); bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + if (!bb) goto retfree; bs = i2b(1); + if (!bs) goto retfree; if (e >= 0) { bb2 = bb5 = 0; @@ -2049,19 +2025,30 @@ undfl: } if (bb5 > 0) { bs = pow5mult(bs, bb5); + if (!bs) goto retfree; bb1 = mult(bs, bb); Bfree(bb); bb = bb1; + if (!bb) goto retfree; } - if (bb2 > 0) + if (bb2 > 0) { bb = lshift(bb, bb2); - if (bd5 > 0) + if (!bb) goto retfree; + } + if (bd5 > 0) { bd = pow5mult(bd, bd5); - if (bd2 > 0) + if (!bd) goto retfree; + } + if (bd2 > 0) { bd = lshift(bd, bd2); - if (bs2 > 0) + if (!bd) goto retfree; + } + if (bs2 > 0) { bs = lshift(bs, bs2); + if (!bs) goto retfree; + } delta = diff(bb, bd); + if (!delta) goto retfree; dsign = delta->sign; delta->sign = 0; i = cmp(delta, bs); @@ -2094,6 +2081,7 @@ undfl: #endif { delta = lshift(delta,Log2P); + if (!delta) goto nomem; if (cmp(delta, bs) <= 0) adj = -0.5; } @@ -2183,6 +2171,7 @@ apply_adj: break; } delta = lshift(delta,Log2P); + if (!delta) goto retfree; if (cmp(delta, bs) > 0) goto drop_down; break; @@ -2585,6 +2574,7 @@ nrv_alloc(const char *s, char **rve, size_t n) char *rv, *t; t = rv = rv_alloc(n); + if (!rv) return NULL; while ((*t = *s++) != 0) t++; if (rve) *rve = t; @@ -2757,6 +2747,7 @@ dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve) #endif b = d2b(dval(d), &be, &bbits); + if (!b) return NULL; #ifdef Sudden_Underflow i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); #else @@ -2876,13 +2867,20 @@ dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve) leftright = 0; /* no break */ case 5: - i = ndigits + k + 1; + if (ckd_add(&i, ndigits, k + 1)) { /* k + 1 should be safe */ + Bfree(b); + return NULL; + } ilim = i; ilim1 = i - 1; if (i <= 0) i = 1; } s = s0 = rv_alloc(i+1); + if (!s) { + Bfree(b); + return NULL; + } #ifdef Honor_FLT_ROUNDS if (mode > 1 && rounding != 1) @@ -3063,6 +3061,7 @@ bump_up: b2 += i; s2 += i; mhi = i2b(1); + if (!mhi) goto nomem; } if (m2 > 0 && s2 > 0) { i = m2 < s2 ? m2 : s2; @@ -3074,19 +3073,28 @@ bump_up: if (leftright) { if (m5 > 0) { mhi = pow5mult(mhi, m5); + if (!mhi) goto nomem; b1 = mult(mhi, b); Bfree(b); b = b1; + if (!b) goto nomem; } - if ((j = b5 - m5) != 0) + if ((j = b5 - m5) != 0) { b = pow5mult(b, j); + if (!b) goto nomem; + } } - else + else { b = pow5mult(b, b5); + if (!b) goto nomem; + } } S = i2b(1); - if (s5 > 0) + if (!S) goto nomem; + if (s5 > 0) { S = pow5mult(S, s5); + if (!S) goto nomem; + } /* Check for special case that d is a normalized power of 2. */ @@ -3134,16 +3142,23 @@ bump_up: m2 += i; s2 += i; } - if (b2 > 0) + if (b2 > 0) { b = lshift(b, b2); - if (s2 > 0) + if (!b) goto nomem; + } + if (s2 > 0) { S = lshift(S, s2); + if (!S) goto nomem; + } if (k_check) { if (cmp(b,S) < 0) { k--; b = multadd(b, 10, 0); /* we botched the k estimate */ - if (leftright) + if (!b) goto nomem; + if (leftright) { mhi = multadd(mhi, 10, 0); + if (!mhi) goto nomem; + } ilim = ilim1; } } @@ -3160,8 +3175,10 @@ one_digit: goto ret; } if (leftright) { - if (m2 > 0) + if (m2 > 0) { mhi = lshift(mhi, m2); + if (!mhi) goto nomem; + } /* Compute mlo -- check for special case * that d is a normalized power of 2. @@ -3170,8 +3187,10 @@ one_digit: mlo = mhi; if (spec_case) { mhi = Balloc(mhi->k); + if (!mhi) goto nomem; Bcopy(mhi, mlo); mhi = lshift(mhi, Log2P); + if (!mhi) goto nomem; } for (i = 1;;i++) { @@ -3181,6 +3200,7 @@ one_digit: */ j = cmp(b, mlo); delta = diff(S, mhi); + if (!delta) goto nomem; j1 = delta->sign ? 1 : cmp(b, delta); Bfree(delta); #ifndef ROUND_BIASED @@ -3221,6 +3241,7 @@ one_digit: #endif /*Honor_FLT_ROUNDS*/ if (j1 > 0) { b = lshift(b, 1); + if (!b) goto nomem; j1 = cmp(b, S); if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ == '9') goto round_9_up; @@ -3249,11 +3270,16 @@ keep_dig: if (i == ilim) break; b = multadd(b, 10, 0); - if (mlo == mhi) + if (!b) goto nomem; + if (mlo == mhi) { mlo = mhi = multadd(mhi, 10, 0); + if (!mlo) goto nomem; + } else { mlo = multadd(mlo, 10, 0); + if (!mlo) goto nomem; mhi = multadd(mhi, 10, 0); + if (!mhi) goto nomem; } } } @@ -3269,6 +3295,7 @@ keep_dig: if (i >= ilim) break; b = multadd(b, 10, 0); + if (!b) goto nomem; } /* Round off last digit */ @@ -3280,6 +3307,7 @@ keep_dig: } #endif b = lshift(b, 1); + if (!b) goto nomem; j = cmp(b, S); if (j > 0 || (j == 0 && (dig & 1))) { roundoff: @@ -3321,6 +3349,16 @@ ret1: if (rve) *rve = s; return s0; + nomem: + if (S) Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + if (b) Bfree(b); + FREE(s0); + return NULL; } /*- @@ -3429,6 +3467,7 @@ hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, char **rv */ bufsize = (ndigits > 0) ? ndigits : SIGFIGS; s0 = rv_alloc(bufsize+1); + if (!s0) return NULL; /* Round to the desired number of digits. */ if (SIGFIGS > ndigits && ndigits > 0) { diff --git a/missing/explicit_bzero.c b/missing/explicit_bzero.c index 1220e5f9ad..59417e158e 100644 --- a/missing/explicit_bzero.c +++ b/missing/explicit_bzero.c @@ -1,12 +1,9 @@ #ifndef __STDC_WANT_LIB_EXT1__ -#define __STDC_WANT_LIB_EXT1__ 1 +#define __STDC_WANT_LIB_EXT1__ 1 /* for memset_s() */ #endif #include "ruby/missing.h" #include <string.h> -#ifdef HAVE_MEMSET_S -# include <string.h> -#endif #ifdef _WIN32 #include <windows.h> diff --git a/missing/procstat_vm.c b/missing/procstat_vm.c index 76fd8f61ba..155ee355d1 100644 --- a/missing/procstat_vm.c +++ b/missing/procstat_vm.c @@ -6,7 +6,7 @@ # define KVME_TYPE_MGTDEVICE 8 # endif void -procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp) +procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp, FILE *errout) { struct kinfo_vmentry *freep, *kve; int ptrwidth; @@ -17,7 +17,7 @@ procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp) #else ptrwidth = 2*sizeof(void *) + 2; #endif - fprintf(stderr, "%*s %*s %3s %4s %4s %3s %3s %4s %-2s %-s\n", + fprintf(errout, "%*s %*s %3s %4s %4s %3s %3s %4s %-2s %-s\n", ptrwidth, "START", ptrwidth, "END", "PRT", "RES", "P""RES", "REF", "SHD", "FL", "TP", "PATH"); @@ -30,20 +30,20 @@ procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp) return; for (i = 0; i < cnt; i++) { kve = &freep[i]; - fprintf(stderr, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_start); - fprintf(stderr, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_end); - fprintf(stderr, "%s", kve->kve_protection & KVME_PROT_READ ? "r" : "-"); - fprintf(stderr, "%s", kve->kve_protection & KVME_PROT_WRITE ? "w" : "-"); - fprintf(stderr, "%s ", kve->kve_protection & KVME_PROT_EXEC ? "x" : "-"); - fprintf(stderr, "%4d ", kve->kve_resident); - fprintf(stderr, "%4d ", kve->kve_private_resident); - fprintf(stderr, "%3d ", kve->kve_ref_count); - fprintf(stderr, "%3d ", kve->kve_shadow_count); - fprintf(stderr, "%-1s", kve->kve_flags & KVME_FLAG_COW ? "C" : "-"); - fprintf(stderr, "%-1s", kve->kve_flags & KVME_FLAG_NEEDS_COPY ? "N" : + fprintf(errout, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_start); + fprintf(errout, "%#*jx ", ptrwidth, (uintmax_t)kve->kve_end); + fprintf(errout, "%s", kve->kve_protection & KVME_PROT_READ ? "r" : "-"); + fprintf(errout, "%s", kve->kve_protection & KVME_PROT_WRITE ? "w" : "-"); + fprintf(errout, "%s ", kve->kve_protection & KVME_PROT_EXEC ? "x" : "-"); + fprintf(errout, "%4d ", kve->kve_resident); + fprintf(errout, "%4d ", kve->kve_private_resident); + fprintf(errout, "%3d ", kve->kve_ref_count); + fprintf(errout, "%3d ", kve->kve_shadow_count); + fprintf(errout, "%-1s", kve->kve_flags & KVME_FLAG_COW ? "C" : "-"); + fprintf(errout, "%-1s", kve->kve_flags & KVME_FLAG_NEEDS_COPY ? "N" : "-"); - fprintf(stderr, "%-1s", kve->kve_flags & KVME_FLAG_SUPER ? "S" : "-"); - fprintf(stderr, "%-1s ", kve->kve_flags & KVME_FLAG_GROWS_UP ? "U" : + fprintf(errout, "%-1s", kve->kve_flags & KVME_FLAG_SUPER ? "S" : "-"); + fprintf(errout, "%-1s ", kve->kve_flags & KVME_FLAG_GROWS_UP ? "U" : kve->kve_flags & KVME_FLAG_GROWS_DOWN ? "D" : "-"); switch (kve->kve_type) { case KVME_TYPE_NONE: @@ -78,8 +78,8 @@ procstat_vm(struct procstat *procstat, struct kinfo_proc *kipp) str = "??"; break; } - fprintf(stderr, "%-2s ", str); - fprintf(stderr, "%-s\n", kve->kve_path); + fprintf(errout, "%-2s ", str); + fprintf(errout, "%-s\n", kve->kve_path); } free(freep); } diff --git a/missing/setproctitle.c b/missing/setproctitle.c index 811829c060..5b2dfa65ce 100644 --- a/missing/setproctitle.c +++ b/missing/setproctitle.c @@ -80,10 +80,43 @@ static char **argv1_addr = NULL; #endif /* HAVE_SETPROCTITLE */ +#if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV +# define ALLOCATE_ENVIRON 1 +#else +# define ALLOCATE_ENVIRON 0 +#endif + +#if ALLOCATE_ENVIRON +/* system_environ is the value of environ before we allocate a custom buffer. + * + * We use this to restore environ in ruby_free_proctitle. + */ +static char **system_environ = NULL; +/* orig_environ is the buffer we allocate for environ. + * + * We use this to free this buffer in ruby_free_proctitle. When we add new + * environment variables using setenv, the system may change environ to a + * different buffer and will not free the original buffer, so we need to hold + * onto this so we can free it in ruby_free_proctitle. + * + * We must not free any of the contents because it may change if the system + * updates existing environment variables. + */ +static char **orig_environ = NULL; +/* alloc_environ is a copy of orig_environ. + * + * We use this to free all the original string copies that were in orig_environ. + * Since environ could be changed to point to strings allocated by the system + * if environment variables are updated, so we need this to point to the + * original strings. + */ +static char **alloc_environ = NULL; +#endif + void compat_init_setproctitle(int argc, char *argv[]) { -#if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV +#if ALLOCATE_ENVIRON extern char **environ; char *lastargv = NULL; char *lastenvp = NULL; @@ -100,9 +133,13 @@ compat_init_setproctitle(int argc, char *argv[]) return; /* Fail if we can't allocate room for the new environment */ - for (i = 0; envp[i] != NULL; i++) - ; - if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) { + for (i = 0; envp[i] != NULL; i++); + + system_environ = environ; + + alloc_environ = xcalloc(i + 1, sizeof(*environ)); + orig_environ = environ = xcalloc(i + 1, sizeof(*environ)); + if (environ == NULL) { environ = envp; /* put it back */ return; } @@ -129,12 +166,31 @@ compat_init_setproctitle(int argc, char *argv[]) argv_env_len = lastenvp - argv[0]; for (i = 0; envp[i] != NULL; i++) - environ[i] = ruby_strdup(envp[i]); - environ[i] = NULL; + alloc_environ[i] = environ[i] = ruby_strdup(envp[i]); + alloc_environ[i] = environ[i] = NULL; #endif /* SPT_REUSEARGV */ } +void +ruby_free_proctitle(void) +{ +#if ALLOCATE_ENVIRON + extern char **environ; + + if (!orig_environ) return; /* environ is allocated by OS */ + + for (int i = 0; alloc_environ[i] != NULL; i++) { + xfree(alloc_environ[i]); + } + xfree(alloc_environ); + xfree(orig_environ); + + environ = system_environ; +#endif +} + #ifndef HAVE_SETPROCTITLE + void setproctitle(const char *fmt, ...) { |
