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 */
};