Skip to content

Commit

Permalink
Fix some issues with select()
Browse files Browse the repository at this point in the history
  • Loading branch information
jart committed Oct 4, 2023
1 parent 6918c3f commit 982dc4d
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 34 deletions.
3 changes: 2 additions & 1 deletion examples/greenbean.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
9 changes: 5 additions & 4 deletions libc/intrin/describefdset.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion libc/proc/execve-sysv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
84 changes: 56 additions & 28 deletions libc/sock/select.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
} else {
#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) {
ts.tv_sec = timeout->tv_sec;
ts.tv_nsec = timeout->tv_usec * 1000;
tsp = &ts;
} else {
tsp = 0;
old_timeout = *timeout;
old_timeout_ptr = &old_timeout;
}
rc = sys_pselect(nfds, readfds, writefds, exceptfds, tsp, 0);
#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, tvp);
rc = sys_select(nfds, readfds, writefds, exceptfds, timeout);
#endif
} else {
rc = sys_select_nt(nfds, readfds, writefds, exceptfds, tvp, 0);
} 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;
}

0 comments on commit 982dc4d

Please sign in to comment.