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:
Justine Tunney 2022-08-15 15:18:37 -07:00
parent d3b599a796
commit f0701d2a24
35 changed files with 635 additions and 340 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -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 *,

View file

@ -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) */