mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-05 02:38:31 +00:00
Make improvements
- Polyfill pselect() on Windows - Add -O NOFILE flag to pledge.com - Polyfill ppoll() on NetBSD, XNU, and Windows - Support negative numbers and errno in sizetol() - Add .RSS, .NOFILE, and .MAXCORE to Landlock Make - Fix issue with .PLEDGE preventing touching of output files - Add __watch() function (like ftrace) for logging memory changes
This commit is contained in:
parent
d3b599a796
commit
f0701d2a24
35 changed files with 635 additions and 340 deletions
|
@ -87,7 +87,8 @@ int sys_socketpair_nt_stream(int, int, int, int[2]) hidden;
|
|||
int sys_socketpair_nt_dgram(int, int, int, int[2]) hidden;
|
||||
*/
|
||||
int sys_socketpair_nt(int, int, int, int[2]) hidden;
|
||||
int sys_select_nt(int, fd_set *, fd_set *, fd_set *, struct timeval *) hidden;
|
||||
int sys_select_nt(int, fd_set *, fd_set *, fd_set *, struct timeval *,
|
||||
const sigset_t *) hidden;
|
||||
|
||||
size_t __iovec2nt(struct NtIovec[hasatleast 16], const struct iovec *,
|
||||
size_t) hidden;
|
||||
|
|
|
@ -18,9 +18,13 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/select.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Does what poll() does except with bitset API.
|
||||
|
@ -32,9 +36,30 @@ int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||
const struct timespec *timeout, const sigset_t *sigmask) {
|
||||
int rc;
|
||||
sigset_t oldmask;
|
||||
rc = sys_pselect(nfds, readfds, writefds, exceptfds, timeout, sigmask);
|
||||
POLLTRACE("pselect(%d, %p, %p, %p, [%s], %s) → %d% m", nfds, readfds,
|
||||
writefds, exceptfds, DescribeTimeval(rc, timeout),
|
||||
DescribeSigset(0, sigmask), rc);
|
||||
struct timeval tv, *tvp;
|
||||
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))) ||
|
||||
(timeout && !__asan_is_valid(timeout, sizeof(*timeout))) ||
|
||||
(sigmask && !__asan_is_valid(sigmask, sizeof(*sigmask))))) {
|
||||
rc = efault();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_pselect(nfds, readfds, writefds, exceptfds, timeout, sigmask);
|
||||
} else {
|
||||
if (timeout) {
|
||||
tv.tv_sec = timeout->tv_sec;
|
||||
tv.tv_usec = timeout->tv_nsec / 1000;
|
||||
tvp = &tv;
|
||||
} else {
|
||||
tvp = 0;
|
||||
}
|
||||
rc = sys_select_nt(nfds, readfds, writefds, exceptfds, tvp, sigmask);
|
||||
}
|
||||
POLLTRACE("pselect(%d, %p, %p, %p, %s, %s) → %d% m", nfds, readfds, writefds,
|
||||
exceptfds, DescribeTimeval(0, timeout), DescribeSigset(0, sigmask),
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/sock/select.h"
|
||||
|
@ -27,14 +28,12 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int sys_select_nt(int nfds, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds, struct timeval *timeout) {
|
||||
fd_set *exceptfds, struct timeval *timeout,
|
||||
const sigset_t *sigmask) {
|
||||
uint64_t millis;
|
||||
int i, pfds, events, fdcount;
|
||||
struct pollfd fds[64];
|
||||
|
||||
// check for interrupts early before doing work
|
||||
if (_check_interrupts(false, g_fds.p)) return eintr();
|
||||
|
||||
// convert bitsets to pollfd
|
||||
for (pfds = i = 0; i < nfds; ++i) {
|
||||
events = 0;
|
||||
|
@ -60,7 +59,7 @@ int sys_select_nt(int nfds, fd_set *readfds, fd_set *writefds,
|
|||
}
|
||||
|
||||
// call our nt poll implementation
|
||||
fdcount = sys_poll_nt(fds, pfds, &millis);
|
||||
fdcount = sys_poll_nt(fds, pfds, &millis, sigmask);
|
||||
if (fdcount == -1) return -1;
|
||||
|
||||
// convert pollfd back to bitsets
|
||||
|
|
|
@ -19,9 +19,11 @@
|
|||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/select.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Does what poll() does except with bitset API.
|
||||
|
@ -35,10 +37,18 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||
int rc;
|
||||
POLLTRACE("select(%d, %p, %p, %p, %s) → ...", nfds, readfds, writefds,
|
||||
exceptfds, DescribeTimeval(0, timeout));
|
||||
if (!IsWindows()) {
|
||||
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))) ||
|
||||
(timeout && !__asan_is_valid(timeout, sizeof(*timeout))))) {
|
||||
rc = efault();
|
||||
} else if (!IsWindows()) {
|
||||
rc = sys_select(nfds, readfds, writefds, exceptfds, timeout);
|
||||
} else {
|
||||
rc = sys_select_nt(nfds, readfds, writefds, exceptfds, timeout);
|
||||
rc = sys_select_nt(nfds, readfds, writefds, exceptfds, timeout, 0);
|
||||
}
|
||||
POLLTRACE("select(%d, %p, %p, %p, [%s]) → %d% m", nfds, readfds, writefds,
|
||||
exceptfds, DescribeTimeval(rc, timeout), rc);
|
||||
|
|
|
@ -11,13 +11,14 @@
|
|||
COSMOPOLITAN_C_START_
|
||||
|
||||
typedef struct fd_set {
|
||||
uint64_t fds_bits[FD_SETSIZE / 64];
|
||||
unsigned long fds_bits[FD_SETSIZE / (sizeof(long) * CHAR_BIT)];
|
||||
} fd_set;
|
||||
|
||||
#define FD_ISSET(FD, SET) (((SET)->fds_bits[(FD) >> 6] >> ((FD)&63)) & 1)
|
||||
#define FD_SET(FD, SET) ((SET)->fds_bits[(FD) >> 6] |= 1ull << ((FD)&63))
|
||||
#define FD_CLR(FD, SET) ((SET)->fds_bits[(FD) >> 6] &= ~(1ull << ((FD)&63)))
|
||||
#define FD_ZERO(SET) bzero((SET)->fds_bits, sizeof((SET)->fds_bits))
|
||||
#define FD_SIZE(bits) (((bits) + (sizeof(long) * CHAR_BIT) - 1) / sizeof(long))
|
||||
|
||||
int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
|
||||
int pselect(int, fd_set *, fd_set *, fd_set *, const struct timespec *,
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_SOCK_STRUCT_POLLFD_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_POLLFD_INTERNAL_H_
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/sock/struct/pollfd.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int32_t sys_poll(struct pollfd *, uint64_t, signed) hidden;
|
||||
int sys_ppoll(struct pollfd *, size_t, const struct timespec *,
|
||||
const sigset_t *);
|
||||
int sys_poll_metal(struct pollfd *, size_t, unsigned);
|
||||
int sys_poll_nt(struct pollfd *, uint64_t, uint64_t *) hidden;
|
||||
int sys_poll_nt(struct pollfd *, uint64_t, uint64_t *, const sigset_t *) hidden;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue