s3:unix_msg: add fds-array to unix_msg_send() for fd passing
authorMichael Adam <obnox@samba.org>
Sat, 17 May 2014 22:22:55 +0000 (00:22 +0200)
committerMichael Adam <obnox@samba.org>
Wed, 24 Sep 2014 06:44:11 +0000 (08:44 +0200)
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Michael Adam <obnox@samba.org>
source3/lib/messages_dgm.c
source3/lib/unix_msg/test_source.c
source3/lib/unix_msg/tests.c
source3/lib/unix_msg/unix_msg.c
source3/lib/unix_msg/unix_msg.h

index cadcb4be724fcecb2135e42a8fc65e8851dab0a6..7ba79fcfd0abd3026d5d7d0a7954ff4995235030 100644 (file)
@@ -318,7 +318,7 @@ int messaging_dgm_send(pid_t pid, const struct iovec *iov, int iovlen)
 
        DEBUG(10, ("%s: Sending message to %u\n", __func__, (unsigned)pid));
 
-       ret = unix_msg_send(ctx->dgm_ctx, &dst, iov, iovlen);
+       ret = unix_msg_send(ctx->dgm_ctx, &dst, iov, iovlen, NULL, 0);
 
        return ret;
 }
index 7f6a7a5e8c07cb56c395803201d0887922b26d71..5224ebff6f6f247d6cb3f35a7412b2501c7f436f 100644 (file)
@@ -65,7 +65,7 @@ int main(int argc, const char *argv[])
                unsigned j;
 
                for (j=0; j<100000; j++) {
-                       ret = unix_msg_send(ctxs[i], &dst, &iov, 1);
+                       ret = unix_msg_send(ctxs[i], &dst, &iov, 1, NULL, 0);
                        if (ret != 0) {
                                fprintf(stderr, "unix_msg_send failed: %s\n",
                                        strerror(ret));
index a213cc22a67280e14423037ee164c31a0a80efc4..df094afb3d811bc3300387f9d68a0a231a1f83ff 100644 (file)
@@ -103,7 +103,7 @@ int main(void)
        state.buf = NULL;
        state.buflen = 0;
 
-       ret = unix_msg_send(ctx1, &addr2, NULL, 0);
+       ret = unix_msg_send(ctx1, &addr2, NULL, 0, NULL, 0);
        if (ret != 0) {
                fprintf(stderr, "unix_msg_send failed: %s\n",
                        strerror(ret));
@@ -120,7 +120,7 @@ int main(void)
        state.buf = &msg;
        state.buflen = sizeof(msg);
 
-       ret = unix_msg_send(ctx1, &addr2, &iov, 1);
+       ret = unix_msg_send(ctx1, &addr2, &iov, 1, NULL, 0);
        if (ret != 0) {
                fprintf(stderr, "unix_msg_send failed: %s\n",
                        strerror(ret));
@@ -141,13 +141,13 @@ int main(void)
        state.buflen = sizeof(buf);
 
        for (i=0; i<3; i++) {
-               ret = unix_msg_send(ctx1, &addr2, &iov, 1);
+               ret = unix_msg_send(ctx1, &addr2, &iov, 1, NULL, 0);
                if (ret != 0) {
                        fprintf(stderr, "unix_msg_send failed: %s\n",
                                strerror(ret));
                        return 1;
                }
-               ret = unix_msg_send(ctx2, &addr2, &iov, 1);
+               ret = unix_msg_send(ctx2, &addr2, &iov, 1, NULL, 0);
                if (ret != 0) {
                        fprintf(stderr, "unix_msg_send failed: %s\n",
                                strerror(ret));
@@ -186,7 +186,7 @@ int main(void)
                        j++;
                }
 
-               ret = unix_msg_send(ctx1, &addr1, iovs, j);
+               ret = unix_msg_send(ctx1, &addr1, iovs, j, NULL, 0);
                if (ret != 0) {
                        fprintf(stderr, "unix_msg_send failed: %s\n",
                                strerror(ret));
@@ -199,13 +199,13 @@ int main(void)
        printf("Filling send queues before freeing\n");
 
        for (i=0; i<5; i++) {
-               ret = unix_msg_send(ctx1, &addr2, &iov, 1);
+               ret = unix_msg_send(ctx1, &addr2, &iov, 1, NULL, 0);
                if (ret != 0) {
                        fprintf(stderr, "unix_msg_send failed: %s\n",
                                strerror(ret));
                        return 1;
                }
-               ret = unix_msg_send(ctx1, &addr1, &iov, 1);
+               ret = unix_msg_send(ctx1, &addr1, &iov, 1, NULL, 0);
                if (ret != 0) {
                        fprintf(stderr, "unix_msg_send failed: %s\n",
                                strerror(ret));
index e32a4d80bcd275d92caa6dfddd83a1973686ae4c..28ea51444cf5c379ecc2653ed348e889f1a876b0 100644 (file)
@@ -851,7 +851,8 @@ int unix_msg_init(const struct sockaddr_un *addr,
 }
 
 int unix_msg_send(struct unix_msg_ctx *ctx, const struct sockaddr_un *dst,
-                 const struct iovec *iov, int iovlen)
+                 const struct iovec *iov, int iovlen,
+                 const int *fds, size_t num_fds)
 {
        ssize_t msglen;
        size_t sent;
@@ -869,6 +870,16 @@ int unix_msg_send(struct unix_msg_ctx *ctx, const struct sockaddr_un *dst,
                return EINVAL;
        }
 
+#ifndef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+       if (num_fds > 0) {
+               return ENOSYS;
+       }
+#endif /* ! HAVE_STRUCT_MSGHDR_MSG_CONTROL */
+
+       if (num_fds > INT8_MAX) {
+               return EINVAL;
+       }
+
        if (msglen <= (ctx->fragment_len - sizeof(uint64_t))) {
                uint64_t cookie = 0;
 
@@ -880,7 +891,7 @@ int unix_msg_send(struct unix_msg_ctx *ctx, const struct sockaddr_un *dst,
                }
 
                return unix_dgram_send(ctx->dgram, dst, iov_copy, iovlen+1,
-                                      NULL, 0);
+                                      fds, num_fds);
        }
 
        hdr = (struct unix_msg_hdr) {
@@ -936,8 +947,19 @@ int unix_msg_send(struct unix_msg_ctx *ctx, const struct sockaddr_un *dst,
                }
                sent += (fragment_len - sizeof(ctx->cookie) - sizeof(hdr));
 
-               ret = unix_dgram_send(ctx->dgram, dst, iov_copy, iov_index,
-                                     NULL, 0);
+               /*
+                * only the last fragment should pass the fd array.
+                * That simplifies the receiver a lot.
+                */
+               if (sent < msglen) {
+                       ret = unix_dgram_send(ctx->dgram, dst,
+                                             iov_copy, iov_index,
+                                             NULL, 0);
+               } else {
+                       ret = unix_dgram_send(ctx->dgram, dst,
+                                             iov_copy, iov_index,
+                                             fds, num_fds);
+               }
                if (ret != 0) {
                        break;
                }
index 16c7c83aaa015d17f1a0b809732751c934909134..6024804fc3e1fab565314e43304b6a9da808acea 100644 (file)
@@ -93,11 +93,14 @@ int unix_msg_init(const struct sockaddr_un *addr,
  * @param[in] dst_sock The destination socket path
  * @param[in] iov The message
  * @param[in] iovlen The number of iov structs
+ * @param[in] fds - optional fd array
+ * @param[in] num_fds - fd array size
  * @return 0 on success, errno on failure
  */
 
 int unix_msg_send(struct unix_msg_ctx *ctx, const struct sockaddr_un *dst,
-                 const struct iovec *iov, int iovlen);
+                 const struct iovec *iov, int iovlen,
+                 const int *fds, size_t num_fds);
 
 /**
  * @brief Free a unix_msg_ctx