Add more apis to redbean unix module

- Document unix.fcntl()
- Add POSIX Advisory Locks
- Add mask parameter to unix.poll()
- Add lowest parameter to unix.dup()
This commit is contained in:
Justine Tunney 2022-08-16 23:23:34 -07:00
parent ce588dd56b
commit a1aaf23dc1
16 changed files with 432 additions and 102 deletions

View file

@ -110,8 +110,9 @@ textwindows int sys_fcntl_nt(int fd, int cmd, uintptr_t arg) {
uint32_t flags;
if (__isfdkind(fd, kFdFile) || __isfdkind(fd, kFdSocket)) {
if (cmd == F_GETFL) {
return g_fds.p[fd].flags & (O_ACCMODE | O_APPEND | O_ASYNC | O_DIRECT |
O_NOATIME | O_NONBLOCK);
return g_fds.p[fd].flags &
(O_ACCMODE | O_APPEND | O_ASYNC | O_DIRECT | O_NOATIME |
O_NONBLOCK | O_RANDOM | O_SEQUENTIAL);
} else if (cmd == F_SETFL) {
// O_APPEND doesn't appear to be tunable at cursory glance
// O_NONBLOCK might require we start doing all i/o in threads
@ -131,7 +132,7 @@ textwindows int sys_fcntl_nt(int fd, int cmd, uintptr_t arg) {
g_fds.p[fd].flags &= ~O_CLOEXEC;
return 0;
}
} else if (cmd == F_SETLK || cmd == F_SETLKW) {
} else if (cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK) {
return sys_fcntl_nt_lock(g_fds.p + fd, cmd, arg);
} else if (cmd == F_DUPFD || cmd == F_DUPFD_CLOEXEC) {
return sys_fcntl_nt_dupfd(fd, cmd, arg);

View file

@ -74,14 +74,12 @@ void flock2cosmo(uintptr_t memory) {
l_pid = u->linux.l_pid;
l_type = u->linux.l_type;
l_whence = u->linux.l_whence;
l_sysid = 0;
} else if (IsXnu()) {
l_start = u->xnu.l_start;
l_len = u->xnu.l_len;
l_pid = u->xnu.l_pid;
l_type = u->xnu.l_type;
l_whence = u->xnu.l_whence;
l_sysid = 0;
} else if (IsFreebsd()) {
l_start = u->freebsd.l_start;
l_len = u->freebsd.l_len;
@ -89,20 +87,19 @@ void flock2cosmo(uintptr_t memory) {
l_type = u->freebsd.l_type;
l_whence = u->freebsd.l_whence;
l_sysid = u->freebsd.l_sysid;
u->cosmo.l_sysid = l_sysid;
} else if (IsOpenbsd()) {
l_start = u->openbsd.l_start;
l_len = u->openbsd.l_len;
l_pid = u->openbsd.l_pid;
l_type = u->openbsd.l_type;
l_whence = u->openbsd.l_whence;
l_sysid = 0;
} else if (IsNetbsd()) {
l_start = u->netbsd.l_start;
l_len = u->netbsd.l_len;
l_pid = u->netbsd.l_pid;
l_type = u->netbsd.l_type;
l_whence = u->netbsd.l_whence;
l_sysid = 0;
} else {
return;
}
@ -111,7 +108,6 @@ void flock2cosmo(uintptr_t memory) {
u->cosmo.l_pid = l_pid;
u->cosmo.l_type = l_type;
u->cosmo.l_whence = l_whence;
u->cosmo.l_sysid = l_sysid;
}
void cosmo2flock(uintptr_t memory) {

View file

@ -61,17 +61,22 @@ textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t *ms,
struct sys_pollfd_nt sockfds[64];
int pipeindices[ARRAYLEN(pipefds)];
int sockindices[ARRAYLEN(sockfds)];
int i, sn, pn, failed, gotinvals, gotpipes, gotsocks, waitfor;
int i, rc, sn, pn, gotinvals, gotpipes, gotsocks, waitfor;
// check for interrupts early before doing work
if (sigmask && __sig_mask(SIG_SETMASK, sigmask, &oldmask)) return -1;
if (_check_interrupts(false, g_fds.p)) return eintr();
if (sigmask) {
__sig_mask(SIG_SETMASK, sigmask, &oldmask);
}
if (_check_interrupts(false, g_fds.p)) {
rc = eintr();
goto ReturnPath;
}
// do the planning
// we need to read static variables
// we might need to spawn threads and open pipes
__fds_lock();
for (gotinvals = failed = sn = pn = i = 0; i < nfds; ++i) {
for (gotinvals = rc = sn = pn = i = 0; i < nfds; ++i) {
if (fds[i].fd < 0) continue;
if (__isfdopen(fds[i].fd)) {
if (__isfdkind(fds[i].fd, kFdSocket)) {
@ -85,7 +90,7 @@ textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t *ms,
++sn;
} else {
// too many socket fds
failed = enomem();
rc = enomem();
break;
}
} else if (pn < ARRAYLEN(pipefds)) {
@ -109,7 +114,7 @@ textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t *ms,
++pn;
} else {
// too many non-socket fds
failed = enomem();
rc = enomem();
break;
}
} else {
@ -117,9 +122,9 @@ textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t *ms,
}
}
__fds_unlock();
if (failed) {
if (rc) {
// failed to create a polling solution
return failed;
goto ReturnPath;
}
// perform the i/o and sleeping and looping
@ -164,7 +169,8 @@ textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t *ms,
POLLTRACE("WSAPoll(%p, %u, %'d) out of %'lu", sockfds, sn, waitfor, *ms);
#endif
if ((gotsocks = WSAPoll(sockfds, sn, waitfor)) == -1) {
return __winsockerr();
rc = __winsockerr();
goto ReturnPath;
}
*ms -= waitfor;
} else {
@ -188,7 +194,8 @@ textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t *ms,
// otherwise loop limitlessly for timeout to elapse while
// checking for signal delivery interrupts, along the way
if (_check_interrupts(false, g_fds.p)) {
return eintr();
rc = eintr();
goto ReturnPath;
}
}
@ -209,5 +216,11 @@ textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t *ms,
}
// and finally return
return gotinvals + gotpipes + gotsocks;
rc = gotinvals + gotpipes + gotsocks;
ReturnPath:
if (sigmask) {
__sig_mask(SIG_SETMASK, &oldmask, 0);
}
return rc;
}

View file

@ -7,7 +7,7 @@ struct flock { /* cosmopolitan abi */
int16_t l_type; /* F_RDLCK, F_WRLCK, F_UNLCK */
int16_t l_whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
int64_t l_start; /* starting offset */
int64_t l_len; /* 0 means until end of file */
int64_t l_len; /* no. bytes (0 means to end of file) */
int32_t l_pid; /* lock owner */
int32_t l_sysid; /* remote system id or zero for local */
};

View file

@ -61,6 +61,7 @@ kOpenFlags:
.e O_SEQUENTIAL,"SEQUENTIAL" // windows
.e O_COMPRESSED,"COMPRESSED" // windows
.e O_INDEXED,"INDEXED" // windows
.e O_LARGEFILE,"LARGEFILE" //
.long MAGNUM_TERMINATOR
.endobj kOpenFlags,globl,hidden
.overrun

View file

@ -52,7 +52,7 @@ int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval tv, *tvp;
struct timespec ts, *tsp;
struct {
sigset_t *s;
const sigset_t *s;
size_t n;
} ss;
if (nfds < 0) {

View file

@ -213,7 +213,7 @@ syscon open O_VERIFY 0 0 0x00200000 0 0 0 #
syscon open O_SHLOCK 0 0x00000010 0x00000010 0x00000010 0x00000010 0 #
syscon open O_EXLOCK 0 0x00000020 0x00000020 0x00000020 0x00000020 0 #
syscon open O_TTY_INIT 0 0 0x00080000 0 0 0 #
syscon compat O_LARGEFILE 0 0 0 0 0 0 #
syscon compat O_LARGEFILE 0100000 0 0 0 0 0 #
# mmap() flags
# the revolutionary praxis of malloc()

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon compat,O_LARGEFILE,0,0,0,0,0,0
.syscon compat,O_LARGEFILE,0100000,0,0,0,0,0