From 982dc4db87722f6c09b616d21055fb8dcb1655c0 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Wed, 4 Oct 2023 09:10:58 -0700 Subject: [PATCH] Fix some issues with select() --- examples/greenbean.c | 3 +- libc/intrin/describefdset.c | 9 ++-- libc/proc/execve-sysv.c | 2 +- libc/sock/select.c | 90 ++++++++++++++++++++++++------------- 4 files changed, 67 insertions(+), 37 deletions(-) diff --git a/examples/greenbean.c b/examples/greenbean.c index 3ba5cd21b..cdf43de97 100644 --- a/examples/greenbean.c +++ b/examples/greenbean.c @@ -380,9 +380,10 @@ int main(int argc, char *argv[]) { sigaddset(&block, SIGHUP); sigaddset(&block, SIGQUIT); pthread_attr_t attr; + int pagesz = getauxval(AT_PAGESZ); unassert(!pthread_attr_init(&attr)); - unassert(!pthread_attr_setguardsize(&attr, 4096)); unassert(!pthread_attr_setstacksize(&attr, 65536)); + unassert(!pthread_attr_setguardsize(&attr, pagesz)); unassert(!pthread_attr_setsigmask_np(&attr, &block)); pthread_t *th = gc(calloc(threads, sizeof(pthread_t))); for (i = 0; i < threads; ++i) { diff --git a/libc/intrin/describefdset.c b/libc/intrin/describefdset.c index 165c7e760..2edca8f17 100644 --- a/libc/intrin/describefdset.c +++ b/libc/intrin/describefdset.c @@ -43,14 +43,15 @@ const char *(DescribeFdSet)(char buf[N], ssize_t rc, int nfds, fd_set *fds) { for (int fd = 0; fd < nfds; fd += 64) { uint64_t w = fds->fds_bits[fd >> 6]; while (w) { - unsigned o = _bsr(w); - w &= ~((uint64_t)1 << o); - if (fd + o < nfds) { + unsigned m = _bsr(w); + w &= ~((uint64_t)1 << m); + if (fd + m < nfds) { if (!gotsome) { gotsome = true; + } else { append(", "); - append("%d", fd); } + append("%d", fd + m); } } } diff --git a/libc/proc/execve-sysv.c b/libc/proc/execve-sysv.c index f9902276f..2ffa4057a 100644 --- a/libc/proc/execve-sysv.c +++ b/libc/proc/execve-sysv.c @@ -53,7 +53,7 @@ static struct { const char *tmpdir; } g_execve; -bool IsApeFile(const char *path) { +static bool IsApeFile(const char *path) { if (endswith(path, ".com")) { return true; } else { diff --git a/libc/sock/select.c b/libc/sock/select.c index d72afa495..abbd53ca0 100644 --- a/libc/sock/select.c +++ b/libc/sock/select.c @@ -47,50 +47,78 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { int rc; - struct timeval tv, *tvp; +#ifdef SYSDEBUG + fd_set old_readfds; + fd_set *old_readfds_ptr = 0; + fd_set old_writefds; + fd_set *old_writefds_ptr = 0; + fd_set old_exceptfds; + fd_set *old_exceptfds_ptr = 0; + struct timeval old_timeout; + struct timeval *old_timeout_ptr = 0; +#endif + POLLTRACE("select(%d, %p, %p, %p, %s) → ...", nfds, readfds, writefds, exceptfds, DescribeTimeval(0, timeout)); - // the linux kernel modifies timeout - if (timeout) { - if (IsAsan() && !__asan_is_valid(timeout, sizeof(*timeout))) { - return efault(); - } - tv = *timeout; - tvp = &tv; - } else { - tvp = 0; - } - BEGIN_CANCELLATION_POINT; if (nfds < 0) { rc = einval(); } else if (IsAsan() && ((readfds && !__asan_is_valid(readfds, FD_SIZE(nfds))) || (writefds && !__asan_is_valid(writefds, FD_SIZE(nfds))) || - (exceptfds && !__asan_is_valid(exceptfds, FD_SIZE(nfds))))) { + (exceptfds && !__asan_is_valid(exceptfds, FD_SIZE(nfds))) || + (timeout && !__asan_is_valid(timeout, sizeof(*timeout))))) { rc = efault(); - } else if (!IsWindows()) { -#ifdef __aarch64__ - struct timespec ts, *tsp; - if (timeout) { - ts.tv_sec = timeout->tv_sec; - ts.tv_nsec = timeout->tv_usec * 1000; - tsp = &ts; - } else { - tsp = 0; - } - rc = sys_pselect(nfds, readfds, writefds, exceptfds, tsp, 0); -#else - rc = sys_select(nfds, readfds, writefds, exceptfds, tvp); -#endif } else { - rc = sys_select_nt(nfds, readfds, writefds, exceptfds, tvp, 0); +#ifdef SYSDEBUG + if (readfds) { + old_readfds = *readfds; + old_readfds_ptr = &old_readfds; + } + if (writefds) { + old_writefds = *writefds; + old_writefds_ptr = &old_writefds; + } + if (exceptfds) { + old_exceptfds = *exceptfds; + old_exceptfds_ptr = &old_exceptfds; + } + if (timeout) { + old_timeout = *timeout; + old_timeout_ptr = &old_timeout; + } +#endif + if (!IsWindows()) { +#ifdef __aarch64__ + struct timespec ts, *tsp; + if (timeout) { + ts = timeval_totimespec(*timeout); + tsp = &ts; + } else { + tsp = 0; + } + rc = sys_pselect(nfds, readfds, writefds, exceptfds, tsp, 0); + if (timeout) { + *timeout = timespec_totimeval(ts); + } +#else + rc = sys_select(nfds, readfds, writefds, exceptfds, timeout); +#endif + } else { + rc = sys_select_nt(nfds, readfds, writefds, exceptfds, timeout, 0); + } } END_CANCELLATION_POINT; - STRACE("select(%d, [%s], [%s], [%s], [%s]) → %d% m", nfds, - DescribeFdSet(rc, nfds, readfds), DescribeFdSet(rc, nfds, writefds), - DescribeFdSet(rc, nfds, exceptfds), DescribeTimeval(rc, tvp), rc); + STRACE("select(%d, %s → [%s], %s → [%s], %s → [%s], %s → [%s]) → %d% m", nfds, + DescribeFdSet(rc, nfds, old_readfds_ptr), + DescribeFdSet(rc, nfds, readfds), + DescribeFdSet(rc, nfds, old_writefds_ptr), + DescribeFdSet(rc, nfds, writefds), + DescribeFdSet(rc, nfds, old_exceptfds_ptr), + DescribeFdSet(rc, nfds, exceptfds), // + DescribeTimeval(rc, old_timeout_ptr), // + DescribeTimeval(rc, timeout), rc); return rc; }