s3:torture: wait in tevent-loop for child to confirm receive in FDPASS2 msg test
authorMichael Adam <obnox@samba.org>
Tue, 30 Sep 2014 08:15:33 +0000 (10:15 +0200)
committerMichael Adam <obnox@samba.org>
Tue, 30 Sep 2014 14:36:10 +0000 (16:36 +0200)
This is the only way to correctly transfer bigger messages.

Signed-off-by: Michael Adam <obnox@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source3/torture/test_messaging_fd_passing.c

index 4be0221d2d4dd3ca1087a20cdc70e2f966ae3cbc..94c5244bbf5a0ebfe12bc7d2e6b7efca8bdff106 100644 (file)
@@ -161,6 +161,13 @@ static bool fdpass2_child(int ready_fd)
 
        SMB_ASSERT(rec->num_fds == 2);
 
+       /* Tell the parent we are done. */
+       bytes = write(ready_fd, &c, 1);
+       if (bytes != 1) {
+               perror("child: failed to write to ready_fd");
+               goto done;
+       }
+
        up_fd = rec->fds[0];
        down_fd = rec->fds[1];
 
@@ -184,6 +191,29 @@ done:
        return retval;
 }
 
+struct child_done_state {
+       int fd;
+       bool done;
+};
+
+static void child_done_cb(struct tevent_context *ev,
+                         struct tevent_fd *fde,
+                         uint16_t flags,
+                         void *private_data)
+{
+       struct child_done_state *state =
+                       (struct child_done_state *)private_data;
+       char c = 0;
+       ssize_t bytes;
+
+       bytes = read(state->fd, &c, 1);
+       if (bytes != 1) {
+               perror("parent: read from ready_fd failed");
+       }
+
+       state->done = true;
+}
+
 static bool fdpass2_parent(pid_t child_pid, int ready_fd)
 {
        struct tevent_context *ev = NULL;
@@ -200,6 +230,8 @@ static bool fdpass2_parent(pid_t child_pid, int ready_fd)
        ssize_t bytes;
        struct iovec iov;
        DATA_BLOB blob;
+       struct tevent_fd *child_done_fde;
+       struct child_done_state child_state;
 
        ev = samba_tevent_context_init(frame);
        if (ev == NULL) {
@@ -232,6 +264,17 @@ static bool fdpass2_parent(pid_t child_pid, int ready_fd)
                goto done;
        }
 
+       child_state.fd = ready_fd;
+       child_state.done = false;
+
+       child_done_fde = tevent_add_fd(ev, ev, ready_fd, TEVENT_FD_READ,
+                                      child_done_cb, &child_state);
+       if (child_done_fde == NULL) {
+               fprintf(stderr,
+                       "parent: failed tevent_add_fd for child done\n");
+               goto done;
+       }
+
        pass_fds[0] = up_pipe[0];
        pass_fds[1] = down_pipe[1];
 
@@ -255,6 +298,18 @@ static bool fdpass2_parent(pid_t child_pid, int ready_fd)
                goto done;
        }
 
+       printf("parent: waiting for child to confirm\n");
+
+       while (!child_state.done) {
+               ret = tevent_loop_once(ev);
+               if (ret != 0) {
+                       fprintf(stderr, "parent: tevent_loop_once failed\n");
+                       goto done;
+               }
+       }
+
+       printf("parent: child confirmed\n");
+
        close(up_pipe[0]);
        close(down_pipe[1]);