diff options
author | Michael Adam <obnox@samba.org> | 2014-05-18 00:22:55 +0200 |
---|---|---|
committer | Michael Adam <obnox@samba.org> | 2014-09-24 08:44:11 +0200 |
commit | 1b35d2ed631631f470dc5a7cff54068a832bfafc (patch) | |
tree | 822404a8d853823d6202fee97c007dcb2ae2522f /source3/lib | |
parent | c689547c9370967b3eecf0ea88252ad86f0234bf (diff) | |
download | samba-1b35d2ed631631f470dc5a7cff54068a832bfafc.tar.gz samba-1b35d2ed631631f470dc5a7cff54068a832bfafc.tar.xz samba-1b35d2ed631631f470dc5a7cff54068a832bfafc.zip |
s3:unix_msg: add fds-array to unix_msg_send() for fd passing
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Michael Adam <obnox@samba.org>
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/messages_dgm.c | 2 | ||||
-rw-r--r-- | source3/lib/unix_msg/test_source.c | 2 | ||||
-rw-r--r-- | source3/lib/unix_msg/tests.c | 14 | ||||
-rw-r--r-- | source3/lib/unix_msg/unix_msg.c | 30 | ||||
-rw-r--r-- | source3/lib/unix_msg/unix_msg.h | 5 |
5 files changed, 39 insertions, 14 deletions
diff --git a/source3/lib/messages_dgm.c b/source3/lib/messages_dgm.c index cadcb4be72..7ba79fcfd0 100644 --- a/source3/lib/messages_dgm.c +++ b/source3/lib/messages_dgm.c @@ -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; } diff --git a/source3/lib/unix_msg/test_source.c b/source3/lib/unix_msg/test_source.c index 7f6a7a5e8c..5224ebff6f 100644 --- a/source3/lib/unix_msg/test_source.c +++ b/source3/lib/unix_msg/test_source.c @@ -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)); diff --git a/source3/lib/unix_msg/tests.c b/source3/lib/unix_msg/tests.c index a213cc22a6..df094afb3d 100644 --- a/source3/lib/unix_msg/tests.c +++ b/source3/lib/unix_msg/tests.c @@ -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)); diff --git a/source3/lib/unix_msg/unix_msg.c b/source3/lib/unix_msg/unix_msg.c index e32a4d80bc..28ea51444c 100644 --- a/source3/lib/unix_msg/unix_msg.c +++ b/source3/lib/unix_msg/unix_msg.c @@ -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; } diff --git a/source3/lib/unix_msg/unix_msg.h b/source3/lib/unix_msg/unix_msg.h index 16c7c83aaa..6024804fc3 100644 --- a/source3/lib/unix_msg/unix_msg.h +++ b/source3/lib/unix_msg/unix_msg.h @@ -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 |