summaryrefslogtreecommitdiff
path: root/ot_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'ot_socket.c')
-rw-r--r--ot_socket.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/ot_socket.c b/ot_socket.c
index 158459f..47ed26d 100644
--- a/ot_socket.c
+++ b/ot_socket.c
@@ -4,6 +4,7 @@
4 $id$ */ 4 $id$ */
5 5
6/* System */ 6/* System */
7#define _GNU_SOURCE /* accept4 on glibc */
7#include <errno.h> 8#include <errno.h>
8#include <fcntl.h> 9#include <fcntl.h>
9#include <netinet/in.h> 10#include <netinet/in.h>
@@ -170,19 +171,25 @@ int socket_is_connected(int s) {
170 return 1; 171 return 1;
171} 172}
172 173
174/* Linux hands over a blocking socket whatever the listening socket was, the
175 BSDs and macOS inherit the listener's flags, so the accepted socket has to
176 be told either way. accept4 carries the flag itself, which saves the two
177 fcntl calls it otherwise takes. Darwin has neither accept4 nor the flag. */
173int socket_accept(int s, ot_ip6 ip, uint16_t *port) { 178int socket_accept(int s, ot_ip6 ip, uint16_t *port) {
174 struct sockaddr_storage ss; 179 struct sockaddr_storage ss;
175 socklen_t len = sizeof(ss); 180 socklen_t len = sizeof(ss);
176 int fd; 181 int fd;
177 182
178 memset(&ss, 0, sizeof(ss)); 183 memset(&ss, 0, sizeof(ss));
184#ifdef SOCK_NONBLOCK
185 if ((fd = accept4(s, (struct sockaddr *)&ss, &len, SOCK_NONBLOCK)) == -1)
186 return -1;
187#else
179 if ((fd = accept(s, (struct sockaddr *)&ss, &len)) == -1) 188 if ((fd = accept(s, (struct sockaddr *)&ss, &len)) == -1)
180 return -1; 189 return -1;
181
182 /* Linux hands over a blocking socket whatever the listening socket was, the
183 BSDs and macOS inherit the listener's flags, so say which one we want. */
184 if (set_nonblocking(fd) == -1) 190 if (set_nonblocking(fd) == -1)
185 return close_and_fail(fd); 191 return close_and_fail(fd);
192#endif
186 193
187 ip_from_sockaddr(ip, port, &ss); 194 ip_from_sockaddr(ip, port, &ss);
188 return fd; 195 return fd;