summaryrefslogtreecommitdiffstats
path: root/source3/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/messages_dgm.c2
-rw-r--r--source3/lib/unix_msg/test_source.c2
-rw-r--r--source3/lib/unix_msg/tests.c14
-rw-r--r--source3/lib/unix_msg/unix_msg.c30
-rw-r--r--source3/lib/unix_msg/unix_msg.h5
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