1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <assert.h>
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <stdbool.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <sys/ioctl.h>
12 #include <sys/stat.h>
13 #include <threads.h>
14 #include <unistd.h>
15 
16 #include <lib/fdio/io.h>
17 #include <lib/fdio/util.h>
18 #include <unittest/unittest.h>
19 #include <zircon/processargs.h>
20 #include <zircon/syscalls.h>
21 
close_test(void)22 bool close_test(void) {
23     BEGIN_TEST;
24 
25     zx_handle_t h = ZX_HANDLE_INVALID;
26     ASSERT_EQ(ZX_OK, zx_event_create(0u, &h), "zx_event_create() failed");
27     ASSERT_NE(h, ZX_HANDLE_INVALID, "");
28 
29     // fdio_handle_fd() with shared_handle = true
30     int fd = fdio_handle_fd(h, ZX_USER_SIGNAL_0, ZX_USER_SIGNAL_1, true);
31     ASSERT_GT(fd, 0, "fdio_handle_fd() failed");
32 
33     close(fd);
34 
35     // close(fd) has not closed the wrapped handle
36     EXPECT_EQ(ZX_OK, zx_object_signal(h, 0, ZX_USER_SIGNAL_0),
37               "zx_object_signal() should succeed");
38 
39     // fdio_handle_fd() with shared_handle = false
40     fd = fdio_handle_fd(h, ZX_USER_SIGNAL_0, ZX_USER_SIGNAL_1, false);
41     ASSERT_GT(fd, 0, "fdio_handle_fd() failed");
42 
43     close(fd);
44 
45     // close(fd) has closed the wrapped handle
46     EXPECT_EQ(ZX_ERR_BAD_HANDLE, zx_object_signal(h, 0, ZX_USER_SIGNAL_0),
47               "zx_object_signal() should fail");
48 
49     END_TEST;
50 }
51 
pipe_test(void)52 bool pipe_test(void) {
53     BEGIN_TEST;
54 
55     int fds[2];
56     int status = pipe(fds);
57     ASSERT_EQ(status, 0, "pipe() failed");
58 
59     struct stat st;
60     ASSERT_EQ(fstat(fds[0], &st), 0, "fstat() on pipe failed");
61     ASSERT_EQ(st.st_mode & S_IFMT, (mode_t) S_IFIFO, "Unexpected mode");
62     ASSERT_EQ(fstat(fds[1], &st), 0, "fstat() on pipe failed");
63     ASSERT_EQ(st.st_mode & S_IFMT, (mode_t) S_IFIFO, "Unexpected mode");
64 
65     status = fcntl(fds[0], F_GETFL);
66     ASSERT_EQ(status, 0, "fcntl(F_GETFL) failed");
67 
68     status |= O_NONBLOCK;
69     status = fcntl(fds[0], F_SETFL, status);
70     ASSERT_EQ(status, 0, "fcntl(FSETFL, O_NONBLOCK) failed");
71 
72     status = fcntl(fds[0], F_GETFL);
73     ASSERT_EQ(status, O_NONBLOCK, "fcntl(F_GETFL) failed");
74 
75     int message[2] = {-6, 1};
76     ssize_t written = write(fds[1], message, sizeof(message));
77     ASSERT_GE(written, 0, "write() failed");
78     ASSERT_EQ((uint32_t)written, sizeof(message),
79               "write() should have written the whole message.");
80 
81     int available = 0;
82     status = ioctl(fds[0], FIONREAD, &available);
83     ASSERT_GE(status, 0, "ioctl(FIONREAD) failed");
84     EXPECT_EQ((uint32_t)available, sizeof(message),
85               "ioctl(FIONREAD) queried wrong number of bytes");
86 
87     int read_message[2];
88     ssize_t bytes_read = read(fds[0], read_message, sizeof(read_message));
89     ASSERT_GE(bytes_read, 0, "read() failed");
90     ASSERT_EQ((uint32_t)bytes_read, sizeof(read_message),
91               "read() read wrong number of bytes");
92 
93     EXPECT_EQ(read_message[0], message[0], "read() read wrong value");
94     EXPECT_EQ(read_message[1], message[1], "read() read wrong value");
95 
96     END_TEST;
97 }
98 
write_thread(void * arg)99 int write_thread(void* arg) {
100     // Sleep to try to ensure the write happens after the poll.
101     zx_nanosleep(ZX_MSEC(5));
102     int message[2] = {-6, 1};
103     ssize_t written = write(*(int*)arg, message, sizeof(message));
104     ASSERT_GE(written, 0, "write() failed");
105     ASSERT_EQ((uint32_t)written, sizeof(message),
106               "write() should have written the whole message.");
107     return 0;
108 }
109 
ppoll_test_handler(struct timespec * timeout)110 bool ppoll_test_handler(struct timespec* timeout) {
111     BEGIN_TEST;
112 
113     int fds[2];
114     int status = pipe(fds);
115     ASSERT_EQ(status, 0, "pipe() failed");
116 
117     thrd_t t;
118     int thrd_create_result = thrd_create(&t, write_thread, &fds[1]);
119     ASSERT_EQ(thrd_create_result, thrd_success, "create blocking send thread");
120 
121     struct pollfd poll_fds[1] = {{fds[0], POLLIN, 0}};
122     int ppoll_result = ppoll(poll_fds, 1, timeout, NULL);
123 
124     EXPECT_EQ(1, ppoll_result, "didn't read anything");
125 
126     ASSERT_EQ(thrd_join(t, NULL), thrd_success, "join blocking send thread");
127 
128     END_TEST;
129 }
130 
ppoll_negative_test(void)131 bool ppoll_negative_test(void) {
132     struct timespec timeout_ts = {-1, -1};
133     return ppoll_test_handler(&timeout_ts);
134 }
135 
ppoll_null_test(void)136 bool ppoll_null_test(void) {
137     return ppoll_test_handler(NULL);
138 }
139 
ppoll_overflow_test(void)140 bool ppoll_overflow_test(void) {
141     unsigned int nanoseconds_in_seconds = 1000000000;
142     struct timespec timeout_ts = {UINT64_MAX / nanoseconds_in_seconds, UINT64_MAX % nanoseconds_in_seconds};
143     return ppoll_test_handler(&timeout_ts);
144 }
145 
ppoll_immediate_timeout_test(void)146 bool ppoll_immediate_timeout_test(void) {
147     BEGIN_TEST;
148 
149     int fds[2];
150     int status = pipe(fds);
151     ASSERT_EQ(status, 0, "pipe() failed");
152 
153     struct timespec timeout = {0, 0};
154     struct pollfd poll_fds[1] = {{fds[0], POLLIN, 0}};
155     int ppoll_result = ppoll(poll_fds, 1, &timeout, NULL);
156 
157     EXPECT_EQ(0, ppoll_result, "no fds should be readable");
158 
159     END_TEST;
160 }
161 
transfer_fd_test(void)162 bool transfer_fd_test(void) {
163     BEGIN_TEST;
164 
165     int fds[2];
166     int status = pipe(fds);
167     ASSERT_EQ(status, 0, "pipe() failed");
168 
169     // Make pipe nonblocking, write message
170     status |= O_NONBLOCK;
171     status = fcntl(fds[0], F_SETFL, status);
172     ASSERT_EQ(status, 0, "fcntl(FSETFL, O_NONBLOCK) failed");
173     int message[2] = {-6, 1};
174     ssize_t written = write(fds[1], message, sizeof(message));
175     ASSERT_GE(written, 0, "write() failed");
176     ASSERT_EQ((uint32_t)written, sizeof(message),
177               "write() should have written the whole message.");
178 
179 
180     // fd --> handles
181     zx_handle_t handles[FDIO_MAX_HANDLES];
182     uint32_t types[FDIO_MAX_HANDLES];
183     zx_status_t r = fdio_transfer_fd(fds[0], 0, handles, types);
184     ASSERT_GT(r, 0, "failed to transfer fds to handles");
185 
186     // handles --> fd
187     ASSERT_EQ(fdio_create_fd(handles, types, r, &fds[0]), ZX_OK,
188               "failed to transfer handles to fds");
189 
190     // Read message
191     int read_message[2];
192     ssize_t bytes_read = read(fds[0], read_message, sizeof(read_message));
193     ASSERT_GE(bytes_read, 0, "read() failed");
194     ASSERT_EQ((uint32_t)bytes_read, sizeof(read_message),
195               "read() read wrong number of bytes");
196 
197     EXPECT_EQ(read_message[0], message[0], "read() read wrong value");
198     EXPECT_EQ(read_message[1], message[1], "read() read wrong value");
199 
200     END_TEST;
201 }
202 
transfer_device_test(void)203 bool transfer_device_test(void) {
204     BEGIN_TEST;
205 
206     int fd = open("/dev/zero", O_RDONLY);
207     ASSERT_GE(fd, 0, "Failed to open /dev/zero");
208 
209     // fd --> handles
210     zx_handle_t handles[FDIO_MAX_HANDLES];
211     uint32_t types[FDIO_MAX_HANDLES];
212     zx_status_t r = fdio_transfer_fd(fd, 0, handles, types);
213     ASSERT_GT(r, 0, "failed to transfer fds to handles");
214 
215     // handles --> fd
216     ASSERT_EQ(fdio_create_fd(handles, types, r, &fd), ZX_OK,
217               "failed to transfer handles to fds");
218 
219     ASSERT_EQ(close(fd), 0, "Failed to close fd");
220 
221     END_TEST;
222 }
223 
create_fd_from_connected_socket(void)224 bool create_fd_from_connected_socket(void) {
225     BEGIN_TEST;
226 
227     int fd;
228     uint32_t type = PA_FDIO_SOCKET;
229     zx_handle_t h1, h2;
230     ASSERT_EQ(ZX_OK, zx_socket_create(ZX_SOCKET_STREAM, &h1, &h2),
231               "failed to create socket pair");
232     ASSERT_EQ(ZX_OK, fdio_create_fd(&h1, &type, 1, &fd),
233               "failed to create FD for socket handle");
234 
235     int message[2] = {0xab, 0x1234};
236     size_t written;
237     ASSERT_EQ(ZX_OK, zx_socket_write(h2, 0, message, sizeof(message), &written),
238               "failed to write to socket handle");
239     ASSERT_EQ(sizeof(message), written,
240               "failed to write full message to socket handle");
241 
242     int read_message[2] = {};
243     ssize_t bytes_read = read(fd, read_message, sizeof(read_message));
244     ASSERT_EQ(sizeof(message), (uint32_t)bytes_read,
245               "failed to read from socket fd");
246     ASSERT_EQ(0, memcmp(message, read_message, sizeof(message)),
247               "incorrect bytes read from socket fd");
248 
249     // Set O_NONBLOCK
250     int flags = fcntl(fd, F_GETFL);
251     ASSERT_EQ(flags, 0, "fcntl(F_GETFL) failed");
252     flags |= O_NONBLOCK;
253     int ret = fcntl(fd, F_SETFL, flags);
254     ASSERT_EQ(ret, 0, "fcntl(FSETFL, O_NONBLOCK) failed");
255     ASSERT_EQ(-1, read(fd, read_message, sizeof(read_message)),
256               "failed to read from socket with O_NONBLOCK");
257     ASSERT_EQ(EAGAIN, errno, "errno incorrect");
258     END_TEST;
259 }
260 
bind_to_fd_invalid_tests(void)261 static bool bind_to_fd_invalid_tests(void) {
262     BEGIN_TEST;
263 
264     fdio_t* fdio = fdio_null_create();
265     EXPECT_NONNULL(fdio, "");
266 
267     // When binding and not providing a specific |fd|, the
268     // |starting_fd| must be nonnegative.
269     int fd = fdio_bind_to_fd(fdio, -1, -1);
270     int err = errno;
271     EXPECT_LT(fd, 0, "");
272     EXPECT_EQ(err, EINVAL, "");
273 
274     // Starting with a huge |starting_fd| will fail since the table
275     // does not hold so many.
276     fd = fdio_bind_to_fd(fdio, -1, INT_MAX);
277     err = errno;
278     EXPECT_LT(fd, 0, "");
279     EXPECT_EQ(err, EMFILE, "");
280 
281     END_TEST;
282 }
283 
284 BEGIN_TEST_CASE(fdio_handle_fd_test)
285 RUN_TEST(close_test);
286 RUN_TEST(pipe_test);
287 RUN_TEST(ppoll_negative_test);
288 RUN_TEST(ppoll_null_test);
289 RUN_TEST(ppoll_overflow_test);
290 RUN_TEST(ppoll_immediate_timeout_test);
291 RUN_TEST(transfer_fd_test);
292 RUN_TEST(transfer_device_test);
293 RUN_TEST(create_fd_from_connected_socket);
294 RUN_TEST(bind_to_fd_invalid_tests);
295 
296 END_TEST_CASE(fdio_handle_fd_test)
297