Fix some issues with select()

This commit is contained in:
Justine Tunney 2023-10-04 09:10:58 -07:00
parent 6918c3ffc2
commit 982dc4db87
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
4 changed files with 67 additions and 37 deletions

View file

@ -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) {

View file

@ -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);
}
}
}

View file

@ -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 {

View file

@ -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;
}