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 22bool 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 52bool 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 99int 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 110bool 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 131bool ppoll_negative_test(void) { 132 struct timespec timeout_ts = {-1, -1}; 133 return ppoll_test_handler(&timeout_ts); 134} 135 136bool ppoll_null_test(void) { 137 return ppoll_test_handler(NULL); 138} 139 140bool 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 146bool 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 162bool 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 203bool 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 224bool 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 261BEGIN_TEST_CASE(fdio_handle_fd_test) 262RUN_TEST(close_test); 263RUN_TEST(pipe_test); 264RUN_TEST(ppoll_negative_test); 265RUN_TEST(ppoll_null_test); 266RUN_TEST(ppoll_overflow_test); 267RUN_TEST(ppoll_immediate_timeout_test); 268RUN_TEST(transfer_fd_test); 269RUN_TEST(transfer_device_test); 270RUN_TEST(create_fd_from_connected_socket); 271END_TEST_CASE(fdio_handle_fd_test) 272