1 // Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7 #include <config.h>
8
9 #include <util/io/fd.h>
10 #include <util/io/fd_share.h>
11
12 #include <util/unittests/check_valgrind.h>
13 #include <util/unittests/fork.h>
14
15 #include <gtest/gtest.h>
16 #include <unistd.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <cstdio>
20
21 using namespace isc::util::io;
22 using namespace isc::util::unittests;
23
24 namespace {
25
26 // We test that we can transfer a pipe over other pipe
TEST(FDShare,transfer)27 TEST(FDShare, transfer) {
28
29 if (!isc::util::unittests::runningOnValgrind()) {
30 // Get a pipe and fork
31 int pipes[2];
32 ASSERT_NE(-1, socketpair(AF_UNIX, SOCK_STREAM, 0, pipes));
33 const pid_t sender(fork());
34 ASSERT_NE(-1, sender);
35 if (sender) { // We are in parent
36 // Close the other side of pipe, we want only writable one
37 EXPECT_NE(-1, close(pipes[0]));
38 // Get a process to check data
39 int fd(0);
40 const pid_t checker(check_output(&fd, "data", 4));
41 ASSERT_NE(-1, checker);
42 // Now, send the file descriptor, close it and close the pipe
43 EXPECT_NE(-1, send_fd(pipes[1], fd));
44 EXPECT_NE(-1, close(pipes[1]));
45 EXPECT_NE(-1, close(fd));
46 // Check both subprocesses ended well
47 EXPECT_TRUE(process_ok(sender));
48 EXPECT_TRUE(process_ok(checker));
49 } else { // We are in child. We do not use ASSERT here
50 // Close the write end, we only read
51 if (close(pipes[1])) {
52 exit(1);
53 }
54 // Get the file descriptor
55 const int fd(recv_fd(pipes[0]));
56 if (fd == -1) {
57 exit(1);
58 }
59 // This pipe is not needed
60 if (close(pipes[0])) {
61 exit(1);
62 }
63 // Send "data" through the received fd, close it and be done
64 if (!write_data(fd, "data", 4) || close(fd) == -1) {
65 exit(1);
66 }
67 exit(0);
68 }
69 }
70 }
71
72 }
73