summaryrefslogtreecommitdiff
path: root/missing
diff options
context:
space:
mode:
Diffstat (limited to 'missing')
-rw-r--r--missing/alloca.c2
-rw-r--r--missing/crypt.h5
-rw-r--r--missing/dtoa.c334
-rw-r--r--missing/dup2.c60
-rw-r--r--missing/erf.c15
-rw-r--r--missing/explicit_bzero.c17
-rw-r--r--missing/file.h3
-rw-r--r--missing/fileblocks.c1
-rw-r--r--missing/finite.c9
-rw-r--r--missing/flock.c11
-rw-r--r--missing/isinf.c69
-rw-r--r--missing/isnan.c32
-rw-r--r--missing/langinfo.c2
-rw-r--r--missing/memcmp.c3
-rw-r--r--missing/procstat_vm.c36
-rw-r--r--missing/setproctitle.c73
-rw-r--r--missing/signbit.c19
-rw-r--r--missing/stdbool.h20
-rw-r--r--missing/tgamma.c17
-rw-r--r--missing/x86_64-chkstk.S (renamed from missing/x86_64-chkstk.s)0
20 files changed, 323 insertions, 405 deletions
diff --git a/missing/alloca.c b/missing/alloca.c
index 96121f7647..d039dfc2cc 100644
--- a/missing/alloca.c
+++ b/missing/alloca.c
@@ -29,7 +29,7 @@
static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
#endif
-#include "ruby/config.h"
+#include "ruby/internal/config.h"
#define X3J11 1 /* config.h should contain void if needed */
#ifdef C_ALLOCA
diff --git a/missing/crypt.h b/missing/crypt.h
index 7c2642f593..ff135eee93 100644
--- a/missing/crypt.h
+++ b/missing/crypt.h
@@ -1,3 +1,5 @@
+#ifndef CRYPT_H
+#define CRYPT_H 1
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -30,9 +32,6 @@
* SUCH DAMAGE.
*/
-#ifndef CRYPT_H
-#define CRYPT_H 1
-
/* ===== Configuration ==================== */
#ifdef CHAR_BITS
diff --git a/missing/dtoa.c b/missing/dtoa.c
index cbee13ee81..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,15 +172,22 @@
#undef Long
#undef ULong
-#if SIZEOF_INT == 4
+#include <assert.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#if (INT_MAX >> 30) && !(INT_MAX >> 31)
#define Long int
#define ULong unsigned int
-#elif SIZEOF_LONG == 4
+#elif (LONG_MAX >> 30) && !(LONG_MAX >> 31)
#define Long long int
#define ULong unsigned long int
+#else
+#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
@@ -202,6 +198,11 @@
#define Bug(x) {fprintf(stderr, "%s\n", (x)); exit(EXIT_FAILURE);}
#endif
+#ifndef ISDIGIT
+#include <ctype.h>
+#define ISDIGIT(c) isdigit(c)
+#endif
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -209,23 +210,41 @@
#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
-#endif
-
-#ifndef Omit_Private_Memory
-#ifndef PRIVATE_MEM
-#define PRIVATE_MEM 2304
+#define FREE free
#endif
-#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
-static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
+#ifndef NO_SANITIZE
+#define NO_SANITIZE(x, y) y
#endif
#undef IEEE_Arith
@@ -280,7 +299,7 @@ extern "C" {
#endif
#ifndef hexdigit
-static const char hexdigits[] = "0123456789abcdef0123456789ABCDEF";
+static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
#endif
#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + defined(IBM) != 1
@@ -489,6 +508,19 @@ extern double rnd_prod(double, double), rnd_quot(double, double);
#define FREE_DTOA_LOCK(n) /*unused right now*/
#endif
+#ifndef ATOMIC_PTR_CAS
+#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (void *)(old))
+#endif
+#ifndef LIKELY
+#define LIKELY(x) (x)
+#endif
+#ifndef UNLIKELY
+#define UNLIKELY(x) (x)
+#endif
+#ifndef ASSUME
+#define ASSUME(x) (void)(x)
+#endif
+
#define Kmax 15
struct Bigint {
@@ -499,57 +531,29 @@ struct Bigint {
typedef struct Bigint Bigint;
-static Bigint *freelist[Kmax+1];
-
static Bigint *
Balloc(int k)
{
int x;
Bigint *rv;
-#ifndef Omit_Private_Memory
- size_t len;
-#endif
- ACQUIRE_DTOA_LOCK(0);
- if (k <= Kmax && (rv = freelist[k]) != 0) {
- freelist[k] = rv->next;
- }
- else {
- 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 && pmem_next - private_mem + len <= PRIVATE_mem) {
- rv = (Bigint*)pmem_next;
- pmem_next += len;
- }
- else
- 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)
{
- if (v) {
- if (v->k > Kmax) {
- FREE(v);
- return;
- }
- ACQUIRE_DTOA_LOCK(0);
- v->next = freelist[v->k];
- freelist[v->k] = v;
- 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))
@@ -595,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;
@@ -616,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
@@ -629,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;
}
@@ -717,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)
{
@@ -738,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;
@@ -750,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;
@@ -830,48 +855,46 @@ pow5mult(Bigint *b, int k)
{
Bigint *b1, *p5, *p51;
int i;
- static int p05[3] = { 5, 25, 125 };
+ 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 */
-#ifdef MULTIPLE_THREADS
- ACQUIRE_DTOA_LOCK(1);
- if (!(p5 = p5s)) {
- p5 = p5s = i2b(625);
- p5->next = 0;
- }
- FREE_DTOA_LOCK(1);
-#else
- p5 = p5s = i2b(625);
- p5->next = 0;
-#endif
- }
+ /* 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)) {
-#ifdef MULTIPLE_THREADS
- ACQUIRE_DTOA_LOCK(1);
- if (!(p51 = p5->next)) {
- p51 = p5->next = mult(p5,p5);
- p51->next = 0;
- }
- FREE_DTOA_LOCK(1);
-#else
- p51 = p5->next = mult(p5,p5);
- p51->next = 0;
-#endif
- }
+ b_cache(p51, p5->next, mult(p5, p5));
p5 = p51;
}
return b;
@@ -884,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
@@ -894,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;
@@ -979,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;
@@ -992,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;
@@ -1177,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;
@@ -1497,9 +1529,10 @@ 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;
s1 = strchr(hexdigit, *s);
}
if (s1 != NULL) {
@@ -1510,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++;
@@ -1522,14 +1553,11 @@ break2:
for (; *s && (s1 = strchr(hexdigit, *s)); ++s) {
adj += aadj * ((s1 - hexdigit) & 15);
if ((aadj /= 16) == 0.0) {
- while (strchr(hexdigit, *++s));
+ while (*++s && strchr(hexdigit, *s));
break;
}
}
}
- else {
- dsign = 0;
- }
if (*s == 'P' || *s == 'p') {
dsign = 0x2C - *++s; /* +: 2B, -: 2D */
@@ -1552,9 +1580,6 @@ break2:
} while ('0' <= c && c <= '9');
nd0 += nd * dsign;
}
- else {
- if (dsign) goto ret0;
- }
dval(rv) = ldexp(adj, nd0);
goto ret;
}
@@ -1591,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++;
@@ -1934,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;
@@ -1996,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);
@@ -2041,6 +2081,7 @@ undfl:
#endif
{
delta = lshift(delta,Log2P);
+ if (!delta) goto nomem;
if (cmp(delta, bs) <= 0)
adj = -0.5;
}
@@ -2130,6 +2171,7 @@ apply_adj:
break;
}
delta = lshift(delta,Log2P);
+ if (!delta) goto retfree;
if (cmp(delta, bs) > 0)
goto drop_down;
break;
@@ -2520,10 +2562,10 @@ static char *dtoa_result;
static char *
rv_alloc(int i)
{
- return dtoa_result = xmalloc(i);
+ return dtoa_result = MALLOC(i);
}
#else
-#define rv_alloc(i) xmalloc(i)
+#define rv_alloc(i) MALLOC(i)
#endif
static char *
@@ -2532,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;
@@ -2550,7 +2593,7 @@ nrv_alloc(const char *s, char **rve, size_t n)
static void
freedtoa(char *s)
{
- xfree(s);
+ FREE(s);
}
#endif
@@ -2704,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
@@ -2823,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)
@@ -3010,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;
@@ -3021,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. */
@@ -3081,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;
}
}
@@ -3107,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.
@@ -3117,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++) {
@@ -3128,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
@@ -3168,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;
@@ -3196,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;
}
}
}
@@ -3216,6 +3295,7 @@ keep_dig:
if (i >= ilim)
break;
b = multadd(b, 10, 0);
+ if (!b) goto nomem;
}
/* Round off last digit */
@@ -3227,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:
@@ -3268,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;
}
/*-
@@ -3376,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/dup2.c b/missing/dup2.c
deleted file mode 100644
index 7554084c5d..0000000000
--- a/missing/dup2.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Public domain dup2() lookalike
- * by Curtis Jackson @ AT&T Technologies, Burlington, NC
- * electronic address: burl!rcj
- *
- * dup2 performs the following functions:
- *
- * Check to make sure that fd1 is a valid open file descriptor.
- * Check to see if fd2 is already open; if so, close it.
- * Duplicate fd1 onto fd2; checking to make sure fd2 is a valid fd.
- * Return fd2 if all went well; return BADEXIT otherwise.
- */
-
-#include "ruby/config.h"
-
-#if defined(HAVE_FCNTL)
-# include <fcntl.h>
-#endif
-
-#if !defined(HAVE_FCNTL) || !defined(F_DUPFD)
-# include <errno.h>
-#endif
-
-#define BADEXIT -1
-
-int
-dup2(int fd1, int fd2)
-{
-#if defined(HAVE_FCNTL) && defined(F_DUPFD)
- if (fd1 != fd2) {
-#ifdef F_GETFL
- if (fcntl(fd1, F_GETFL) < 0)
- return BADEXIT;
- if (fcntl(fd2, F_GETFL) >= 0)
- close(fd2);
-#else
- close(fd2);
-#endif
- if (fcntl(fd1, F_DUPFD, fd2) < 0)
- return BADEXIT;
- }
- return fd2;
-#else
- extern int errno;
- int i, fd, fds[256];
-
- if (fd1 == fd2) return 0;
- close(fd2);
- for (i=0; i<256; i++) {
- fd = fds[i] = dup(fd1);
- if (fd == fd2) break;
- }
- while (i) {
- close(fds[i--]);
- }
- if (fd == fd2) return 0;
- errno = EMFILE;
- return BADEXIT;
-#endif
-}
diff --git a/missing/erf.c b/missing/erf.c
index d72c4eaf4e..c2c9d5f7e9 100644
--- a/missing/erf.c
+++ b/missing/erf.c
@@ -7,21 +7,6 @@ reference - Haruhiko Okumura: C-gengo niyoru saishin algorithm jiten
#include <stdio.h>
#include <math.h>
-#ifdef _WIN32
-# include <float.h>
-# if !defined __MINGW32__ || defined __NO_ISOCEXT
-# ifndef isnan
-# define isnan(x) _isnan(x)
-# endif
-# ifndef isinf
-# define isinf(x) (!_finite(x) && !_isnan(x))
-# endif
-# ifndef finite
-# define finite(x) _finite(x)
-# endif
-# endif
-#endif
-
static double q_gamma(double, double, double);
/* Incomplete gamma function
diff --git a/missing/explicit_bzero.c b/missing/explicit_bzero.c
index a7ff9cb517..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>
@@ -17,9 +14,9 @@
/* OS support note:
* BSDs have explicit_bzero().
- * OS-X has memset_s().
+ * macOS has memset_s().
* Windows has SecureZeroMemory() since XP.
- * Linux has none. *Sigh*
+ * Linux has explicit_bzero() since glibc 2.25, musl libc 1.1.20.
*/
/*
@@ -33,7 +30,13 @@
#undef explicit_bzero
#ifndef HAVE_EXPLICIT_BZERO
- #ifdef HAVE_MEMSET_S
+ #ifdef HAVE_EXPLICIT_MEMSET
+void
+explicit_bzero(void *b, size_t len)
+{
+ (void)explicit_memset(b, 0, len);
+}
+ #elif defined HAVE_MEMSET_S
void
explicit_bzero(void *b, size_t len)
{
diff --git a/missing/file.h b/missing/file.h
index 241d716563..5e25c4761c 100644
--- a/missing/file.h
+++ b/missing/file.h
@@ -1,7 +1,6 @@
-/* This is file FILE.H */
-
#ifndef _FILE_H_
#define _FILE_H_
+/* This is file FILE.H */
#include <fcntl.h>
diff --git a/missing/fileblocks.c b/missing/fileblocks.c
deleted file mode 100644
index ccb8d667b4..0000000000
--- a/missing/fileblocks.c
+++ /dev/null
@@ -1 +0,0 @@
-/* dummy for autoconf */
diff --git a/missing/finite.c b/missing/finite.c
deleted file mode 100644
index ab7686317b..0000000000
--- a/missing/finite.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* public domain rewrite of finite(3) */
-
-#include "ruby/missing.h"
-
-int
-finite(double n)
-{
- return !isnan(n) && !isinf(n);
-}
diff --git a/missing/flock.c b/missing/flock.c
index 71c5e74210..0b76961762 100644
--- a/missing/flock.c
+++ b/missing/flock.c
@@ -1,7 +1,16 @@
-#include "ruby/config.h"
+#include "ruby/internal/config.h"
#include "ruby/ruby.h"
#if defined _WIN32
+#elif defined __wasi__
+#include <errno.h>
+
+int
+flock(int fd, int operation)
+{
+ errno = EINVAL;
+ return -1;
+}
#elif defined HAVE_FCNTL && defined HAVE_FCNTL_H
/* These are the flock() constants. Since this systems doesn't have
diff --git a/missing/isinf.c b/missing/isinf.c
deleted file mode 100644
index 55187adc63..0000000000
--- a/missing/isinf.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/* public domain rewrite of isinf(3) */
-
-#ifdef __osf__
-
-#define _IEEE 1
-#include <nan.h>
-
-int
-isinf(double n)
-{
- if (IsNANorINF(n) && IsINF(n)) {
- return 1;
- }
- else {
- return 0;
- }
-}
-
-#else
-
-#include "ruby/config.h"
-
-#if defined(HAVE_FINITE) && defined(HAVE_ISNAN)
-
-#include <math.h>
-#ifdef HAVE_IEEEFP_H
-#include <ieeefp.h>
-#endif
-
-/*
- * isinf may be provided only as a macro.
- * ex. HP-UX, Solaris 10
- * http://www.gnu.org/software/automake/manual/autoconf/Function-Portability.html
- */
-#ifndef isinf
-int
-isinf(double n)
-{
- return (!finite(n) && !isnan(n));
-}
-#endif
-
-#else
-
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
-
-static double zero(void) { return 0.0; }
-static double one (void) { return 1.0; }
-static double inf (void) { return one() / zero(); }
-
-int
-isinf(double n)
-{
- static double pinf = 0.0;
- static double ninf = 0.0;
-
- if (pinf == 0.0) {
- pinf = inf();
- ninf = -pinf;
- }
- return memcmp(&n, &pinf, sizeof n) == 0
- || memcmp(&n, &ninf, sizeof n) == 0;
-}
-#endif
-#endif
diff --git a/missing/isnan.c b/missing/isnan.c
deleted file mode 100644
index ed10bf5cd6..0000000000
--- a/missing/isnan.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/* public domain rewrite of isnan(3) */
-
-#include "ruby/missing.h"
-
-/*
- * isnan() may be a macro, a function or both.
- * (The C99 standard defines that isnan() is a macro, though.)
- * http://www.gnu.org/software/automake/manual/autoconf/Function-Portability.html
- *
- * macro only: uClibc
- * both: GNU libc
- *
- * This file is compile if no isnan() function is available.
- * (autoconf AC_REPLACE_FUNCS detects only the function.)
- * The macro is detected by following #ifndef.
- */
-
-#ifndef isnan
-static int double_ne(double n1, double n2);
-
-int
-isnan(double n)
-{
- return double_ne(n, n);
-}
-
-static int
-double_ne(double n1, double n2)
-{
- return n1 != n2;
-}
-#endif
diff --git a/missing/langinfo.c b/missing/langinfo.c
index 9ba06b15f6..0274a378f5 100644
--- a/missing/langinfo.c
+++ b/missing/langinfo.c
@@ -140,7 +140,7 @@ char *nl_langinfo(nl_item item)
#ifdef TEST
#include <stdio.h>
-int main()
+int main(void)
{
printf("%s\n", nl_langinfo(CODESET));
return 0;
diff --git a/missing/memcmp.c b/missing/memcmp.c
index a81eec4244..9657e6c372 100644
--- a/missing/memcmp.c
+++ b/missing/memcmp.c
@@ -11,7 +11,8 @@ memcmp(const void *s1, const void *s2, size_t len)
register int tmp;
for (; len; --len) {
- if (tmp = *a++ - *b++)
+ tmp = *a++ - *b++;
+ if (tmp)
return tmp;
}
return 0;
diff --git a/missing/procstat_vm.c b/missing/procstat_vm.c
index f56c406bf9..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,9 +17,9 @@ 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",
- "PRES", "REF", "SHD", "FL", "TP", "PATH");
+ "P""RES", "REF", "SHD", "FL", "TP", "PATH");
#ifdef HAVE_PROCSTAT_GETVMMAP
freep = procstat_getvmmap(procstat, kipp, &cnt);
@@ -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 9fceeee52b..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, ...)
{
@@ -152,10 +208,9 @@ setproctitle(const char *fmt, ...)
return;
#endif
+ /* fmt must be non-NULL */
va_start(ap, fmt);
- if (fmt != NULL) {
- vsnprintf(ptitle, sizeof(ptitle) , fmt, ap);
- }
+ vsnprintf(ptitle, sizeof(ptitle), fmt, ap);
va_end(ap);
#if SPT_TYPE == SPT_PSTAT
diff --git a/missing/signbit.c b/missing/signbit.c
deleted file mode 100644
index 2f7ce8c601..0000000000
--- a/missing/signbit.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#include <limits.h>
-#include "ruby.h"
-
-int
-signbit(double x)
-{
- enum {double_per_long = sizeof(double) / sizeof(long)};
- enum {long_msb = sizeof(long) * CHAR_BIT - 1};
- union {double d; unsigned long i[double_per_long];} u;
- unsigned long l;
-
- u.d = x;
-#ifdef WORDS_BIGENDIAN
- l = u.i[0];
-#else
- l = u.i[double_per_long - 1];
-#endif
- return (int)(l >> long_msb);
-}
diff --git a/missing/stdbool.h b/missing/stdbool.h
deleted file mode 100644
index f370e01e92..0000000000
--- a/missing/stdbool.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * missing/stdbool.h: Quick alternative of C99 stdbool.h
- */
-
-#ifndef _MISSING_STDBOOL_H_
-#define _MISSING_STDBOOL_H_
-
-#ifndef __bool_true_false_are_defined
-# ifndef __cplusplus
-# undef bool
-# undef false
-# undef true
-# define bool signed char
-# define false 0
-# define true 1
-# define __bool_true_false_are_defined 1
-# endif
-#endif
-
-#endif /* _MISSING_STDBOOL_H_ */
diff --git a/missing/tgamma.c b/missing/tgamma.c
index 6260e4f519..82d614d755 100644
--- a/missing/tgamma.c
+++ b/missing/tgamma.c
@@ -9,26 +9,11 @@ reference - Haruhiko Okumura: C-gengo niyoru saishin algorithm jiten
/***********************************************************
gamma.c -- Gamma function
***********************************************************/
-#include "ruby/config.h"
+#include "ruby/internal/config.h"
#include "ruby/missing.h"
#include <math.h>
#include <errno.h>
-#ifdef _WIN32
-# include <float.h>
-# if !defined __MINGW32__ || defined __NO_ISOCEXT
-# ifndef isnan
-# define isnan(x) _isnan(x)
-# endif
-# ifndef isinf
-# define isinf(x) (!_finite(x) && !_isnan(x))
-# endif
-# ifndef finite
-# define finite(x) _finite(x)
-# endif
-# endif
-#endif
-
#ifndef HAVE_LGAMMA_R
#include <errno.h>
diff --git a/missing/x86_64-chkstk.s b/missing/x86_64-chkstk.S
index 6d1227b6d2..6d1227b6d2 100644
--- a/missing/x86_64-chkstk.s
+++ b/missing/x86_64-chkstk.S