mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-25 20:10:29 +00:00
Make fixes and improvements
- Introduce __assert_disable global - Improve strsignal() thread safety - Make system call tracing thread safe - Fix SO_RCVTIMEO / SO_SNDTIMEO on Windows - Refactor DescribeFoo() functions into one place - Fix fork() on Windows when TLS and MAP_STACK exist - Round upwards in setsockopt(SO_RCVTIMEO) on Windows - Disable futexes on OpenBSD which seem extremely broken - Implement a better kludge for monotonic time on Windows
This commit is contained in:
parent
5d837c4e7c
commit
fbc053e018
186 changed files with 1836 additions and 1325 deletions
|
@ -19,9 +19,9 @@
|
|||
#include "libc/calls/strace.internal.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/sock.h"
|
||||
#include "libc/sock/sockdebug.h"
|
||||
#include "libc/sock/syscall_fd.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -51,7 +51,6 @@ int accept4(int fd, void *out_addr, uint32_t *inout_addrsize, int flags) {
|
|||
rc = ebadf();
|
||||
}
|
||||
STRACE("accept4(%d, [%s]) -> %d% lm", fd,
|
||||
__describe_sockaddr(out_addr, inout_addrsize ? *inout_addrsize : 0),
|
||||
rc);
|
||||
DescribeSockaddr(out_addr, inout_addrsize ? *inout_addrsize : 0), rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -20,14 +20,18 @@
|
|||
#include "libc/calls/strace.internal.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/sock.h"
|
||||
#include "libc/sock/sockdebug.h"
|
||||
#include "libc/sock/syscall_fd.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Assigns local address and port number to socket.
|
||||
* Assigns local address and port number to socket, e.g.
|
||||
*
|
||||
* struct sockaddr_in in = {AF_INET, htons(12345), {htonl(0x7f000001)}};
|
||||
* int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
* bind(fd, &in, sizeof(in));
|
||||
*
|
||||
* @param fd is the file descriptor returned by socket()
|
||||
* @param addr is usually the binary-encoded ip:port on which to listen
|
||||
|
@ -51,6 +55,6 @@ int bind(int fd, const void *addr, uint32_t addrsize) {
|
|||
} else {
|
||||
rc = einval();
|
||||
}
|
||||
STRACE("bind(%d, %s) -> %d% lm", fd, __describe_sockaddr(addr, addrsize), rc);
|
||||
STRACE("bind(%d, %s) -> %d% lm", fd, DescribeSockaddr(addr, addrsize), rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -25,8 +25,11 @@
|
|||
|
||||
textwindows int sys_connect_nt(struct Fd *fd, const void *addr,
|
||||
uint32_t addrsize) {
|
||||
struct SockFd *sockfd;
|
||||
sockfd = (struct SockFd *)fd->extra;
|
||||
assert(fd->kind == kFdSocket);
|
||||
return __winsockblock(
|
||||
fd->handle, FD_CONNECT_BIT,
|
||||
WSAConnect(fd->handle, addr, addrsize, NULL, NULL, NULL, NULL));
|
||||
WSAConnect(fd->handle, addr, addrsize, NULL, NULL, NULL, NULL),
|
||||
sockfd->rcvtimeo);
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@
|
|||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/sockdebug.h"
|
||||
#include "libc/sock/syscall_fd.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -51,7 +51,6 @@ int connect(int fd, const void *addr, uint32_t addrsize) {
|
|||
} else {
|
||||
rc = efault();
|
||||
}
|
||||
STRACE("connect(%d, %s) -> %d% lm", fd, __describe_sockaddr(addr, addrsize),
|
||||
rc);
|
||||
STRACE("connect(%d, %s) -> %d% lm", fd, DescribeSockaddr(addr, addrsize), rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
|
||||
/**
|
||||
* Describes setsockopt() level arguments.
|
||||
*/
|
||||
char *DescribeSockLevel(int x) {
|
||||
static char buf[12];
|
||||
if (x == SOL_IP) return "SOL_IP";
|
||||
if (x == SOL_TCP) return "SOL_TCP";
|
||||
if (x == SOL_UDP) return "SOL_UDP";
|
||||
if (x == SOL_SOCKET) return "SOL_SOCKET";
|
||||
FormatInt32(buf, x);
|
||||
return buf;
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
|
||||
/**
|
||||
* Describes setsockopt() optname arguments.
|
||||
*/
|
||||
char *DescribeSockOptname(int l, int x) {
|
||||
int i;
|
||||
char *ps, *s;
|
||||
const struct MagnumStr *ms = 0;
|
||||
_Alignas(char) static char buf[32];
|
||||
if (x) {
|
||||
if (l == SOL_SOCKET) {
|
||||
ps = "SO_";
|
||||
ms = kSockOptnames;
|
||||
} else if (l == SOL_TCP) {
|
||||
ps = "TCP_";
|
||||
ms = kTcpOptnames;
|
||||
} else if (l == SOL_IP) {
|
||||
ps = "IP_";
|
||||
ms = kIpOptnames;
|
||||
}
|
||||
}
|
||||
if (ms && (s = GetMagnumStr(ms, x))) {
|
||||
stpcpy(stpcpy(buf, ps), s);
|
||||
return buf;
|
||||
} else {
|
||||
FormatInt32(buf, x);
|
||||
return buf;
|
||||
}
|
||||
}
|
|
@ -19,9 +19,9 @@
|
|||
#include "libc/calls/strace.internal.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/sock.h"
|
||||
#include "libc/sock/sockdebug.h"
|
||||
#include "libc/sock/syscall_fd.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -44,6 +44,6 @@ int getpeername(int fd, void *out_addr, uint32_t *out_addrsize) {
|
|||
rc = ebadf();
|
||||
}
|
||||
STRACE("getpeername(%d, [%s]) -> %d% lm", fd,
|
||||
__describe_sockaddr(out_addr, out_addrsize ? *out_addrsize : 0), rc);
|
||||
DescribeSockaddr(out_addr, out_addrsize ? *out_addrsize : 0), rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
#include "libc/calls/strace.internal.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/sock.h"
|
||||
#include "libc/sock/sockdebug.h"
|
||||
#include "libc/sock/syscall_fd.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -44,6 +44,6 @@ int getsockname(int fd, void *out_addr, uint32_t *out_addrsize) {
|
|||
rc = ebadf();
|
||||
}
|
||||
STRACE("getsockname(%d, [%s]) -> %d% lm", fd,
|
||||
__describe_sockaddr(out_addr, out_addrsize ? *out_addrsize : 0), rc);
|
||||
DescribeSockaddr(out_addr, out_addrsize ? *out_addrsize : 0), rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -26,14 +26,17 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/so.h"
|
||||
#include "libc/sysv/consts/sol.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_getsockopt_nt(struct Fd *fd, int level, int optname,
|
||||
void *out_opt_optval,
|
||||
uint32_t *inout_optlen) {
|
||||
uint64_t ms;
|
||||
uint32_t in_optlen;
|
||||
struct SockFd *sockfd;
|
||||
struct linger_nt linger;
|
||||
assert(fd->kind == kFdSocket);
|
||||
sockfd = (struct SockFd *)fd->extra;
|
||||
|
||||
if (out_opt_optval && inout_optlen) {
|
||||
in_optlen = *inout_optlen;
|
||||
|
@ -41,6 +44,23 @@ textwindows int sys_getsockopt_nt(struct Fd *fd, int level, int optname,
|
|||
in_optlen = 0;
|
||||
}
|
||||
|
||||
if (level == SOL_SOCKET &&
|
||||
(optname == SO_RCVTIMEO || optname == SO_SNDTIMEO)) {
|
||||
if (in_optlen >= sizeof(struct timeval)) {
|
||||
if (optname == SO_RCVTIMEO) {
|
||||
ms = sockfd->rcvtimeo;
|
||||
} else {
|
||||
ms = sockfd->sndtimeo;
|
||||
}
|
||||
((struct timeval *)out_opt_optval)->tv_sec = ms / 1000;
|
||||
((struct timeval *)out_opt_optval)->tv_usec = ms % 1000 * 1000;
|
||||
*inout_optlen = sizeof(struct timeval);
|
||||
return 0;
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jart): Use WSAIoctl?
|
||||
if (__sys_getsockopt_nt(fd->handle, level, optname, out_opt_optval,
|
||||
inout_optlen) == -1) {
|
||||
|
@ -48,14 +68,7 @@ textwindows int sys_getsockopt_nt(struct Fd *fd, int level, int optname,
|
|||
}
|
||||
|
||||
if (level == SOL_SOCKET) {
|
||||
if ((optname == SO_RCVTIMEO || optname == SO_SNDTIMEO) &&
|
||||
in_optlen == sizeof(struct timeval) &&
|
||||
*inout_optlen == sizeof(uint32_t)) {
|
||||
ms = *(uint32_t *)out_opt_optval;
|
||||
((struct timeval *)out_opt_optval)->tv_sec = ms / 1000;
|
||||
((struct timeval *)out_opt_optval)->tv_usec = ms % 1000 * 1000;
|
||||
*inout_optlen = sizeof(struct timeval);
|
||||
} else if (optname == SO_LINGER && in_optlen == sizeof(struct linger)) {
|
||||
if (optname == SO_LINGER && in_optlen == sizeof(struct linger)) {
|
||||
linger = *(struct linger_nt *)out_opt_optval;
|
||||
((struct linger *)out_opt_optval)->l_onoff = !!linger.l_onoff;
|
||||
((struct linger *)out_opt_optval)->l_linger = linger.l_linger;
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/syscall_fd.internal.h"
|
||||
|
|
|
@ -72,6 +72,8 @@ struct SockFd {
|
|||
int family;
|
||||
int type;
|
||||
int protocol;
|
||||
uint32_t rcvtimeo;
|
||||
uint32_t sndtimeo;
|
||||
bool32 (*__msabi ConnectEx)(int64_t s, const struct sockaddr *name,
|
||||
int namelen, const void *opt_lpSendBuffer,
|
||||
uint32_t dwSendDataLength,
|
||||
|
@ -144,8 +146,9 @@ ssize_t sys_sendto_nt(int, const struct iovec *, size_t, uint32_t, void *,
|
|||
void WinSockInit(void) hidden;
|
||||
int64_t __winsockerr(void) nocallback hidden;
|
||||
int __fixupnewsockfd(int, int) hidden;
|
||||
int __wsablock(int64_t, struct NtOverlapped *, uint32_t *, bool) hidden;
|
||||
int64_t __winsockblock(int64_t, unsigned, int64_t) hidden;
|
||||
int __wsablock(int64_t, struct NtOverlapped *, uint32_t *, bool,
|
||||
uint32_t) hidden;
|
||||
int64_t __winsockblock(int64_t, unsigned, int64_t, uint32_t) hidden;
|
||||
struct SockFd *_dupsockfd(struct SockFd *) hidden;
|
||||
int64_t GetNtBaseSocket(int64_t) hidden;
|
||||
int sys_close_epoll(int) hidden;
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.macro .e e s
|
||||
.long \e - kIpOptnames
|
||||
.long 1f - kIpOptnames
|
||||
.rodata.str1.1
|
||||
1: .string "\s"
|
||||
.previous
|
||||
.endm
|
||||
|
||||
.section .rodata
|
||||
.align 4
|
||||
.underrun
|
||||
kIpOptnames:
|
||||
.e IP_TOS,"TOS" # int
|
||||
.e IP_MTU,"MTU" # int
|
||||
.e IP_TTL,"TTL" # int
|
||||
.e IP_HDRINCL,"HDRINCL" # bool32
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kIpOptnames,globl,hidden
|
||||
.overrun
|
|
@ -1,52 +0,0 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.macro .e e s
|
||||
.long \e - kSockOptnames
|
||||
.long 1f - kSockOptnames
|
||||
.rodata.str1.1
|
||||
1: .string "\s"
|
||||
.previous
|
||||
.endm
|
||||
|
||||
.section .rodata
|
||||
.align 4
|
||||
.underrun
|
||||
kSockOptnames:
|
||||
.e SO_DEBUG,"DEBUG" # bool32
|
||||
.e SO_ACCEPTCONN,"ACCEPTCONN" # bool32
|
||||
.e SO_BROADCAST,"BROADCAST" # bool32
|
||||
.e SO_REUSEADDR,"REUSEADDR" # bool32
|
||||
.e SO_REUSEPORT,"REUSEPORT" # bool32
|
||||
.e SO_KEEPALIVE,"KEEPALIVE" # bool32
|
||||
.e SO_DONTROUTE,"DONTROUTE" # bool32
|
||||
.e SO_RCVTIMEO,"RCVTIMEO" # timeval
|
||||
.e SO_SNDTIMEO,"SNDTIMEO" # timeval
|
||||
.e SO_LINGER,"LINGER" # linger
|
||||
.e SO_TYPE,"TYPE" # int
|
||||
.e SO_SNDBUF,"SNDBUF" # int
|
||||
.e SO_RCVBUF,"RCVBUF" # int
|
||||
.e SO_RCVLOWAT,"RCVLOWAT" # int
|
||||
.e SO_SNDLOWAT,"SNDLOWAT" # int
|
||||
.e SO_ERROR,"ERROR" # int
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kSockOptnames,globl,hidden
|
||||
.overrun
|
|
@ -1,49 +0,0 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
.macro .e e s
|
||||
.long \e - kTcpOptnames
|
||||
.long 1f - kTcpOptnames
|
||||
.rodata.str1.1
|
||||
1: .string "\s"
|
||||
.previous
|
||||
.endm
|
||||
|
||||
.section .rodata
|
||||
.align 4
|
||||
.underrun
|
||||
kTcpOptnames:
|
||||
.e TCP_NODELAY,"NODELAY" # bool32
|
||||
.e TCP_CORK,"CORK" # bool32
|
||||
.e TCP_QUICKACK,"QUICKACK" # bool32
|
||||
.e TCP_FASTOPEN_CONNECT,"FASTOPEN_CONNECT" # bool32
|
||||
.e TCP_DEFER_ACCEPT,"DEFER_ACCEPT" # bool32
|
||||
.e TCP_KEEPIDLE,"KEEPIDLE" # int (seconds)
|
||||
.e TCP_KEEPINTVL,"KEEPINTVL" # int (seconds)
|
||||
.e TCP_FASTOPEN,"FASTOPEN" # int
|
||||
.e TCP_KEEPCNT,"KEEPCNT" # int
|
||||
.e TCP_MAXSEG,"MAXSEG" # int
|
||||
.e TCP_SYNCNT,"SYNCNT" # int
|
||||
.e TCP_NOTSENT_LOWAT,"NOTSENT_LOWAT" # int
|
||||
.e TCP_WINDOW_CLAMP,"WINDOW_CLAMP" # int
|
||||
.long MAGNUM_TERMINATOR
|
||||
.endobj kTcpOptnames,globl,hidden
|
||||
.overrun
|
|
@ -16,7 +16,11 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/likely.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/nt/struct/overlapped.h"
|
||||
#include "libc/nt/winsock.h"
|
||||
#include "libc/sock/internal.h"
|
||||
|
@ -31,16 +35,21 @@
|
|||
*/
|
||||
textwindows ssize_t sys_recv_nt(struct Fd *fd, const struct iovec *iov,
|
||||
size_t iovlen, uint32_t flags) {
|
||||
int err;
|
||||
ssize_t rc;
|
||||
uint32_t got = 0;
|
||||
struct SockFd *sockfd;
|
||||
struct NtIovec iovnt[16];
|
||||
struct NtOverlapped overlapped = {.hEvent = WSACreateEvent()};
|
||||
if (_check_interrupts(true, g_fds.p)) return eintr();
|
||||
err = errno;
|
||||
if (!WSARecv(fd->handle, iovnt, __iovec2nt(iovnt, iov, iovlen), &got, &flags,
|
||||
&overlapped, NULL)) {
|
||||
rc = got;
|
||||
} else {
|
||||
rc = __wsablock(fd->handle, &overlapped, &flags, true);
|
||||
errno = err;
|
||||
sockfd = (struct SockFd *)fd->extra;
|
||||
rc = __wsablock(fd->handle, &overlapped, &flags, true, sockfd->rcvtimeo);
|
||||
}
|
||||
WSACloseEvent(overlapped.hEvent);
|
||||
return rc;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/nt/struct/overlapped.h"
|
||||
#include "libc/nt/winsock.h"
|
||||
#include "libc/sock/internal.h"
|
||||
|
@ -33,17 +34,22 @@ textwindows ssize_t sys_recvfrom_nt(struct Fd *fd, const struct iovec *iov,
|
|||
size_t iovlen, uint32_t flags,
|
||||
void *opt_out_srcaddr,
|
||||
uint32_t *opt_inout_srcaddrsize) {
|
||||
int err;
|
||||
ssize_t rc;
|
||||
uint32_t got = 0;
|
||||
struct SockFd *sockfd;
|
||||
struct NtIovec iovnt[16];
|
||||
struct NtOverlapped overlapped = {.hEvent = WSACreateEvent()};
|
||||
if (_check_interrupts(true, g_fds.p)) return eintr();
|
||||
err = errno;
|
||||
if (!WSARecvFrom(fd->handle, iovnt, __iovec2nt(iovnt, iov, iovlen), &got,
|
||||
&flags, opt_out_srcaddr, opt_inout_srcaddrsize, &overlapped,
|
||||
NULL)) {
|
||||
rc = got;
|
||||
} else {
|
||||
rc = __wsablock(fd->handle, &overlapped, &flags, true);
|
||||
errno = err;
|
||||
sockfd = (struct SockFd *)fd->extra;
|
||||
rc = __wsablock(fd->handle, &overlapped, &flags, true, sockfd->rcvtimeo);
|
||||
}
|
||||
WSACloseEvent(overlapped.hEvent);
|
||||
return rc;
|
||||
|
|
|
@ -33,6 +33,7 @@ textwindows ssize_t sys_send_nt(int fd, const struct iovec *iov, size_t iovlen,
|
|||
uint32_t flags) {
|
||||
ssize_t rc;
|
||||
uint32_t sent = 0;
|
||||
struct SockFd *sockfd;
|
||||
struct NtIovec iovnt[16];
|
||||
struct NtOverlapped overlapped = {.hEvent = WSACreateEvent()};
|
||||
if (_check_interrupts(true, g_fds.p)) return eintr();
|
||||
|
@ -40,7 +41,9 @@ textwindows ssize_t sys_send_nt(int fd, const struct iovec *iov, size_t iovlen,
|
|||
flags, &overlapped, NULL)) {
|
||||
rc = sent;
|
||||
} else {
|
||||
rc = __wsablock(g_fds.p[fd].handle, &overlapped, &flags, true);
|
||||
sockfd = (struct SockFd *)g_fds.p[fd].extra;
|
||||
rc = __wsablock(g_fds.p[fd].handle, &overlapped, &flags, true,
|
||||
sockfd->sndtimeo);
|
||||
}
|
||||
WSACloseEvent(overlapped.hEvent);
|
||||
return rc;
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
static textwindows int SendfileBlock(int64_t handle,
|
||||
struct NtOverlapped *overlapped) {
|
||||
uint32_t i, got, flags = 0;
|
||||
if (WSAGetLastError() != kNtErrorIoPending) {
|
||||
if (WSAGetLastError() != kNtErrorIoPending &&
|
||||
WSAGetLastError() != WSAEINPROGRESS) {
|
||||
NTTRACE("TransmitFile failed %lm");
|
||||
return __winsockerr();
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ textwindows ssize_t sys_sendto_nt(int fd, const struct iovec *iov,
|
|||
void *opt_in_addr, uint32_t in_addrsize) {
|
||||
ssize_t rc;
|
||||
uint32_t sent = 0;
|
||||
struct SockFd *sockfd;
|
||||
struct NtIovec iovnt[16];
|
||||
struct NtOverlapped overlapped = {.hEvent = WSACreateEvent()};
|
||||
if (_check_interrupts(true, g_fds.p)) return eintr();
|
||||
|
@ -41,7 +42,9 @@ textwindows ssize_t sys_sendto_nt(int fd, const struct iovec *iov,
|
|||
&sent, flags, opt_in_addr, in_addrsize, &overlapped, NULL)) {
|
||||
rc = sent;
|
||||
} else {
|
||||
rc = __wsablock(g_fds.p[fd].handle, &overlapped, &flags, true);
|
||||
sockfd = (struct SockFd *)g_fds.p[fd].extra;
|
||||
rc = __wsablock(g_fds.p[fd].handle, &overlapped, &flags, true,
|
||||
sockfd->sndtimeo);
|
||||
}
|
||||
WSACloseEvent(overlapped.hEvent);
|
||||
return rc;
|
||||
|
|
|
@ -28,9 +28,10 @@
|
|||
|
||||
textwindows int sys_setsockopt_nt(struct Fd *fd, int level, int optname,
|
||||
const void *optval, uint32_t optlen) {
|
||||
int64_t ms;
|
||||
int64_t ms, micros;
|
||||
struct timeval *tv;
|
||||
struct linger *linger;
|
||||
struct SockFd *sockfd;
|
||||
union {
|
||||
uint32_t millis;
|
||||
struct linger_nt linger;
|
||||
|
@ -47,7 +48,8 @@ textwindows int sys_setsockopt_nt(struct Fd *fd, int level, int optname,
|
|||
optlen == sizeof(struct timeval)) {
|
||||
tv = optval;
|
||||
if (__builtin_mul_overflow(tv->tv_sec, 1000, &ms) ||
|
||||
__builtin_add_overflow(ms, tv->tv_usec / 1000, &ms) ||
|
||||
__builtin_add_overflow(tv->tv_usec, 999, µs) ||
|
||||
__builtin_add_overflow(ms, micros / 1000, &ms) ||
|
||||
(ms < 0 || ms > 0xffffffff)) {
|
||||
u.millis = 0xffffffff;
|
||||
} else {
|
||||
|
@ -55,6 +57,14 @@ textwindows int sys_setsockopt_nt(struct Fd *fd, int level, int optname,
|
|||
}
|
||||
optval = &u.millis;
|
||||
optlen = sizeof(u.millis);
|
||||
sockfd = (struct SockFd *)fd->extra;
|
||||
if (optname == SO_RCVTIMEO) {
|
||||
sockfd->rcvtimeo = u.millis;
|
||||
}
|
||||
if (optname == SO_SNDTIMEO) {
|
||||
sockfd->sndtimeo = u.millis;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/magnumstrs.internal.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/nt/winsock.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
#include "libc/bits/bswap.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/sock/struct/linger.h"
|
||||
#include "libc/sock/struct/msghdr.h"
|
||||
#include "libc/sock/struct/pollfd.h"
|
||||
#include "libc/sock/struct/sockaddr.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
|
@ -25,62 +29,11 @@ COSMOPOLITAN_C_START_
|
|||
#define htonl(u32) bswap_32(u32)
|
||||
#define ntohl(u32) bswap_32(u32)
|
||||
|
||||
struct in_addr { /* ARPA ABI */
|
||||
/* e.g. 127|0<<8|0<<16|1<<24 or inet_pton(AF_INET, "127.0.0.1", &s_addr) */
|
||||
uint32_t s_addr;
|
||||
};
|
||||
|
||||
struct sockaddr { /* Linux+NT ABI */
|
||||
uint16_t sa_family; /* AF_XXX */
|
||||
char sa_data[14];
|
||||
};
|
||||
|
||||
struct sockaddr_in { /* Linux+NT ABI */
|
||||
uint16_t sin_family; /* AF_XXX */
|
||||
uint16_t sin_port; /* htons(XXX) i.e. big endian */
|
||||
struct in_addr sin_addr;
|
||||
uint8_t sin_zero[8];
|
||||
};
|
||||
|
||||
struct sockaddr_un {
|
||||
uint16_t sun_family; /* AF_UNIX */
|
||||
char sun_path[108]; /* path */
|
||||
};
|
||||
|
||||
struct sockaddr_storage {
|
||||
union {
|
||||
uint16_t ss_family;
|
||||
intptr_t __ss_align;
|
||||
char __ss_storage[128];
|
||||
};
|
||||
};
|
||||
|
||||
struct ip_mreq {
|
||||
struct in_addr imr_multiaddr; /* IP multicast address of group */
|
||||
struct in_addr imr_interface; /* local IP address of interface */
|
||||
};
|
||||
|
||||
struct linger { /* Linux+XNU+BSD ABI */
|
||||
int32_t l_onoff; /* on/off */
|
||||
int32_t l_linger; /* seconds */
|
||||
};
|
||||
|
||||
struct pollfd {
|
||||
int32_t fd;
|
||||
int16_t events;
|
||||
int16_t revents;
|
||||
};
|
||||
|
||||
struct msghdr { /* Linux+NT ABI */
|
||||
void *msg_name; /* optional address */
|
||||
uint32_t msg_namelen; /* size of msg_name */
|
||||
struct iovec *msg_iov; /* scatter/gather array */
|
||||
uint64_t msg_iovlen; /* iovec count */
|
||||
void *msg_control; /* credentials and stuff */
|
||||
uint64_t msg_controllen; /* size of msg_control */
|
||||
uint32_t msg_flags; /* MSG_XXX */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure used in SIOCGIFCONF request.
|
||||
* Used to retrieve interface configuration
|
||||
|
|
|
@ -6,7 +6,7 @@ PKGS += LIBC_SOCK
|
|||
LIBC_SOCK_ARTIFACTS += LIBC_SOCK_A
|
||||
LIBC_SOCK = $(LIBC_SOCK_A_DEPS) $(LIBC_SOCK_A)
|
||||
LIBC_SOCK_A = o/$(MODE)/libc/sock/sock.a
|
||||
LIBC_SOCK_A_FILES := $(wildcard libc/sock/*)
|
||||
LIBC_SOCK_A_FILES := $(wildcard libc/sock/*) $(wildcard libc/sock/struct/*)
|
||||
LIBC_SOCK_A_HDRS = $(filter %.h,$(LIBC_SOCK_A_FILES))
|
||||
LIBC_SOCK_A_INCS = $(filter %.inc,$(LIBC_SOCK_A_FILES))
|
||||
LIBC_SOCK_A_SRCS_C = $(filter %.c,$(LIBC_SOCK_A_FILES))
|
||||
|
|
|
@ -19,69 +19,24 @@
|
|||
#include "libc/calls/struct/sockaddr6.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/sockdebug.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/ipproto.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
|
||||
const char *__describe_socket_family(int family) {
|
||||
static char buf[12];
|
||||
if (family == AF_UNIX) return "AF_UNIX";
|
||||
if (family == AF_INET) return "AF_INET";
|
||||
if (family == AF_INET6) return "AF_INET6";
|
||||
FormatInt32(buf, family);
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char *__describe_socket_type(int type) {
|
||||
int x;
|
||||
char *p;
|
||||
static char buf[12 + 1 + 12 + 1 + 13 + 1];
|
||||
p = buf;
|
||||
x = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
|
||||
if (x == SOCK_STREAM) {
|
||||
p = stpcpy(p, "SOCK_STREAM");
|
||||
} else if (x == SOCK_DGRAM) {
|
||||
p = stpcpy(p, "SOCK_DGRAM");
|
||||
} else if (x == SOCK_RAW) {
|
||||
p = stpcpy(p, "SOCK_RAW");
|
||||
} else if (x == SOCK_RDM) {
|
||||
p = stpcpy(p, "SOCK_RDM");
|
||||
} else if (x == SOCK_SEQPACKET) {
|
||||
p = stpcpy(p, "SOCK_SEQPACKET");
|
||||
} else {
|
||||
p = FormatInt32(p, x);
|
||||
}
|
||||
if (type & SOCK_CLOEXEC) p = stpcpy(p, "|SOCK_CLOEXEC");
|
||||
if (type & SOCK_NONBLOCK) p = stpcpy(p, "|SOCK_NONBLOCK");
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char *__describe_socket_protocol(int family) {
|
||||
static char buf[12];
|
||||
if (family == IPPROTO_IP) return "IPPROTO_IP";
|
||||
if (family == IPPROTO_ICMP) return "IPPROTO_ICMP";
|
||||
if (family == IPPROTO_TCP) return "IPPROTO_TCP";
|
||||
if (family == IPPROTO_UDP) return "IPPROTO_UDP";
|
||||
if (family == IPPROTO_RAW) return "IPPROTO_RAW";
|
||||
if (family == IPPROTO_IPV6) return "IPPROTO_IPv6";
|
||||
FormatInt32(buf, family);
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char *__describe_sockaddr(const struct sockaddr *sa, size_t sasize) {
|
||||
const char *(DescribeSockaddr)(char buf[128], const struct sockaddr *sa,
|
||||
size_t sasize) {
|
||||
int e;
|
||||
size_t n;
|
||||
uint16_t port;
|
||||
char *p, ip[72];
|
||||
static char buf[128];
|
||||
e = errno;
|
||||
stpcpy(buf, "NULL");
|
||||
if (sa && sasize >= sizeof(sa->sa_family)) {
|
||||
stpcpy(buf, __describe_socket_family(sa->sa_family));
|
||||
stpcpy(buf, DescribeSocketFamily(sa->sa_family));
|
||||
if (sa->sa_family == AF_INET && sasize >= sizeof(struct sockaddr_in)) {
|
||||
const struct sockaddr_in *in;
|
||||
in = (const struct sockaddr_in *)sa;
|
||||
|
@ -108,7 +63,7 @@ const char *__describe_sockaddr(const struct sockaddr *sa, size_t sasize) {
|
|||
const struct sockaddr_un *unix;
|
||||
unix = (const struct sockaddr_un *)sa;
|
||||
n = strnlen(unix->sun_path, sizeof(unix->sun_path));
|
||||
n = MIN(n, sizeof(buf) - 1);
|
||||
n = MIN(n, 128 - 1);
|
||||
memcpy(buf, unix->sun_path, n);
|
||||
buf[n] = 0;
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_SOCK_SOCKDEBUG_H_
|
||||
#define COSMOPOLITAN_LIBC_SOCK_SOCKDEBUG_H_
|
||||
#include "libc/sock/sock.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
const char *__describe_sockaddr(const struct sockaddr *, size_t);
|
||||
const char *__describe_socket_family(int);
|
||||
const char *__describe_socket_type(int);
|
||||
const char *__describe_socket_protocol(int);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_SOCK_SOCKDEBUG_H_ */
|
|
@ -18,9 +18,9 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/sockdebug.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
|
||||
/**
|
||||
|
@ -46,8 +46,7 @@ int socket(int family, int type, int protocol) {
|
|||
} else {
|
||||
rc = sys_socket_nt(family, type, protocol);
|
||||
}
|
||||
STRACE("socket(%s, %s, %s) → %d% lm", __describe_socket_family(family),
|
||||
__describe_socket_type(type), __describe_socket_protocol(protocol),
|
||||
rc);
|
||||
STRACE("socket(%s, %s, %s) → %d% lm", DescribeSocketFamily(family),
|
||||
DescribeSocketType(type), DescribeSocketProtocol(protocol), rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
13
libc/sock/struct/linger.h
Normal file
13
libc/sock/struct/linger.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_SOCK_STRUCT_LINGER_H_
|
||||
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_LINGER_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct linger { /* Linux+XNU+BSD ABI */
|
||||
int32_t l_onoff; /* on/off */
|
||||
int32_t l_linger; /* seconds */
|
||||
};
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_LINGER_H_ */
|
19
libc/sock/struct/msghdr.h
Normal file
19
libc/sock/struct/msghdr.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_SOCK_STRUCT_MSGHDR_H_
|
||||
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_MSGHDR_H_
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct msghdr { /* Linux+NT ABI */
|
||||
void *msg_name; /* optional address */
|
||||
uint32_t msg_namelen; /* size of msg_name */
|
||||
struct iovec *msg_iov; /* scatter/gather array */
|
||||
uint64_t msg_iovlen; /* iovec count */
|
||||
void *msg_control; /* credentials and stuff */
|
||||
uint64_t msg_controllen; /* size of msg_control */
|
||||
uint32_t msg_flags; /* MSG_XXX */
|
||||
};
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_MSGHDR_H_ */
|
14
libc/sock/struct/pollfd.h
Normal file
14
libc/sock/struct/pollfd.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_SOCK_STRUCT_POLLFD_H_
|
||||
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_POLLFD_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct pollfd {
|
||||
int32_t fd;
|
||||
int16_t events;
|
||||
int16_t revents;
|
||||
};
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_POLLFD_H_ */
|
38
libc/sock/struct/sockaddr.h
Normal file
38
libc/sock/struct/sockaddr.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_SOCK_STRUCT_SOCKADDR_H_
|
||||
#define COSMOPOLITAN_LIBC_SOCK_STRUCT_SOCKADDR_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct sockaddr { /* Linux+NT ABI */
|
||||
uint16_t sa_family; /* AF_XXX */
|
||||
char sa_data[14];
|
||||
};
|
||||
|
||||
struct in_addr { /* ARPA ABI */
|
||||
/* e.g. 127|0<<8|0<<16|1<<24 or inet_pton(AF_INET, "127.0.0.1", &s_addr) */
|
||||
uint32_t s_addr;
|
||||
};
|
||||
|
||||
struct sockaddr_in { /* Linux+NT ABI */
|
||||
uint16_t sin_family; /* AF_XXX */
|
||||
uint16_t sin_port; /* htons(XXX) i.e. big endian */
|
||||
struct in_addr sin_addr;
|
||||
uint8_t sin_zero[8];
|
||||
};
|
||||
|
||||
struct sockaddr_un {
|
||||
uint16_t sun_family; /* AF_UNIX */
|
||||
char sun_path[108]; /* path */
|
||||
};
|
||||
|
||||
struct sockaddr_storage {
|
||||
union {
|
||||
uint16_t ss_family;
|
||||
intptr_t __ss_align;
|
||||
char __ss_storage[128];
|
||||
};
|
||||
};
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_SOCK_STRUCT_SOCKADDR_H_ */
|
|
@ -23,7 +23,8 @@
|
|||
#include "libc/sock/sock.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
textwindows int64_t __winsockblock(int64_t fh, unsigned eventbit, int64_t rc) {
|
||||
textwindows int64_t __winsockblock(int64_t fh, unsigned eventbit, int64_t rc,
|
||||
uint32_t timeout) {
|
||||
int64_t eh;
|
||||
struct NtWsaNetworkEvents ev;
|
||||
if (rc != -1) return rc;
|
||||
|
|
|
@ -26,10 +26,11 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int __wsablock(int64_t handle, struct NtOverlapped *overlapped,
|
||||
uint32_t *flags, bool restartable) {
|
||||
uint32_t *flags, bool restartable,
|
||||
uint32_t timeout) {
|
||||
uint32_t i, got;
|
||||
if (WSAGetLastError() != kNtErrorIoPending) {
|
||||
NTTRACE("WSARecv failed %lm");
|
||||
NTTRACE("sock i/o failed %lm");
|
||||
return __winsockerr();
|
||||
}
|
||||
for (;;) {
|
||||
|
@ -39,10 +40,15 @@ textwindows int __wsablock(int64_t handle, struct NtOverlapped *overlapped,
|
|||
NTTRACE("WSAWaitForMultipleEvents failed %lm");
|
||||
return __winsockerr();
|
||||
} else if (i == kNtWaitTimeout || i == kNtWaitIoCompletion) {
|
||||
if (_check_interrupts(restartable, g_fds.p)) return eintr();
|
||||
#if _NTTRACE
|
||||
POLLTRACE("WSAWaitForMultipleEvents...");
|
||||
#endif
|
||||
if (_check_interrupts(restartable, g_fds.p)) {
|
||||
return eintr();
|
||||
}
|
||||
if (timeout) {
|
||||
if (timeout <= __SIG_POLLING_INTERVAL_MS) {
|
||||
return eagain();
|
||||
}
|
||||
timeout -= __SIG_POLLING_INTERVAL_MS;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue