Project

General

Profile

Bug #18152 » 0001-Fix-theoretical-bug-with-signals-qsort-b.patch

Scalable patch for theoretical qsort async-signal bug - eggert (Paul Eggert), 09/06/2021 11:59 PM

View differences:

include/ruby/util.h
void ruby_qsort(void *, const size_t, const size_t,
int (*)(const void *, const void *, void *), void *);
#endif
void ruby_assort(void *, const size_t, const size_t,
int (*)(const void *, const void *, void *), void *);
void ruby_setenv(const char *, const char *);
void ruby_unsetenv(const char *);
process.c
return *(int*)a - *(int*)b;
}
static int
intcmp_r(const void *a, const void *b, void *_)
{
return intcmp(a, b);
}
static int
intrcmp(const void *a, const void *b)
{
......
/* sort the table by oldfd: O(n log n) */
if (!sargp)
qsort(pairs, n, sizeof(struct run_exec_dup2_fd_pair), intcmp); /* hopefully async-signal-safe */
ruby_assort(pairs, n, sizeof(struct run_exec_dup2_fd_pair), intcmp_r, NULL); /* async-signal-safe */
else
qsort(pairs, n, sizeof(struct run_exec_dup2_fd_pair), intrcmp);
util.c
}
# define HAVE_GNU_QSORT_R 1
#elif !defined HAVE_GNU_QSORT_R
void
ruby_qsort(void *base, size_t nel, size_t size, cmpfunc_t *cmp, void *d)
{
return ruby_assort(base, nel, size, cmp, d);
}
#endif /* HAVE_GNU_QSORT_R */
/* mm.c */
#define mmtype long
......
((*cmp)((b),(c),d)<0 ? (b) : ((*cmp)((a),(c),d)<0 ? (c) : (a))) : \
((*cmp)((b),(c),d)>0 ? (b) : ((*cmp)((a),(c),d)<0 ? (a) : (c))))
/* This function is async-signal-safe if cmp is. */
void
ruby_qsort(void* base, const size_t nel, const size_t size, cmpfunc_t *cmp, void *d)
ruby_assort(void *base, size_t nel, size_t size, cmpfunc_t *cmp, void *d)
{
register char *l, *r, *m; /* l,r:left,right group m:median point */
register int t, eq_l, eq_r; /* eq_l: all items in left group are equal to S */
......
else goto nxt; /* need not to sort both sides */
}
}
#endif /* HAVE_GNU_QSORT_R */
char *
ruby_strdup(const char *str)
(1-1/2)