about summary refs log tree commit diff
path: root/src/libunixonacid/ipc_timed_sendv.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2018-06-24 15:05:12 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2018-06-24 15:05:12 +0000
commite235eac7e00a3f52299273f734723dbc9fbaee70 (patch)
tree7a31f7567d6ab7c7c056a29c677509b0988faea9 /src/libunixonacid/ipc_timed_sendv.c
parent191d21f2acde7c2fa3003972a8b04bc080d64e2d (diff)
downloadskalibs-e235eac7e00a3f52299273f734723dbc9fbaee70.tar.gz
skalibs-e235eac7e00a3f52299273f734723dbc9fbaee70.tar.xz
skalibs-e235eac7e00a3f52299273f734723dbc9fbaee70.zip
Add skagetln_loose, skagetlnsep_loose, ipc_timed_sendv
Diffstat (limited to 'src/libunixonacid/ipc_timed_sendv.c')
-rw-r--r--src/libunixonacid/ipc_timed_sendv.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/libunixonacid/ipc_timed_sendv.c b/src/libunixonacid/ipc_timed_sendv.c
new file mode 100644
index 0000000..220b2e3
--- /dev/null
+++ b/src/libunixonacid/ipc_timed_sendv.c
@@ -0,0 +1,43 @@
+/* ISC license. */
+
+#include <skalibs/nonposix.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <skalibs/error.h>
+#include <skalibs/iopause.h>
+#include <skalibs/siovec.h>
+#include <skalibs/unix-timed.h>
+
+ /* For MacOS, that still doesn't know what POSIX says */
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
+int ipc_timed_sendv (int fd, struct iovec const *v, unsigned int n, tain_t const *deadline, tain_t *stamp)
+{
+  struct msghdr hdr =
+  {
+    .msg_name = 0,
+    .msg_namelen = 0,
+    .msg_iov = (struct iovec *)v,
+    .msg_iovlen = n,
+    .msg_control = 0,
+    .msg_controllen = 0,
+    .msg_flags = 0
+  } ;
+  size_t len = siovec_len(v, n) ;
+  iopause_fd x = { .fd = fd, .events = IOPAUSE_WRITE, .revents = 0 } ;
+  for (;;)
+  {
+    int r = iopause_stamp(&x, 1, deadline, stamp) ;
+    if (r < 0) return 0 ;
+    else if (!r) return (errno = ETIMEDOUT, 0) ;
+    else if (x.revents & IOPAUSE_WRITE)
+    {
+      if (sendmsg(fd, &hdr, MSG_NOSIGNAL) == (ssize_t)len) break ;
+      if (!error_isagain(errno)) return 0 ;
+    }
+    else if (x.revents & IOPAUSE_EXCEPT) return (sendmsg(fd, &hdr, MSG_NOSIGNAL) == (ssize_t)len) ;
+  }
+  return 1 ;
+}