lib: Use msghdr_extract_fds in unix_msg
authorVolker Lendecke <vl@samba.org>
Wed, 31 Dec 2014 12:33:48 +0000 (13:33 +0100)
committerJeremy Allison <jra@samba.org>
Mon, 5 Jan 2015 23:33:09 +0000 (00:33 +0100)
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/lib/unix_msg/unix_msg.c

index 8d4960f6bcbaecdf82b580d733093e45d9264afd..c5f8143e0feab72390d1fdba52f782ed6f7e3163 100644 (file)
@@ -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,