From 7fd8e31f7da36dbb89d981edfc449a968957d67a Mon Sep 17 00:00:00 2001 From: leitner Date: Thu, 22 Apr 2021 11:02:44 +0000 Subject: [PATCH] OSX does not have accept4 :( --- GNUmakefile | 9 ++++++++- socket.h | 6 +++++- socket/socket_accept4_flags.c | 15 ++++++++++++--- socket/socket_accept6_flags.c | 11 ++++++++++- tryaccept4.c | 10 ++++++++++ 5 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 tryaccept4.c diff --git a/GNUmakefile b/GNUmakefile index 8f34adc..5cd7fd5 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -204,7 +204,7 @@ clean: rm -f *.o *.obj *.a *.lib *.da *.bbg *.bb core t haveip6.h haven2i.h \ havesl.h haveinline.h iopause.h select.h havekqueue.h haveepoll.h \ libepoll havesigio.h havebsdsf.h havesendfile.h havescope.h havedevpoll.h \ -dep libsocket havealloca.h haveuint128.h entities.h ent havepread.h \ +dep libsocket havealloca.h haveuint128.h entities.h ent havepread.h haveaccept4.h \ *.gcda *.gcno INCLUDES=buffer.h byte.h fmt.h ip4.h ip6.h mmap.h scan.h socket.h str.h stralloc.h \ @@ -337,6 +337,11 @@ select.h: select.h1 select.h2 trysysel.c if $(DIET) $(CCC) $(CFLAGS) -c trysysel.c >/dev/null 2>&1; then cp select.h2 select.h; else cp select.h1 select.h; fi -rm -f trysysel.o +haveaccept4.h: tryaccept4.c + -rm -f $@ + if $(DIET) $(CCC) $(CFLAGS) -c tryaccept4.c >/dev/null 2>&1; then echo "#define HAVE_ACCEPT4"; fi > $@ + -rm -f tryaccept4.o + libsocket: trysocket.c if $(DIET) $(CCC) $(CFLAGS) -o trysocket trysocket.c >/dev/null 2>&1; then echo ""; else \ if $(DIET) $(CCC) $(CFLAGS) -o trysocket trysocket.c -lsocket >/dev/null 2>&1; then echo "-lsocket"; else \ @@ -352,6 +357,8 @@ socket_mchopcount6.o socket_mcjoin6.o socket_mcleave6.o socket_mcloop6.o \ socket_recv6.o socket_remote6.o socket_sctp6b.o socket_send6.o \ socket_tcp6b.o socket_tcp6.o socket_udp6.o socket_accept6_flags.o: haveip6.h +socket_accept4_flags.o socket_accept6_flags.o: haveaccept4.h + socket_accept6.o socket_connect6.o socket_local6.o socket_recv6.o \ socket_remote6.o socket_send6.o socket_accept6_flags.o: havescope.h diff --git a/socket.h b/socket.h index f41766f..e2682b8 100644 --- a/socket.h +++ b/socket.h @@ -47,7 +47,11 @@ int socket_accept4_makenonblocking_setcloseonexec(int s,char* ip,uint16* port); int socket_accept6_makenonblocking_setcloseonexec(int s,char* ip,uint16* port,uint32* scope_id); /* These are internal wrappers around accept4, not meant for external use. - * flags can be SOCK_NONBLOCK or SOCK_CLOEXEC or both (defined in sys/socket.h) */ + * flags can be SOCKET_NONBLOCK or SOCKET_CLOEXEC or both */ +enum { + SOCKET_NONBLOCK=1, + SOCKET_CLOEXEC=2, +}; int socket_accept4_flags(int s,char* ip,uint16* port, int flags); int socket_accept6_flags(int s,char* ip,uint16* port,uint32* scope_id, int flags); diff --git a/socket/socket_accept4_flags.c b/socket/socket_accept4_flags.c index 26023a7..8ffc864 100644 --- a/socket/socket_accept4_flags.c +++ b/socket/socket_accept4_flags.c @@ -20,6 +20,8 @@ #include "io_internal.h" #endif +#include "haveaccept4.h" + int socket_accept4_flags(int s, char *ip, uint16 *port, int flags) { struct sockaddr_in si; socklen_t len = sizeof si; @@ -75,11 +77,15 @@ incoming: } else { #endif +#ifdef HAVE_ACCEPT4 static int noaccept4; // auto initialized to 0 if (noaccept4) fd=-1; else { - if ((fd=accept4(s,(void*) &si, &len, flags))==-1) { + int flg=0; + if (flags & SOCKET_NONBLOCK) flg += SOCK_NONBLOCK; + if (flags & SOCKET_CLOEXEC) flg += SOCK_CLOEXEC; + if ((fd=accept4(s,(void*) &si, &len, flg))==-1) { if (errno != ENOSYS) return -1; // if we get here, fd==-1 && errno==ENOSYS @@ -87,12 +93,13 @@ incoming: } } if (fd==-1) { +#endif int fl = 0; /* if we get here, the kernel did not support accept4. */ if ((fd=accept(s,(void*) &si,&len))==-1) return -1; - if (flags & SOCK_NONBLOCK) fl |= O_NDELAY; - if (flags & SOCK_CLOEXEC) fl |= O_CLOEXEC; + if (flags & SOCKET_NONBLOCK) fl |= O_NDELAY; + if (flags & SOCKET_CLOEXEC) fl |= O_CLOEXEC; /* On BSD the accepted socket inherits O_NDELAY and O_CLOEXEC, on * Linux it doesn't. accept4 makes this explicit. So for the * fallback, make it explicit as well */ @@ -107,7 +114,9 @@ incoming: #ifdef __linux__ } #endif +#ifdef HAVE_ACCEPT4 } +#endif #ifdef __MINGW32__ } diff --git a/socket/socket_accept6_flags.c b/socket/socket_accept6_flags.c index d0ab239..7a784ae 100644 --- a/socket/socket_accept6_flags.c +++ b/socket/socket_accept6_flags.c @@ -25,6 +25,8 @@ #include "io_internal.h" #endif +#include "haveaccept4.h" + int socket_accept6_flags(int s, char* ip, uint16* port, uint32* scope_id, int flags) { #ifdef LIBC_HAS_IP6 @@ -86,17 +88,22 @@ incoming: } else { #endif +#ifdef HAVE_ACCEPT4 static int noaccept4; // auto initialized to 0 if (noaccept4) fd=-1; else { - if ((fd=accept4(s,(void*) &sa, &dummy, flags))==-1) { + int flg=0; + if (flags & SOCKET_NONBLOCK) flg += SOCK_NONBLOCK; + if (flags & SOCKET_CLOEXEC) flg += SOCK_CLOEXEC; + if ((fd=accept4(s,(void*) &sa, &dummy, flg))==-1) { if (errno != ENOSYS) return -1; noaccept4=1; } } if (fd==-1) { +#endif int fl = 0; fd = accept(s, (struct sockaddr *) &sa, &dummy); if (fd == -1) @@ -117,7 +124,9 @@ incoming: #ifdef __linux__ } #endif +#ifdef HAVE_ACCEPT4 } +#endif #ifdef __MINGW32__ } #endif diff --git a/tryaccept4.c b/tryaccept4.c new file mode 100644 index 0000000..1b77b90 --- /dev/null +++ b/tryaccept4.c @@ -0,0 +1,10 @@ +#define _GNU_SOURCE +#include +#include +#include +#include + +int main() { + accept4(0, NULL, NULL, 0); // we just want to know if the symbol exists + return 0; +}