mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-28 15:28:30 +00:00
Add unix domain socket support to redbean
This commit is contained in:
parent
4b23985b7f
commit
fc097ac275
25 changed files with 594 additions and 172 deletions
|
@ -93,12 +93,21 @@ static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) {
|
|||
return rc;
|
||||
}
|
||||
|
||||
forceinline void Sockaddr2linux(void *saddr) {
|
||||
char *p;
|
||||
if (saddr) {
|
||||
p = saddr;
|
||||
p[0] = p[1];
|
||||
p[1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Used for all the ioctl that returns sockaddr structure that
|
||||
* requires adjustment between Linux and XNU
|
||||
*/
|
||||
static int ioctl_siocgifaddr_sysv(int fd, uint64_t op, struct ifreq *ifr) {
|
||||
if (sys_ioctl(fd, op, ifr) == -1) return -1;
|
||||
if (IsBsd()) sockaddr2linux(&ifr->ifr_addr);
|
||||
if (IsBsd()) Sockaddr2linux(&ifr->ifr_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,15 @@
|
|||
|
||||
int sys_accept(int server, void *addr, uint32_t *addrsize) {
|
||||
int client;
|
||||
if ((client = __sys_accept(server, addr, addrsize, 0)) != -1 && IsBsd()) {
|
||||
sockaddr2linux(addr);
|
||||
uint32_t size;
|
||||
union sockaddr_storage_bsd bsd;
|
||||
if (!IsBsd()) {
|
||||
client = __sys_accept(server, addr, addrsize, 0);
|
||||
} else {
|
||||
size = sizeof(bsd);
|
||||
if ((client = __sys_accept(server, &bsd, &size, 0)) != -1) {
|
||||
sockaddr2linux(&bsd, size, addr, addrsize);
|
||||
}
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
|
|
@ -21,27 +21,26 @@
|
|||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
|
||||
#define __NR_accept4_linux 0x0120 /* rhel5:enosysevil */
|
||||
|
||||
int sys_accept4(int server, void *addr, uint32_t *addrsize, int flags) {
|
||||
static bool once, demodernize;
|
||||
if (!flags) return sys_accept(server, addr, addrsize);
|
||||
int olderr, client;
|
||||
if (!flags || demodernize) goto TriedAndTrue;
|
||||
union sockaddr_storage_bsd bsd;
|
||||
uint32_t size = sizeof(bsd);
|
||||
void *out_addr = !IsBsd() ? addr : &bsd;
|
||||
uint32_t *out_addrsize = !IsBsd() ? addrsize : &size;
|
||||
static bool demodernize;
|
||||
if (demodernize) goto TriedAndTrue;
|
||||
olderr = errno;
|
||||
client = __sys_accept4(server, addr, addrsize, flags);
|
||||
client = __sys_accept4(server, out_addr, out_addrsize, flags);
|
||||
if (client == -1 && errno == ENOSYS) {
|
||||
errno = olderr;
|
||||
demodernize = true;
|
||||
TriedAndTrue:
|
||||
client = __fixupnewsockfd(__sys_accept(server, addr, addrsize, 0), flags);
|
||||
} else if (SupportsLinux() && !once) {
|
||||
once = true;
|
||||
if (client == __NR_accept4_linux) {
|
||||
demodernize = true;
|
||||
goto TriedAndTrue;
|
||||
}
|
||||
client = __fixupnewsockfd(__sys_accept(server, out_addr, out_addrsize, 0),
|
||||
flags);
|
||||
}
|
||||
if (client != -1 && IsBsd()) {
|
||||
sockaddr2linux(addr);
|
||||
sockaddr2linux(&bsd, size, addr, addrsize);
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
|
31
libc/sock/bind-sysv.c
Normal file
31
libc/sock/bind-sysv.c
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*-*- 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 2020 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/dce.h"
|
||||
#include "libc/sock/internal.h"
|
||||
|
||||
int sys_bind(int fd, const void *addr, uint32_t addrsize) {
|
||||
union sockaddr_storage_bsd bsd;
|
||||
if (!IsBsd()) {
|
||||
return __sys_bind(fd, addr, addrsize);
|
||||
} else if (!sockaddr2bsd(addr, addrsize, &bsd, &addrsize)) {
|
||||
return __sys_bind(fd, &bsd.sa, addrsize);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -16,7 +16,6 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
@ -25,7 +24,6 @@
|
|||
#include "libc/sock/sock.h"
|
||||
#include "libc/sock/sockdebug.h"
|
||||
#include "libc/sock/syscall_fd.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
|
@ -40,21 +38,11 @@
|
|||
*/
|
||||
int bind(int fd, const void *addr, uint32_t addrsize) {
|
||||
int rc;
|
||||
char addrbuf[72];
|
||||
if (!addr || (IsAsan() && !__asan_is_valid(addr, addrsize))) {
|
||||
rc = efault();
|
||||
} else if (addrsize >= sizeof(struct sockaddr_in)) {
|
||||
if (!IsWindows()) {
|
||||
if (!IsBsd()) {
|
||||
rc = sys_bind(fd, addr, addrsize);
|
||||
} else {
|
||||
char addr2[sizeof(
|
||||
struct sockaddr_un_bsd)]; /* sockaddr_un_bsd is the largest */
|
||||
assert(addrsize <= sizeof(addr2));
|
||||
memcpy(&addr2, addr, addrsize);
|
||||
sockaddr2bsd(&addr2[0]);
|
||||
rc = sys_bind(fd, &addr2, addrsize);
|
||||
}
|
||||
rc = sys_bind(fd, addr, addrsize);
|
||||
} else if (__isfdkind(fd, kFdSocket)) {
|
||||
rc = sys_bind_nt(&g_fds.p[fd], addr, addrsize);
|
||||
} else {
|
||||
|
|
|
@ -16,20 +16,16 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int sys_connect(int fd, const void *addr, uint32_t addrsize) {
|
||||
union sockaddr_storage_bsd bsd;
|
||||
if (!IsBsd()) {
|
||||
return __sys_connect(fd, addr, addrsize);
|
||||
} else if (!sockaddr2bsd(addr, addrsize, &bsd, &addrsize)) {
|
||||
return __sys_connect(fd, &bsd.sa, addrsize);
|
||||
} else {
|
||||
char addr2[sizeof(struct sockaddr_un_bsd)]; /* sockaddr_un_bsd is the largest */
|
||||
assert(addrsize <= sizeof(addr2));
|
||||
memcpy(&addr2, addr, addrsize);
|
||||
sockaddr2bsd(&addr2[0]);
|
||||
return __sys_connect(fd, &addr2, addrsize);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,9 +20,16 @@
|
|||
#include "libc/sock/internal.h"
|
||||
|
||||
int sys_getpeername(int fd, void *out_addr, uint32_t *out_addrsize) {
|
||||
int rc = __sys_getpeername(fd, out_addr, out_addrsize);
|
||||
if (rc != -1 && IsBsd()) {
|
||||
sockaddr2linux(out_addr);
|
||||
int rc;
|
||||
uint32_t size;
|
||||
union sockaddr_storage_bsd bsd;
|
||||
if (!IsBsd()) {
|
||||
rc = __sys_getpeername(fd, out_addr, out_addrsize);
|
||||
} else {
|
||||
size = sizeof(bsd);
|
||||
if ((rc = __sys_getpeername(fd, &bsd, &size)) != -1) {
|
||||
sockaddr2linux(&bsd, size, out_addr, out_addrsize);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -20,9 +20,16 @@
|
|||
#include "libc/sock/internal.h"
|
||||
|
||||
int sys_getsockname(int fd, void *out_addr, uint32_t *out_addrsize) {
|
||||
int rc = __sys_getsockname(fd, out_addr, out_addrsize);
|
||||
if (rc != -1 && IsBsd()) {
|
||||
sockaddr2linux(out_addr);
|
||||
int rc;
|
||||
uint32_t size;
|
||||
union sockaddr_storage_bsd bsd;
|
||||
if (!IsBsd()) {
|
||||
rc = __sys_getsockname(fd, out_addr, out_addrsize);
|
||||
} else {
|
||||
size = sizeof(bsd);
|
||||
if ((rc = __sys_getsockname(fd, &bsd, &size)) != -1) {
|
||||
sockaddr2linux(&bsd, size, out_addr, out_addrsize);
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,18 @@ struct sockaddr_un_bsd {
|
|||
char sun_path[108];
|
||||
};
|
||||
|
||||
union sockaddr_storage_bsd {
|
||||
struct sockaddr_bsd sa;
|
||||
struct sockaddr_in_bsd sin;
|
||||
struct sockaddr_un_bsd sun;
|
||||
};
|
||||
|
||||
union sockaddr_storage_linux {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in sin;
|
||||
struct sockaddr_un sun;
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------*/
|
||||
|
||||
#define SOCKFD_OVERLAP_BUFSIZ 128
|
||||
|
@ -79,10 +91,11 @@ void _firewall(const void *, uint32_t) hidden;
|
|||
|
||||
int32_t __sys_accept(int32_t, void *, uint32_t *, int) dontdiscard hidden;
|
||||
int32_t __sys_accept4(int32_t, void *, uint32_t *, int) dontdiscard hidden;
|
||||
int32_t __sys_bind(int32_t, const void *, uint32_t) hidden;
|
||||
int32_t __sys_connect(int32_t, const void *, uint32_t) hidden;
|
||||
int32_t __sys_socket(int32_t, int32_t, int32_t) hidden;
|
||||
int32_t __sys_getsockname(int32_t, void *, uint32_t *) hidden;
|
||||
int32_t __sys_getpeername(int32_t, void *, uint32_t *) hidden;
|
||||
int32_t __sys_getsockname(int32_t, void *, uint32_t *) hidden;
|
||||
int32_t __sys_socket(int32_t, int32_t, int32_t) hidden;
|
||||
int32_t __sys_socketpair(int32_t, int32_t, int32_t, int32_t[2]) hidden;
|
||||
|
||||
int32_t sys_accept4(int32_t, void *, uint32_t *, int) dontdiscard hidden;
|
||||
|
@ -137,29 +150,10 @@ struct SockFd *_dupsockfd(struct SockFd *) hidden;
|
|||
int64_t GetNtBaseSocket(int64_t) hidden;
|
||||
int sys_close_epoll(int) hidden;
|
||||
|
||||
/**
|
||||
* Converts sockaddr (Linux/Windows) → sockaddr_bsd (XNU/BSD).
|
||||
*/
|
||||
forceinline void sockaddr2bsd(void *saddr) {
|
||||
char *p;
|
||||
if (saddr) {
|
||||
p = saddr;
|
||||
p[1] = p[0];
|
||||
p[0] = sizeof(struct sockaddr_in_bsd);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts sockaddr_in_bsd (XNU/BSD) → sockaddr (Linux/Windows).
|
||||
*/
|
||||
forceinline void sockaddr2linux(void *saddr) {
|
||||
char *p;
|
||||
if (saddr) {
|
||||
p = saddr;
|
||||
p[0] = p[1];
|
||||
p[1] = 0;
|
||||
}
|
||||
}
|
||||
int sockaddr2bsd(const void *, uint32_t, union sockaddr_storage_bsd *,
|
||||
uint32_t *);
|
||||
void sockaddr2linux(const union sockaddr_storage_bsd *, uint32_t,
|
||||
union sockaddr_storage_linux *, uint32_t *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -45,19 +45,26 @@
|
|||
*/
|
||||
ssize_t recvfrom(int fd, void *buf, size_t size, uint32_t flags,
|
||||
void *opt_out_srcaddr, uint32_t *opt_inout_srcaddrsize) {
|
||||
ssize_t rc, got;
|
||||
ssize_t rc;
|
||||
uint32_t sz;
|
||||
union sockaddr_storage_bsd bsd;
|
||||
if (IsAsan() &&
|
||||
(!__asan_is_valid(buf, size) ||
|
||||
(opt_out_srcaddr &&
|
||||
!__asan_is_valid(opt_out_srcaddr, *opt_inout_srcaddrsize)))) {
|
||||
(!__asan_is_valid(opt_inout_srcaddrsize,
|
||||
sizeof(*opt_inout_srcaddrsize)) ||
|
||||
!__asan_is_valid(opt_out_srcaddr, *opt_inout_srcaddrsize))))) {
|
||||
rc = efault();
|
||||
} else if (!IsWindows()) {
|
||||
got = sys_recvfrom(fd, buf, size, flags, opt_out_srcaddr,
|
||||
opt_inout_srcaddrsize);
|
||||
if (opt_out_srcaddr && IsBsd() && got != -1) {
|
||||
sockaddr2linux(opt_out_srcaddr);
|
||||
if (!IsBsd() || !opt_out_srcaddr) {
|
||||
rc = sys_recvfrom(fd, buf, size, flags, opt_out_srcaddr,
|
||||
opt_inout_srcaddrsize);
|
||||
} else {
|
||||
sz = sizeof(bsd);
|
||||
if ((rc = sys_recvfrom(fd, buf, size, flags, &bsd, &sz)) != -1) {
|
||||
sockaddr2linux(&bsd, sz, opt_out_srcaddr, opt_inout_srcaddrsize);
|
||||
}
|
||||
}
|
||||
rc = got;
|
||||
} else if (__isfdopen(fd)) {
|
||||
if (__isfdkind(fd, kFdSocket)) {
|
||||
rc = sys_recvfrom_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1,
|
||||
|
|
|
@ -41,15 +41,24 @@
|
|||
*/
|
||||
ssize_t recvmsg(int fd, struct msghdr *msg, int flags) {
|
||||
ssize_t rc, got;
|
||||
struct msghdr msg2;
|
||||
union sockaddr_storage_bsd bsd;
|
||||
if (IsAsan() && !__asan_is_valid_msghdr(msg)) {
|
||||
rc = efault();
|
||||
} else if (!IsWindows()) {
|
||||
got = sys_recvmsg(fd, msg, flags);
|
||||
// An address was provided, convert from BSD form
|
||||
if (msg->msg_name && IsBsd() && got != -1) {
|
||||
sockaddr2linux(msg->msg_name);
|
||||
if (IsBsd() && msg->msg_name) {
|
||||
memcpy(&msg2, msg, sizeof(msg2));
|
||||
if (!(rc = sockaddr2bsd(msg->msg_name, msg->msg_namelen, &bsd,
|
||||
&msg2.msg_namelen))) {
|
||||
msg2.msg_name = &bsd.sa;
|
||||
if ((rc = sys_recvmsg(fd, &msg2, flags)) != -1) {
|
||||
sockaddr2linux(msg2.msg_name, msg2.msg_namelen, msg->msg_name,
|
||||
&msg->msg_namelen);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rc = sys_recvmsg(fd, msg, flags);
|
||||
}
|
||||
rc = got;
|
||||
} else if (__isfdopen(fd)) {
|
||||
if (!msg->msg_control) {
|
||||
if (__isfdkind(fd, kFdSocket)) {
|
||||
|
|
|
@ -44,27 +44,22 @@
|
|||
*/
|
||||
ssize_t sendmsg(int fd, const struct msghdr *msg, int flags) {
|
||||
int64_t rc;
|
||||
char addr2[128];
|
||||
struct msghdr msg2;
|
||||
union sockaddr_storage_bsd bsd;
|
||||
|
||||
if (IsAsan() && !__asan_is_valid_msghdr(msg)) {
|
||||
rc = efault();
|
||||
} else if (!IsWindows()) {
|
||||
if (IsBsd() && msg->msg_name) {
|
||||
/* An optional address is provided, convert it to the BSD form */
|
||||
if (msg->msg_namelen <= sizeof(addr2)) {
|
||||
memcpy(&addr2[0], msg->msg_name, msg->msg_namelen);
|
||||
sockaddr2bsd(&addr2[0]);
|
||||
/* Copy all of msg (except for msg_name) into the new ephemeral local */
|
||||
memcpy(&msg2, msg, sizeof(msg2));
|
||||
msg2.msg_name = &addr2[0];
|
||||
memcpy(&msg2, msg, sizeof(msg2));
|
||||
if (!(rc = sockaddr2bsd(msg->msg_name, msg->msg_namelen, &bsd,
|
||||
&msg2.msg_namelen))) {
|
||||
msg2.msg_name = &bsd.sa;
|
||||
rc = sys_sendmsg(fd, &msg2, flags);
|
||||
} else {
|
||||
rc = einval();
|
||||
}
|
||||
} else {
|
||||
rc = sys_sendmsg(fd, msg, flags);
|
||||
}
|
||||
/* else do the syscall */
|
||||
rc = sys_sendmsg(fd, msg, flags);
|
||||
} else if (__isfdopen(fd)) {
|
||||
if (msg->msg_control) {
|
||||
rc = einval(); /* control msg not supported */
|
||||
|
|
|
@ -52,7 +52,8 @@
|
|||
ssize_t sendto(int fd, const void *buf, size_t size, uint32_t flags,
|
||||
const void *opt_addr, uint32_t addrsize) {
|
||||
ssize_t rc;
|
||||
char addr2[sizeof(struct sockaddr_un_bsd)];
|
||||
uint32_t bsdaddrsize;
|
||||
union sockaddr_storage_bsd bsd;
|
||||
if (IsAsan() && (!__asan_is_valid(buf, size) ||
|
||||
(opt_addr && !__asan_is_valid(opt_addr, addrsize)))) {
|
||||
rc = efault();
|
||||
|
@ -61,12 +62,8 @@ ssize_t sendto(int fd, const void *buf, size_t size, uint32_t flags,
|
|||
if (!IsWindows()) {
|
||||
if (!IsBsd() || !opt_addr) {
|
||||
rc = sys_sendto(fd, buf, size, flags, opt_addr, addrsize);
|
||||
} else if (addrsize > sizeof(addr2)) {
|
||||
rc = einval();
|
||||
} else {
|
||||
memcpy(&addr2, opt_addr, addrsize);
|
||||
sockaddr2bsd(&addr2[0]);
|
||||
rc = sys_sendto(fd, buf, size, flags, &addr2[0], addrsize);
|
||||
} else if (!(rc = sockaddr2bsd(opt_addr, addrsize, &bsd, &bsdaddrsize))) {
|
||||
rc = sys_sendto(fd, buf, size, flags, &bsd, bsdaddrsize);
|
||||
}
|
||||
} else if (__isfdopen(fd)) {
|
||||
if (__isfdkind(fd, kFdSocket)) {
|
||||
|
|
66
libc/sock/sockaddr2bsd.c
Normal file
66
libc/sock/sockaddr2bsd.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*-*- 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/sock/internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Converts sockaddr (Linux/Windows) → sockaddr_bsd (XNU/BSD).
|
||||
*/
|
||||
int sockaddr2bsd(const void *addr, uint32_t addrsize,
|
||||
union sockaddr_storage_bsd *out_addr, uint32_t *out_addrsize) {
|
||||
uint32_t len, famsize;
|
||||
if (addrsize >= sizeof(((struct sockaddr *)addr)->sa_family)) {
|
||||
if (((struct sockaddr *)addr)->sa_family == AF_INET) {
|
||||
if (addrsize >= sizeof(struct sockaddr_in)) {
|
||||
out_addr->sin.sin_len = 0;
|
||||
out_addr->sin.sin_family = AF_INET;
|
||||
out_addr->sin.sin_port = ((struct sockaddr_in *)addr)->sin_port;
|
||||
out_addr->sin.sin_addr = ((struct sockaddr_in *)addr)->sin_addr;
|
||||
bzero(&out_addr->sin.sin_zero, sizeof(out_addr->sin.sin_zero));
|
||||
*out_addrsize = sizeof(struct sockaddr_in_bsd);
|
||||
return 0;
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
} else if (((struct sockaddr *)addr)->sa_family == AF_UNIX) {
|
||||
famsize = sizeof(((struct sockaddr_un *)addr)->sun_family);
|
||||
if (addrsize >= famsize &&
|
||||
(len = strnlen(((struct sockaddr_un *)addr)->sun_path,
|
||||
addrsize - famsize)) <
|
||||
sizeof(out_addr->sun.sun_path)) {
|
||||
out_addr->sun.sun_len = 0;
|
||||
out_addr->sun.sun_family = AF_UNIX;
|
||||
memcpy(out_addr->sun.sun_path, ((struct sockaddr_un *)addr)->sun_path,
|
||||
len);
|
||||
out_addr->sun.sun_path[len] = 0;
|
||||
*out_addrsize = sizeof(out_addr->sun.sun_len) +
|
||||
sizeof(out_addr->sun.sun_family) + len;
|
||||
return 0;
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
} else {
|
||||
return epfnosupport();
|
||||
}
|
||||
} else {
|
||||
return einval();
|
||||
}
|
||||
}
|
60
libc/sock/sockaddr2linux.c
Normal file
60
libc/sock/sockaddr2linux.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*-*- 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/intrin/kprintf.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Converts sockaddr_bsd (XNU/BSD) → sockaddr (Linux/Windows).
|
||||
*/
|
||||
void sockaddr2linux(const union sockaddr_storage_bsd *addr, uint32_t addrsize,
|
||||
union sockaddr_storage_linux *out_addr,
|
||||
uint32_t *inout_addrsize) {
|
||||
uint32_t len, size;
|
||||
if (out_addr && inout_addrsize) {
|
||||
size = *inout_addrsize;
|
||||
bzero(out_addr, size);
|
||||
if (addrsize >= sizeof(addr->sa.sa_family)) {
|
||||
if (addr->sa.sa_family == AF_INET) {
|
||||
if (addrsize >= sizeof(struct sockaddr_in_bsd) &&
|
||||
size >= sizeof(struct sockaddr_in)) {
|
||||
out_addr->sin.sin_family = AF_INET;
|
||||
out_addr->sin.sin_port = addr->sin.sin_port;
|
||||
out_addr->sin.sin_addr = addr->sin.sin_addr;
|
||||
*inout_addrsize = sizeof(struct sockaddr_in);
|
||||
}
|
||||
} else if (addr->sa.sa_family == AF_UNIX) {
|
||||
if (addrsize >=
|
||||
sizeof(addr->sun.sun_len) + sizeof(addr->sun.sun_family) &&
|
||||
size >= sizeof(out_addr->sun.sun_family)) {
|
||||
len = strnlen(((struct sockaddr_un *)addr)->sun_path,
|
||||
MIN(addrsize - (sizeof(addr->sun.sun_len) +
|
||||
sizeof(addr->sun.sun_family)),
|
||||
size - sizeof(out_addr->sun.sun_family)));
|
||||
out_addr->sun.sun_family = AF_UNIX;
|
||||
if (len) memcpy(out_addr->sun.sun_path, addr->sun.sun_path, len);
|
||||
*inout_addrsize = sizeof(out_addr->sun.sun_family) + len + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2
libc/sysv/calls/__sys_bind.s
Normal file
2
libc/sysv/calls/__sys_bind.s
Normal file
|
@ -0,0 +1,2 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall __sys_bind,0x0680680682068031,globl,hidden
|
|
@ -1,2 +0,0 @@
|
|||
.include "o/libc/sysv/macros.internal.inc"
|
||||
.scall sys_bind,0x0680680682068031,globl,hidden
|
|
@ -84,7 +84,7 @@ scall sys_recvfrom 0x01d01d01d201d02d globl hidden
|
|||
scall sys_sendmsg 0x01c01c01c201c02e globl hidden
|
||||
scall sys_recvmsg 0x01b01b01b201b02f globl hidden
|
||||
scall sys_shutdown 0x0860860862086030 globl hidden
|
||||
scall sys_bind 0x0680680682068031 globl hidden
|
||||
scall __sys_bind 0x0680680682068031 globl hidden
|
||||
scall sys_listen 0x06a06a06a206a032 globl hidden
|
||||
scall __sys_getsockname 0x0200200202020033 globl hidden
|
||||
scall __sys_getpeername 0x01f01f08d201f034 globl hidden
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue