summaryrefslogtreecommitdiff
path: root/src/libwpactrl/wpactrl_fd_recv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libwpactrl/wpactrl_fd_recv.c')
-rw-r--r--src/libwpactrl/wpactrl_fd_recv.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/libwpactrl/wpactrl_fd_recv.c b/src/libwpactrl/wpactrl_fd_recv.c
new file mode 100644
index 0000000..3e2a006
--- /dev/null
+++ b/src/libwpactrl/wpactrl_fd_recv.c
@@ -0,0 +1,47 @@
+/* ISC license. */
+
+#include <skalibs/sysdeps.h>
+#include <skalibs/nonposix.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <bcnm/wpactrl.h>
+#include "wpactrl-internal.h"
+
+ssize_t wpactrl_fd_recv (int fd, char *s, size_t len)
+{
+ static int const bsd_braindeadness_workaround_flags =
+#ifdef SKALIBS_HASMSGDONTWAIT
+ MSG_DONTWAIT
+#else
+ 0
+#endif
+ |
+#ifdef SKALIBS_HASNBWAITALL
+ MSG_WAITALL
+#else
+ 0
+#endif
+ |
+#ifdef SKALIBS_HASCMSGCLOEXEC
+ MSG_CMSG_CLOEXEC
+#else
+ 0
+#endif
+ ;
+ struct iovec iov = { .iov_base = s, .iov_len = len } ;
+ struct msghdr msghdr =
+ {
+ .msg_name = 0,
+ .msg_namelen = 0,
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_flags = 0,
+ .msg_control = 0,
+ .msg_controllen = 0
+ } ;
+ ssize_t r ;
+ do r = recvmsg(fd, &msghdr, bsd_braindeadness_workaround_flags) ;
+ while (r == -1 && errno == EINTR) ;
+ return r > 0 && msghdr.msg_flags | MSG_TRUNC ? (errno = EMSGSIZE, -1) : r ;
+}