Improve system call support

This commit is contained in:
Justine Tunney 2021-08-25 21:35:58 -07:00
parent 63b867bd2f
commit 3085ac7837
65 changed files with 900 additions and 544 deletions

View file

@ -24,9 +24,12 @@
#include "libc/sock/internal.h"
#include "libc/sock/yoink.inc"
#include "libc/sysv/consts/fio.h"
#include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/poll.h"
#include "libc/sysv/consts/so.h"
#include "libc/sysv/consts/sock.h"
#include "libc/sysv/consts/sol.h"
#include "libc/sysv/errfuns.h"
textwindows int sys_accept_nt(struct Fd *fd, void *addr, uint32_t *addrsize,
@ -38,33 +41,28 @@ textwindows int sys_accept_nt(struct Fd *fd, void *addr, uint32_t *addrsize,
for (;;) {
if (!WSAPoll(&(struct sys_pollfd_nt){fd->handle, POLLIN}, 1, 1000))
continue;
if ((client = __reservefd()) == -1) return -1;
if ((h = WSAAccept(fd->handle, addr, (int32_t *)addrsize, 0, 0)) != -1) {
oflags = 0;
if (flags & SOCK_CLOEXEC) oflags |= O_CLOEXEC;
if (flags & SOCK_NONBLOCK) oflags |= O_NONBLOCK;
if (flags & SOCK_NONBLOCK) {
if (__sys_ioctlsocket_nt(g_fds.p[client].handle, FIONBIO,
(uint32_t[]){1}) == -1) {
__winsockerr();
__sys_closesocket_nt(g_fds.p[client].handle);
__releasefd(client);
return -1;
if ((!(flags & SOCK_NONBLOCK) ||
__sys_ioctlsocket_nt(h, FIONBIO, (uint32_t[]){1}) != -1) &&
(sockfd2 = calloc(1, sizeof(struct SockFd)))) {
if ((client = __reservefd()) != -1) {
sockfd2->family = sockfd->family;
sockfd2->type = sockfd->type;
sockfd2->protocol = sockfd->protocol;
sockfd2->event = WSACreateEvent();
g_fds.p[client].kind = kFdSocket;
g_fds.p[client].flags = oflags;
g_fds.p[client].handle = h;
g_fds.p[client].extra = (uintptr_t)sockfd2;
return client;
}
free(sockfd2);
}
sockfd2 = calloc(1, sizeof(struct SockFd));
sockfd2->family = sockfd->family;
sockfd2->type = sockfd->type;
sockfd2->protocol = sockfd->protocol;
sockfd2->event = WSACreateEvent();
g_fds.p[client].kind = kFdSocket;
g_fds.p[client].flags = oflags;
g_fds.p[client].handle = h;
g_fds.p[client].extra = (uintptr_t)sockfd2;
return client;
} else {
__releasefd(client);
return __winsockerr();
__sys_closesocket_nt(h);
}
return __winsockerr();
}
}

View file

@ -26,24 +26,27 @@
#include "libc/sysv/consts/poll.h"
#include "libc/sysv/errfuns.h"
textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t timeoutms) {
int got;
size_t i;
uint64_t waitfor;
textwindows int sys_poll_nt(struct pollfd *fds, uint64_t nfds, uint64_t ms) {
int i, got, waitfor;
struct sys_pollfd_nt ntfds[64];
if (nfds > 64) return einval();
if (nfds >= ARRAYLEN(ntfds)) return einval();
for (i = 0; i < nfds; ++i) {
if (!__isfdkind(fds[i].fd, kFdSocket)) return ebadf();
ntfds[i].handle = g_fds.p[fds[i].fd].handle;
ntfds[i].events = fds[i].events & (POLLPRI | POLLIN | POLLOUT);
if (fds[i].fd >= 0) {
if (!__isfdkind(fds[i].fd, kFdSocket)) return enotsock();
ntfds[i].handle = g_fds.p[fds[i].fd].handle;
ntfds[i].events = fds[i].events & (POLLPRI | POLLIN | POLLOUT);
} else {
ntfds[i].handle = -1;
ntfds[i].events = POLLIN;
}
}
for (;;) {
if (cmpxchg(&__interrupted, true, false)) return eintr();
waitfor = MIN(1000, timeoutms); /* for ctrl+c */
waitfor = MIN(1000, ms); /* for ctrl+c */
if ((got = WSAPoll(ntfds, nfds, waitfor)) != -1) {
if (!got && (timeoutms -= waitfor)) continue;
if (!got && (ms -= waitfor) > 0) continue;
for (i = 0; i < nfds; ++i) {
fds[i].revents = ntfds[i].revents;
fds[i].revents = ntfds[i].handle < 0 ? 0 : ntfds[i].revents;
}
return got;
} else {

View file

@ -18,16 +18,21 @@
*/
#include "libc/calls/internal.h"
#include "libc/mem/mem.h"
#include "libc/nt/winsock.h"
#include "libc/nt/iphlpapi.h"
#include "libc/nt/winsock.h"
#include "libc/sock/internal.h"
#include "libc/sock/yoink.inc"
#include "libc/sysv/consts/fio.h"
#include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/so.h"
#include "libc/sysv/consts/sock.h"
#include "libc/sysv/consts/sol.h"
/* ioctl(SIOCGIFCONFIG) for Windows need to access the following functions through
* weak reference. This ensure those symbols are not stripped during final link
/*
* ioctl(SIOCGIFCONFIG) for Windows need to access the following
* functions through weak reference. This ensure those symbols are not
* stripped during final link.
*/
STATIC_YOINK("GetAdaptersAddresses");
STATIC_YOINK("tprecode16to8");

View file

@ -23,7 +23,9 @@
#include "libc/sysv/errfuns.h"
/**
* Creates new system resource for network communication.
* Creates new system resource for network communication, e.g.
*
* int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
*
* @param family can be AF_UNIX, AF_INET, etc.
* @param type can be SOCK_STREAM (for TCP), SOCK_DGRAM (e.g. UDP), or