diff options
Diffstat (limited to 'source3/lib/unix_msg')
-rw-r--r-- | source3/lib/unix_msg/unix_msg.c | 75 |
1 files changed, 19 insertions, 56 deletions
diff --git a/source3/lib/unix_msg/unix_msg.c b/source3/lib/unix_msg/unix_msg.c index 8d4960f6bc..c5f8143e0f 100644 --- a/source3/lib/unix_msg/unix_msg.c +++ b/source3/lib/unix_msg/unix_msg.c @@ -135,32 +135,6 @@ static int prepare_socket(int sock) return prepare_socket_cloexec(sock); } -static void extract_fd_array_from_msghdr(struct msghdr *msg, int **fds, - size_t *num_fds) -{ -#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL - struct cmsghdr *cmsg; - - for(cmsg = CMSG_FIRSTHDR(msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(msg, cmsg)) - { - void *data = CMSG_DATA(cmsg); - - if (cmsg->cmsg_type != SCM_RIGHTS) { - continue; - } - if (cmsg->cmsg_level != SOL_SOCKET) { - continue; - } - - *fds = (int *)data; - *num_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof (int); - break; - } -#endif -} - static size_t unix_dgram_msg_size(void) { size_t msgsize = sizeof(struct unix_dgram_msg); @@ -195,14 +169,11 @@ static void close_fd_array_dgram_msg(struct unix_dgram_msg *dmsg) { struct msghdr_buf *hdr = unix_dgram_msghdr(dmsg); struct msghdr *msg = msghdr_buf_msghdr(hdr); - int *fds = NULL; - size_t num_fds = 0; + size_t num_fds = msghdr_extract_fds(msg, NULL, 0); + int fds[num_fds]; - extract_fd_array_from_msghdr(msg, &fds, &num_fds); + msghdr_extract_fds(msg, fds, num_fds); - /* - * TODO: caveat - side-effect - changing msg ??? - */ close_fd_array(fds, num_fds); } @@ -304,8 +275,6 @@ static void unix_dgram_recv_handler(struct poll_watch *w, int fd, short events, #ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL char buf[CMSG_SPACE(sizeof(int)*INT8_MAX)] = { 0, }; #endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */ - int *fds = NULL; - size_t i, num_fds = 0; iov = (struct iovec) { .iov_base = (void *)ctx->recv_buf, @@ -342,32 +311,26 @@ static void unix_dgram_recv_handler(struct poll_watch *w, int fd, short events, return; } - extract_fd_array_from_msghdr(&msg, &fds, &num_fds); - - for (i = 0; i < num_fds; i++) { - int err; + { + size_t num_fds = msghdr_extract_fds(&msg, NULL, 0); + int fds[num_fds]; + int i; - err = prepare_socket_cloexec(fds[i]); - if (err != 0) { - goto cleanup_fds; - } - } + msghdr_extract_fds(&msg, fds, num_fds); - ctx->recv_callback(ctx, ctx->recv_buf, received, - fds, num_fds, ctx->private_data); + for (i = 0; i < num_fds; i++) { + int err; - /* - * Close those fds that the callback has not set to -1. - */ - close_fd_array(fds, num_fds); - - return; - -cleanup_fds: - close_fd_array(fds, num_fds); + err = prepare_socket_cloexec(fds[i]); + if (err != 0) { + close_fd_array(fds, num_fds); + num_fds = 0; + } + } - ctx->recv_callback(ctx, ctx->recv_buf, received, - NULL, 0, ctx->private_data); + ctx->recv_callback(ctx, ctx->recv_buf, received, + fds, num_fds, ctx->private_data); + } } static void unix_dgram_job_finished(struct poll_watch *w, int fd, short events, |