mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Fix some more socket bugs
- The functions that return a sockaddr now do so the same way the Linux Kernel does across platforms, e.g. getpeername(), accept4() - Socket system calls on Windows will now only check for interrupts when a blocking operation needs to be performed. - Write tests for recvfrom() system call
This commit is contained in:
parent
ac92f25296
commit
0ba3199915
49 changed files with 347 additions and 352 deletions
|
@ -18,13 +18,12 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/winsock.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/struct/sockaddr.h"
|
||||
#include "libc/sock/struct/sockaddr.internal.h"
|
||||
#include "libc/sock/struct/sockaddr6.h"
|
||||
#include "libc/sock/syscall_fd.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
|
@ -32,7 +31,7 @@
|
|||
#include "libc/sysv/consts/sock.h"
|
||||
|
||||
union AcceptExAddr {
|
||||
union sockaddr_storage_linux addr;
|
||||
struct sockaddr_storage addr;
|
||||
char buf[sizeof(struct sockaddr_storage) + 16];
|
||||
};
|
||||
|
||||
|
@ -41,30 +40,8 @@ struct AcceptExBuffer {
|
|||
union AcceptExAddr remote;
|
||||
};
|
||||
|
||||
static void CopyLinuxSockAddr(const union sockaddr_storage_linux *addr,
|
||||
void *out_addr, uint32_t *inout_addrsize) {
|
||||
uint32_t insize, outsize;
|
||||
if (out_addr && inout_addrsize) {
|
||||
if (addr->sa.sa_family == AF_INET) {
|
||||
outsize = sizeof(struct sockaddr_in);
|
||||
} else if (addr->sa.sa_family == AF_INET6) {
|
||||
outsize = sizeof(struct sockaddr_in6);
|
||||
} else if (addr->sa.sa_family == AF_UNIX) {
|
||||
outsize = sizeof(addr->sun.sun_family) +
|
||||
strnlen(addr->sun.sun_path, sizeof(addr->sun.sun_path)) + 1;
|
||||
} else {
|
||||
outsize = sizeof(union sockaddr_storage_linux);
|
||||
}
|
||||
insize = *inout_addrsize;
|
||||
if (insize) bzero(out_addr, insize);
|
||||
outsize = MIN(insize, outsize);
|
||||
if (outsize) memcpy(out_addr, addr, outsize);
|
||||
*inout_addrsize = outsize;
|
||||
}
|
||||
}
|
||||
|
||||
textwindows int sys_accept_nt(struct Fd *fd, void *out_addr,
|
||||
uint32_t *inout_addrsize, int accept4_flags) {
|
||||
textwindows int sys_accept_nt(struct Fd *fd, struct sockaddr_storage *addr,
|
||||
int accept4_flags) {
|
||||
int64_t handle;
|
||||
int rc, client, oflags;
|
||||
uint32_t bytes_received;
|
||||
|
@ -72,11 +49,6 @@ textwindows int sys_accept_nt(struct Fd *fd, void *out_addr,
|
|||
struct AcceptExBuffer buffer;
|
||||
struct SockFd *sockfd, *sockfd2;
|
||||
|
||||
// deliver interrupt instead if any are pending
|
||||
if (_check_interrupts(true, g_fds.p)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// creates resources for child socket
|
||||
// inherit the listener configuration
|
||||
sockfd = (struct SockFd *)fd->extra;
|
||||
|
@ -120,6 +92,6 @@ textwindows int sys_accept_nt(struct Fd *fd, void *out_addr,
|
|||
__fds_unlock();
|
||||
|
||||
// handoff information to caller;
|
||||
CopyLinuxSockAddr(&buffer.remote.addr, out_addr, inout_addrsize);
|
||||
memcpy(addr, &buffer.remote.addr, sizeof(*addr));
|
||||
return client;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue