lib: Support fd passing using the 4.3BSD way
authorVolker Lendecke <vl@samba.org>
Sat, 26 Sep 2015 22:54:42 +0000 (00:54 +0200)
committerMichael Adam <obnox@samba.org>
Thu, 1 Oct 2015 00:55:21 +0000 (02:55 +0200)
This is required on Solaris

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11053

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Michael Adam <obnox@samba.org>
source3/lib/msghdr.c

index d89b7c13db338c539570260784db5717c7a98f37..2aa2f2e05164a7b98d19e44502db245ab41a2420 100644 (file)
@@ -21,6 +21,8 @@
 #include "lib/util/iov_buf.h"
 #include <sys/socket.h>
 
+#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL)
+
 ssize_t msghdr_prep_fds(struct msghdr *msg, uint8_t *buf, size_t bufsize,
                        const int *fds, size_t num_fds)
 {
@@ -106,6 +108,84 @@ size_t msghdr_extract_fds(struct msghdr *msg, int *fds, size_t fds_size)
        return num_fds;
 }
 
+#elif defined(HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTS)
+
+ssize_t msghdr_prep_fds(struct msghdr *msg, uint8_t *buf, size_t bufsize,
+                       const int *fds, size_t num_fds)
+{
+       size_t needed;
+
+       if (num_fds > INT8_MAX) {
+               return -1;
+       }
+
+       needed = sizeof(int) * num_fds;
+
+       if ((msg == NULL) || (needed > bufsize)) {
+               return needed;
+       }
+
+       memcpy(buf, fds, needed);
+
+       msg->msg_accrights = (caddr_t) buf;
+       msg->msg_accrightslen = needed;
+
+       return needed;
+}
+
+size_t msghdr_prep_recv_fds(struct msghdr *msg, uint8_t *buf, size_t bufsize,
+                           size_t num_fds)
+{
+       size_t ret = num_fds * sizeof(int);
+
+       if (bufsize < ret) {
+               return ret;
+       }
+
+       if (msg != NULL) {
+               if (num_fds != 0) {
+                       msg->msg_accrights = (caddr_t) buf;
+                       msg->msg_accrightslen = ret;
+               } else {
+                       msg->msg_accrights = NULL;
+                       msg->msg_accrightslen = 0;
+               }
+       }
+       return ret;
+}
+
+size_t msghdr_extract_fds(struct msghdr *msg, int *fds, size_t fds_size)
+{
+       size_t num_fds = msg->msg_accrightslen / sizeof(int);
+
+       if ((fds != 0) && (num_fds <= fds_size)) {
+               memcpy(fds, msg->msg_accrights, msg->msg_accrightslen);
+       }
+
+       return num_fds;
+}
+
+#else
+
+ssize_t msghdr_prep_fds(struct msghdr *msg, uint8_t *buf, size_t bufsize,
+                       const int *fds, size_t num_fds)
+{
+       return -1;
+}
+
+size_t msghdr_prep_recv_fds(struct msghdr *msg, uint8_t *buf, size_t bufsize,
+                           size_t num_fds)
+{
+       return 0;
+}
+
+size_t msghdr_extract_fds(struct msghdr *msg, int *fds, size_t fds_size)
+{
+       return 0;
+}
+
+#endif
+
 struct msghdr_buf {
        struct msghdr msg;
        struct sockaddr_storage addr;