1b29e1426SEnji Cooper /*- 2b29e1426SEnji Cooper * Copyright (c) 2018 Enji Cooper. 3b29e1426SEnji Cooper * All rights reserved. 4b29e1426SEnji Cooper * 5b29e1426SEnji Cooper * Redistribution and use in source and binary forms, with or without 6b29e1426SEnji Cooper * modification, are permitted provided that the following conditions 7b29e1426SEnji Cooper * are met: 8b29e1426SEnji Cooper * 1. Redistributions of source code must retain the above copyright 9b29e1426SEnji Cooper * notice, this list of conditions and the following disclaimer. 10b29e1426SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 11b29e1426SEnji Cooper * notice, this list of conditions and the following disclaimer in the 12b29e1426SEnji Cooper * documentation and/or other materials provided with the distribution. 13b29e1426SEnji Cooper * 14b29e1426SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15b29e1426SEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16b29e1426SEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17b29e1426SEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18b29e1426SEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19b29e1426SEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20b29e1426SEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21b29e1426SEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22b29e1426SEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23b29e1426SEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24b29e1426SEnji Cooper * SUCH DAMAGE. 25b29e1426SEnji Cooper */ 26b29e1426SEnji Cooper 27b29e1426SEnji Cooper #include <sys/cdefs.h> 28b29e1426SEnji Cooper __FBSDID("$FreeBSD$"); 29b29e1426SEnji Cooper 30b29e1426SEnji Cooper #include <sys/param.h> 31b29e1426SEnji Cooper #include <sys/mman.h> 32b29e1426SEnji Cooper #include <sys/socket.h> 33b29e1426SEnji Cooper #include <sys/stat.h> 34b29e1426SEnji Cooper #include <sys/sysctl.h> 35b29e1426SEnji Cooper #include <sys/uio.h> 36b29e1426SEnji Cooper #include <err.h> 37b29e1426SEnji Cooper #include <errno.h> 38b29e1426SEnji Cooper #include <fcntl.h> 39b29e1426SEnji Cooper #include <netdb.h> 40b29e1426SEnji Cooper #include <paths.h> 41b29e1426SEnji Cooper #include <stdio.h> 42b29e1426SEnji Cooper #include <stdlib.h> 43b29e1426SEnji Cooper #include <string.h> 44b29e1426SEnji Cooper #include <unistd.h> 45b29e1426SEnji Cooper 46b29e1426SEnji Cooper #include <atf-c.h> 47b29e1426SEnji Cooper 48b29e1426SEnji Cooper const char DETERMINISTIC_PATTERN[] = 49b29e1426SEnji Cooper "The past is already gone, the future is not yet here. There's only one moment for you to live.\n"; 50b29e1426SEnji Cooper 51b29e1426SEnji Cooper #define SOURCE_FILE "source" 52b29e1426SEnji Cooper #define DESTINATION_FILE "dest" 53b29e1426SEnji Cooper 54b29e1426SEnji Cooper #define PORTRANGE_FIRST "net.inet.ip.portrange.first" 55b29e1426SEnji Cooper #define PORTRANGE_LAST "net.inet.ip.portrange.last" 56b29e1426SEnji Cooper 57b29e1426SEnji Cooper static int portrange_first, portrange_last; 58b29e1426SEnji Cooper 59b29e1426SEnji Cooper static int 60b29e1426SEnji Cooper get_int_via_sysctlbyname(const char *oidname) 61b29e1426SEnji Cooper { 62b29e1426SEnji Cooper size_t oldlen; 63b29e1426SEnji Cooper int int_value; 64b29e1426SEnji Cooper 65b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(sysctlbyname(oidname, &int_value, &oldlen, NULL, 0), 66b29e1426SEnji Cooper 0, "sysctlbyname(%s, ...) failed: %s", oidname, strerror(errno)); 67b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(sizeof(int_value), oldlen, "sanity check failed"); 68b29e1426SEnji Cooper 69b29e1426SEnji Cooper return (int_value); 70b29e1426SEnji Cooper } 71b29e1426SEnji Cooper 72b29e1426SEnji Cooper static int 73b29e1426SEnji Cooper generate_random_port(int seed) 74b29e1426SEnji Cooper { 75b29e1426SEnji Cooper int random_port; 76b29e1426SEnji Cooper 77b29e1426SEnji Cooper printf("Generating a random port with seed=%d\n", seed); 78b29e1426SEnji Cooper if (portrange_first == 0) { 79b29e1426SEnji Cooper portrange_first = get_int_via_sysctlbyname(PORTRANGE_FIRST); 80b29e1426SEnji Cooper printf("Port range lower bound: %d\n", portrange_first); 81b29e1426SEnji Cooper } 82b29e1426SEnji Cooper 83b29e1426SEnji Cooper if (portrange_last == 0) { 84b29e1426SEnji Cooper portrange_last = get_int_via_sysctlbyname(PORTRANGE_LAST); 85b29e1426SEnji Cooper printf("Port range upper bound: %d\n", portrange_last); 86b29e1426SEnji Cooper } 87b29e1426SEnji Cooper 88b29e1426SEnji Cooper srand((unsigned)seed); 89b29e1426SEnji Cooper 90b29e1426SEnji Cooper random_port = rand() % (portrange_last - portrange_first) + 91b29e1426SEnji Cooper portrange_first; 92b29e1426SEnji Cooper 93b29e1426SEnji Cooper printf("Random port generated: %d\n", random_port); 94b29e1426SEnji Cooper return (random_port); 95b29e1426SEnji Cooper } 96b29e1426SEnji Cooper 97b29e1426SEnji Cooper static void 98b29e1426SEnji Cooper resolve_localhost(struct addrinfo **res, int domain, int type, int port) 99b29e1426SEnji Cooper { 100b29e1426SEnji Cooper char *serv; 101b29e1426SEnji Cooper struct addrinfo hints; 102b29e1426SEnji Cooper int error; 103b29e1426SEnji Cooper 104b29e1426SEnji Cooper ATF_REQUIRE_MSG(domain == AF_INET || domain == AF_INET6, 105b29e1426SEnji Cooper "unhandled domain: %d", domain); 106b29e1426SEnji Cooper 107b29e1426SEnji Cooper ATF_REQUIRE_MSG(asprintf(&serv, "%d", port) >= 0, 108b29e1426SEnji Cooper "asprintf failed: %s", strerror(errno)); 109b29e1426SEnji Cooper 110b29e1426SEnji Cooper memset(&hints, 0, sizeof(hints)); 111b29e1426SEnji Cooper hints.ai_family = domain; 112b29e1426SEnji Cooper hints.ai_flags = AI_ADDRCONFIG|AI_NUMERICSERV; 113b29e1426SEnji Cooper hints.ai_socktype = type; 114b29e1426SEnji Cooper 115b29e1426SEnji Cooper error = getaddrinfo("localhost", serv, &hints, res); 116b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(error, 0, 117*4ce7bd25SEnji Cooper "getaddrinfo failed: %s", gai_strerror(error)); 118b29e1426SEnji Cooper free(serv); 119b29e1426SEnji Cooper } 120b29e1426SEnji Cooper 121b29e1426SEnji Cooper static int 122b29e1426SEnji Cooper make_socket(int domain, int type, int protocol) 123b29e1426SEnji Cooper { 124b29e1426SEnji Cooper int sock; 125b29e1426SEnji Cooper 126b29e1426SEnji Cooper sock = socket(domain, type, protocol); 127b29e1426SEnji Cooper ATF_REQUIRE_MSG(sock != -1, "socket(%d, %d, 0) failed: %s", 128b29e1426SEnji Cooper domain, type, strerror(errno)); 129b29e1426SEnji Cooper 130b29e1426SEnji Cooper return (sock); 131b29e1426SEnji Cooper } 132b29e1426SEnji Cooper 133b29e1426SEnji Cooper static int 134b29e1426SEnji Cooper setup_client(int domain, int type, int port) 135b29e1426SEnji Cooper { 136b29e1426SEnji Cooper struct addrinfo *res; 137b29e1426SEnji Cooper char host[NI_MAXHOST+1]; 138b29e1426SEnji Cooper int error, sock; 139b29e1426SEnji Cooper 140b29e1426SEnji Cooper resolve_localhost(&res, domain, type, port); 141b29e1426SEnji Cooper error = getnameinfo( 142b29e1426SEnji Cooper (const struct sockaddr*)res->ai_addr, res->ai_addrlen, 143b29e1426SEnji Cooper host, nitems(host) - 1, NULL, 0, NI_NUMERICHOST); 144b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(error, 0, 145b29e1426SEnji Cooper "getnameinfo failed: %s", gai_strerror(error)); 146b29e1426SEnji Cooper printf( 147b29e1426SEnji Cooper "Will try to connect to host='%s', address_family=%d, " 148b29e1426SEnji Cooper "socket_type=%d\n", 149b29e1426SEnji Cooper host, res->ai_family, res->ai_socktype); 150b29e1426SEnji Cooper sock = make_socket(res->ai_family, res->ai_socktype, res->ai_protocol); 151b29e1426SEnji Cooper error = connect(sock, (struct sockaddr*)res->ai_addr, res->ai_addrlen); 152b29e1426SEnji Cooper freeaddrinfo(res); 153b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(error, 0, "connect failed: %s", strerror(errno)); 154b29e1426SEnji Cooper return (sock); 155b29e1426SEnji Cooper } 156b29e1426SEnji Cooper 157b29e1426SEnji Cooper /* 158b29e1426SEnji Cooper * XXX: use linear probing to find a free port and eliminate `port` argument as 159b29e1426SEnji Cooper * a [const] int (it will need to be a pointer so it can be passed back out of 160b29e1426SEnji Cooper * the function and can influence which port `setup_client(..)` connects on. 161b29e1426SEnji Cooper */ 162b29e1426SEnji Cooper static int 163b29e1426SEnji Cooper setup_server(int domain, int type, int port) 164b29e1426SEnji Cooper { 165b29e1426SEnji Cooper struct addrinfo *res; 166b29e1426SEnji Cooper char host[NI_MAXHOST+1]; 167b29e1426SEnji Cooper int error, sock; 168b29e1426SEnji Cooper 169b29e1426SEnji Cooper resolve_localhost(&res, domain, type, port); 170b29e1426SEnji Cooper sock = make_socket(res->ai_family, res->ai_socktype, res->ai_protocol); 171b29e1426SEnji Cooper 172b29e1426SEnji Cooper error = getnameinfo( 173b29e1426SEnji Cooper (const struct sockaddr*)res->ai_addr, res->ai_addrlen, 174b29e1426SEnji Cooper host, nitems(host) - 1, NULL, 0, NI_NUMERICHOST); 175b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(error, 0, 176b29e1426SEnji Cooper "getnameinfo failed: %s", gai_strerror(error)); 177b29e1426SEnji Cooper printf( 178b29e1426SEnji Cooper "Will try to bind socket to host='%s', address_family=%d, " 179b29e1426SEnji Cooper "socket_type=%d\n", 180b29e1426SEnji Cooper host, res->ai_family, res->ai_socktype); 181b29e1426SEnji Cooper error = bind(sock, res->ai_addr, res->ai_addrlen); 182b29e1426SEnji Cooper freeaddrinfo(res); 183b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(error, 0, "bind failed: %s", strerror(errno)); 184b29e1426SEnji Cooper error = listen(sock, 1); 185b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(error, 0, "listen failed: %s", strerror(errno)); 186b29e1426SEnji Cooper 187b29e1426SEnji Cooper return (sock); 188b29e1426SEnji Cooper } 189b29e1426SEnji Cooper 190b29e1426SEnji Cooper /* 191b29e1426SEnji Cooper * This function is a helper routine for taking data being sent by `sendfile` via 192b29e1426SEnji Cooper * `server_sock`, and pushing the received stream out to a file, denoted by 193b29e1426SEnji Cooper * `dest_filename`. 194b29e1426SEnji Cooper */ 195b29e1426SEnji Cooper static void 196b29e1426SEnji Cooper server_cat(const char *dest_filename, int server_sock, size_t len) 197b29e1426SEnji Cooper { 198de00e09dSEnji Cooper char *buffer; 199b29e1426SEnji Cooper int recv_sock; 200b29e1426SEnji Cooper ssize_t received_bytes; 201b29e1426SEnji Cooper 202b29e1426SEnji Cooper buffer = calloc(len + 1, sizeof(char)); 203b29e1426SEnji Cooper if (buffer == NULL) 204b29e1426SEnji Cooper err(1, "malloc failed"); 205b29e1426SEnji Cooper 206b29e1426SEnji Cooper recv_sock = accept(server_sock, NULL, 0); 207b29e1426SEnji Cooper if (recv_sock == -1) 208b29e1426SEnji Cooper err(1, "accept failed"); 209b29e1426SEnji Cooper 210b29e1426SEnji Cooper /* 211b29e1426SEnji Cooper * XXX: this assumes the simplest case where all data is received in a 212b29e1426SEnji Cooper * single recv(2) call. 213b29e1426SEnji Cooper */ 214b29e1426SEnji Cooper if (recv(recv_sock, buffer, len, 0) == -1) 215b29e1426SEnji Cooper err(1, "recv failed"); 216b29e1426SEnji Cooper 217b29e1426SEnji Cooper atf_utils_create_file(dest_filename, "%s", buffer); 218b29e1426SEnji Cooper 219b29e1426SEnji Cooper /* 220b29e1426SEnji Cooper * This recv(2) call helps ensure the amount of sent data is exactly 221b29e1426SEnji Cooper * what was specified by `len`. 222b29e1426SEnji Cooper */ 223b29e1426SEnji Cooper received_bytes = recv(recv_sock, buffer, len, 0); 224b29e1426SEnji Cooper switch (received_bytes) { 225b29e1426SEnji Cooper case -1: 226b29e1426SEnji Cooper err(1, "recv failed"); 227b29e1426SEnji Cooper case 0: 228b29e1426SEnji Cooper break; 229b29e1426SEnji Cooper default: 230b29e1426SEnji Cooper errx(1, "received unexpected data: %s", buffer); 231b29e1426SEnji Cooper } 232b29e1426SEnji Cooper 233b29e1426SEnji Cooper (void)close(recv_sock); 234b29e1426SEnji Cooper (void)close(server_sock); 235b29e1426SEnji Cooper free(buffer); 236b29e1426SEnji Cooper } 237b29e1426SEnji Cooper 238b29e1426SEnji Cooper static int 239b29e1426SEnji Cooper setup_tcp_server(int domain, int port) 240b29e1426SEnji Cooper { 241b29e1426SEnji Cooper 242b29e1426SEnji Cooper return (setup_server(domain, SOCK_STREAM, port)); 243b29e1426SEnji Cooper } 244b29e1426SEnji Cooper 245b29e1426SEnji Cooper static int 246b29e1426SEnji Cooper setup_tcp_client(int domain, int port) 247b29e1426SEnji Cooper { 248b29e1426SEnji Cooper 249b29e1426SEnji Cooper return (setup_client(domain, SOCK_STREAM, port)); 250b29e1426SEnji Cooper } 251b29e1426SEnji Cooper 252b29e1426SEnji Cooper static off_t 253b29e1426SEnji Cooper file_size_from_fd(int fd) 254b29e1426SEnji Cooper { 255b29e1426SEnji Cooper struct stat st; 256b29e1426SEnji Cooper 257b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, fstat(fd, &st), 258b29e1426SEnji Cooper "fstat failed: %s", strerror(errno)); 259b29e1426SEnji Cooper 260b29e1426SEnji Cooper return (st.st_size); 261b29e1426SEnji Cooper } 262b29e1426SEnji Cooper 263b29e1426SEnji Cooper /* 264b29e1426SEnji Cooper * NB: `nbytes` == 0 has special connotations given the sendfile(2) API 265b29e1426SEnji Cooper * contract. In short, "send the whole file" (paraphrased). 266b29e1426SEnji Cooper */ 267b29e1426SEnji Cooper static void 268b29e1426SEnji Cooper verify_source_and_dest(const char* dest_filename, int src_fd, off_t offset, 269b29e1426SEnji Cooper size_t nbytes) 270b29e1426SEnji Cooper { 271de00e09dSEnji Cooper char *dest_pointer, *src_pointer; 272b29e1426SEnji Cooper off_t dest_file_size, src_file_size; 273b29e1426SEnji Cooper size_t length; 274b29e1426SEnji Cooper int dest_fd; 275b29e1426SEnji Cooper 276b29e1426SEnji Cooper atf_utils_cat_file(dest_filename, "dest_file: "); 277b29e1426SEnji Cooper 278b29e1426SEnji Cooper dest_fd = open(dest_filename, O_RDONLY); 279b29e1426SEnji Cooper ATF_REQUIRE_MSG(dest_fd != -1, "open failed"); 280b29e1426SEnji Cooper 281b29e1426SEnji Cooper dest_file_size = file_size_from_fd(dest_fd); 282b29e1426SEnji Cooper src_file_size = file_size_from_fd(src_fd); 283b29e1426SEnji Cooper 284b29e1426SEnji Cooper /* 285b29e1426SEnji Cooper * Per sendfile(2), "send the whole file" (paraphrased). This means 286b29e1426SEnji Cooper * that we need to grab the file size, as passing in length = 0 with 287b29e1426SEnji Cooper * mmap(2) will result in a failure with EINVAL (length = 0 is invalid). 288b29e1426SEnji Cooper */ 289b29e1426SEnji Cooper length = (nbytes == 0) ? (size_t)(src_file_size - offset) : nbytes; 290b29e1426SEnji Cooper 291b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(dest_file_size, length, 292e190da54SEnji Cooper "number of bytes written out to %s (%ju) doesn't match the " 2938dd6af34SEnji Cooper "expected number of bytes (%zu)", dest_filename, dest_file_size, 294b29e1426SEnji Cooper length); 295b29e1426SEnji Cooper 296b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, lseek(src_fd, offset, SEEK_SET), 297b29e1426SEnji Cooper "lseek failed: %s", strerror(errno)); 298b29e1426SEnji Cooper 299b29e1426SEnji Cooper dest_pointer = mmap(NULL, length, PROT_READ, MAP_PRIVATE, dest_fd, 0); 300b29e1426SEnji Cooper ATF_REQUIRE_MSG(dest_pointer != MAP_FAILED, "mmap failed: %s", 301b29e1426SEnji Cooper strerror(errno)); 302b29e1426SEnji Cooper 303b29e1426SEnji Cooper printf("Will mmap in the source file from offset=%jd to length=%zu\n", 304b29e1426SEnji Cooper offset, length); 305b29e1426SEnji Cooper 306b29e1426SEnji Cooper src_pointer = mmap(NULL, length, PROT_READ, MAP_PRIVATE, src_fd, offset); 307b29e1426SEnji Cooper ATF_REQUIRE_MSG(src_pointer != MAP_FAILED, "mmap failed: %s", 308b29e1426SEnji Cooper strerror(errno)); 309b29e1426SEnji Cooper 310b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, memcmp(src_pointer, dest_pointer, length), 311b29e1426SEnji Cooper "Contents of source and destination do not match. '%s' != '%s'", 312b29e1426SEnji Cooper src_pointer, dest_pointer); 313b29e1426SEnji Cooper 314b29e1426SEnji Cooper (void)munmap(src_pointer, length); 315b29e1426SEnji Cooper (void)munmap(dest_pointer, length); 316b29e1426SEnji Cooper (void)close(dest_fd); 317b29e1426SEnji Cooper } 318b29e1426SEnji Cooper 319b29e1426SEnji Cooper static void 320b29e1426SEnji Cooper fd_positive_file_test(int domain) 321b29e1426SEnji Cooper { 322b29e1426SEnji Cooper off_t offset; 323b29e1426SEnji Cooper size_t nbytes, pattern_size; 324b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 325b29e1426SEnji Cooper pid_t server_pid; 326b29e1426SEnji Cooper 327b29e1426SEnji Cooper pattern_size = strlen(DETERMINISTIC_PATTERN); 328b29e1426SEnji Cooper 329b29e1426SEnji Cooper atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); 330b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_RDONLY); 331b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 332b29e1426SEnji Cooper 333b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 334b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 335b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 336b29e1426SEnji Cooper 337b29e1426SEnji Cooper server_pid = atf_utils_fork(); 338b29e1426SEnji Cooper if (server_pid == 0) { 339b29e1426SEnji Cooper (void)close(client_sock); 340b29e1426SEnji Cooper server_cat(DESTINATION_FILE, server_sock, pattern_size); 341b29e1426SEnji Cooper _exit(0); 342b29e1426SEnji Cooper } else 343b29e1426SEnji Cooper (void)close(server_sock); 344b29e1426SEnji Cooper 345b29e1426SEnji Cooper nbytes = 0; 346b29e1426SEnji Cooper offset = 0; 347b29e1426SEnji Cooper error = sendfile(fd, client_sock, offset, nbytes, NULL, NULL, 348b29e1426SEnji Cooper SF_FLAGS(0, 0)); 349b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, error, "sendfile failed: %s", strerror(errno)); 350b29e1426SEnji Cooper (void)close(client_sock); 351b29e1426SEnji Cooper 352b29e1426SEnji Cooper atf_utils_wait(server_pid, 0, "", ""); 353b29e1426SEnji Cooper verify_source_and_dest(DESTINATION_FILE, fd, offset, nbytes); 354b29e1426SEnji Cooper 355b29e1426SEnji Cooper (void)close(fd); 356b29e1426SEnji Cooper } 357b29e1426SEnji Cooper 358b29e1426SEnji Cooper ATF_TC(fd_positive_file_v4); 359b29e1426SEnji Cooper ATF_TC_HEAD(fd_positive_file_v4, tc) 360b29e1426SEnji Cooper { 361b29e1426SEnji Cooper 362b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 363b29e1426SEnji Cooper "Verify regular file as file descriptor support (IPv4)"); 364b29e1426SEnji Cooper } 365b29e1426SEnji Cooper ATF_TC_BODY(fd_positive_file_v4, tc) 366b29e1426SEnji Cooper { 367b29e1426SEnji Cooper 368b29e1426SEnji Cooper fd_positive_file_test(AF_INET); 369b29e1426SEnji Cooper } 370b29e1426SEnji Cooper 371b29e1426SEnji Cooper ATF_TC(fd_positive_file_v6); 372b29e1426SEnji Cooper ATF_TC_HEAD(fd_positive_file_v6, tc) 373b29e1426SEnji Cooper { 374b29e1426SEnji Cooper 375b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 376b29e1426SEnji Cooper "Verify regular file as file descriptor support (IPv6)"); 377b29e1426SEnji Cooper } 378b29e1426SEnji Cooper ATF_TC_BODY(fd_positive_file_v6, tc) 379b29e1426SEnji Cooper { 380b29e1426SEnji Cooper 381b29e1426SEnji Cooper fd_positive_file_test(AF_INET6); 382b29e1426SEnji Cooper } 383b29e1426SEnji Cooper 384b29e1426SEnji Cooper static void 385b29e1426SEnji Cooper fd_positive_shm_test(int domain) 386b29e1426SEnji Cooper { 387de00e09dSEnji Cooper char *shm_pointer; 388b29e1426SEnji Cooper off_t offset; 389b29e1426SEnji Cooper size_t nbytes, pattern_size; 390b29e1426SEnji Cooper pid_t server_pid; 391b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 392b29e1426SEnji Cooper 393b29e1426SEnji Cooper pattern_size = strlen(DETERMINISTIC_PATTERN); 394b29e1426SEnji Cooper 395b29e1426SEnji Cooper printf("pattern size: %zu\n", pattern_size); 396b29e1426SEnji Cooper 397b29e1426SEnji Cooper fd = shm_open(SHM_ANON, O_RDWR|O_CREAT, 0600); 398b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "shm_open failed: %s", strerror(errno)); 399b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, ftruncate(fd, pattern_size), 400b29e1426SEnji Cooper "ftruncate failed: %s", strerror(errno)); 401b29e1426SEnji Cooper shm_pointer = mmap(NULL, pattern_size, PROT_READ|PROT_WRITE, 402b29e1426SEnji Cooper MAP_SHARED, fd, 0); 403b29e1426SEnji Cooper ATF_REQUIRE_MSG(shm_pointer != MAP_FAILED, 404b29e1426SEnji Cooper "mmap failed: %s", strerror(errno)); 405b29e1426SEnji Cooper memcpy(shm_pointer, DETERMINISTIC_PATTERN, pattern_size); 406b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, 407b29e1426SEnji Cooper memcmp(shm_pointer, DETERMINISTIC_PATTERN, pattern_size), 408b29e1426SEnji Cooper "memcmp showed data mismatch: '%s' != '%s'", 409b29e1426SEnji Cooper DETERMINISTIC_PATTERN, shm_pointer); 410b29e1426SEnji Cooper 411b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 412b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 413b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 414b29e1426SEnji Cooper 415b29e1426SEnji Cooper server_pid = atf_utils_fork(); 416b29e1426SEnji Cooper if (server_pid == 0) { 417b29e1426SEnji Cooper (void)close(client_sock); 418b29e1426SEnji Cooper server_cat(DESTINATION_FILE, server_sock, pattern_size); 419b29e1426SEnji Cooper _exit(0); 420b29e1426SEnji Cooper } else 421b29e1426SEnji Cooper (void)close(server_sock); 422b29e1426SEnji Cooper 423b29e1426SEnji Cooper nbytes = 0; 424b29e1426SEnji Cooper offset = 0; 425b29e1426SEnji Cooper error = sendfile(fd, client_sock, offset, nbytes, NULL, NULL, 426b29e1426SEnji Cooper SF_FLAGS(0, 0)); 427b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, error, "sendfile failed: %s", strerror(errno)); 428b29e1426SEnji Cooper (void)close(client_sock); 429b29e1426SEnji Cooper 430b29e1426SEnji Cooper atf_utils_wait(server_pid, 0, "", ""); 431b29e1426SEnji Cooper verify_source_and_dest(DESTINATION_FILE, fd, offset, nbytes); 432b29e1426SEnji Cooper 433b29e1426SEnji Cooper (void)munmap(shm_pointer, sizeof(DETERMINISTIC_PATTERN)); 434b29e1426SEnji Cooper (void)close(fd); 435b29e1426SEnji Cooper } 436b29e1426SEnji Cooper 437b29e1426SEnji Cooper ATF_TC(fd_positive_shm_v4); 438b29e1426SEnji Cooper ATF_TC_HEAD(fd_positive_shm_v4, tc) 439b29e1426SEnji Cooper { 440b29e1426SEnji Cooper 441b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 442b29e1426SEnji Cooper "Verify shared memory as file descriptor support (IPv4)"); 443b29e1426SEnji Cooper } 444b29e1426SEnji Cooper ATF_TC_BODY(fd_positive_shm_v4, tc) 445b29e1426SEnji Cooper { 446b29e1426SEnji Cooper 447b29e1426SEnji Cooper fd_positive_shm_test(AF_INET); 448b29e1426SEnji Cooper } 449b29e1426SEnji Cooper 450b29e1426SEnji Cooper ATF_TC(fd_positive_shm_v6); 451b29e1426SEnji Cooper ATF_TC_HEAD(fd_positive_shm_v6, tc) 452b29e1426SEnji Cooper { 453b29e1426SEnji Cooper 454b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 455b29e1426SEnji Cooper "Verify shared memory as file descriptor support (IPv6))"); 456b29e1426SEnji Cooper } 457b29e1426SEnji Cooper ATF_TC_BODY(fd_positive_shm_v6, tc) 458b29e1426SEnji Cooper { 459b29e1426SEnji Cooper 460b29e1426SEnji Cooper fd_positive_shm_test(AF_INET6); 461b29e1426SEnji Cooper } 462b29e1426SEnji Cooper 463b29e1426SEnji Cooper static void 464b29e1426SEnji Cooper fd_negative_bad_fd_test(int domain) 465b29e1426SEnji Cooper { 466b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 467b29e1426SEnji Cooper 468b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 469b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 470b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 471b29e1426SEnji Cooper 472b29e1426SEnji Cooper fd = -1; 473b29e1426SEnji Cooper 474b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, NULL, SF_FLAGS(0, 0)); 475b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, error == -1); 476b29e1426SEnji Cooper 477b29e1426SEnji Cooper (void)close(client_sock); 478b29e1426SEnji Cooper (void)close(server_sock); 479b29e1426SEnji Cooper } 480b29e1426SEnji Cooper 481b29e1426SEnji Cooper ATF_TC(fd_negative_bad_fd_v4); 482b29e1426SEnji Cooper ATF_TC_HEAD(fd_negative_bad_fd_v4, tc) 483b29e1426SEnji Cooper { 484b29e1426SEnji Cooper 485b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 486b29e1426SEnji Cooper "Verify bad file descriptor returns EBADF (IPv4)"); 487b29e1426SEnji Cooper } 488b29e1426SEnji Cooper ATF_TC_BODY(fd_negative_bad_fd_v4, tc) 489b29e1426SEnji Cooper { 490b29e1426SEnji Cooper 491b29e1426SEnji Cooper fd_negative_bad_fd_test(AF_INET); 492b29e1426SEnji Cooper } 493b29e1426SEnji Cooper 494b29e1426SEnji Cooper ATF_TC(fd_negative_bad_fd_v6); 495b29e1426SEnji Cooper ATF_TC_HEAD(fd_negative_bad_fd_v6, tc) 496b29e1426SEnji Cooper { 497b29e1426SEnji Cooper 498b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 499b29e1426SEnji Cooper "Verify bad file descriptor returns EBADF (IPv6)"); 500b29e1426SEnji Cooper } 501b29e1426SEnji Cooper ATF_TC_BODY(fd_negative_bad_fd_v6, tc) 502b29e1426SEnji Cooper { 503b29e1426SEnji Cooper 504b29e1426SEnji Cooper fd_negative_bad_fd_test(AF_INET6); 505b29e1426SEnji Cooper } 506b29e1426SEnji Cooper 507b29e1426SEnji Cooper static void 508b29e1426SEnji Cooper flags_test(int domain) 509b29e1426SEnji Cooper { 510b29e1426SEnji Cooper off_t offset; 511b29e1426SEnji Cooper size_t nbytes, pattern_size; 512b29e1426SEnji Cooper int client_sock, error, fd, i, port, server_sock; 513b29e1426SEnji Cooper pid_t server_pid; 514b29e1426SEnji Cooper int16_t number_pages = 10; 515b29e1426SEnji Cooper 516b29e1426SEnji Cooper pattern_size = strlen(DETERMINISTIC_PATTERN); 517b29e1426SEnji Cooper 518b29e1426SEnji Cooper struct testcase { 519b29e1426SEnji Cooper int16_t readahead_pages, flags; 520b29e1426SEnji Cooper } testcases[] = { 521b29e1426SEnji Cooper /* This is covered in `:fd_positive_file` */ 522b29e1426SEnji Cooper #if 0 523b29e1426SEnji Cooper { 524b29e1426SEnji Cooper .readahead_pages = 0, 525b29e1426SEnji Cooper .flags = 0 526b29e1426SEnji Cooper }, 527b29e1426SEnji Cooper #endif 528b29e1426SEnji Cooper { 529b29e1426SEnji Cooper .readahead_pages = 0, 530b29e1426SEnji Cooper .flags = SF_NOCACHE 531b29e1426SEnji Cooper }, 532b29e1426SEnji Cooper #ifdef SF_USER_READAHEAD 533b29e1426SEnji Cooper { 534b29e1426SEnji Cooper .readahead_pages = 0, 535b29e1426SEnji Cooper .flags = SF_NOCACHE|SF_USER_READAHEAD 536b29e1426SEnji Cooper }, 537b29e1426SEnji Cooper { 538b29e1426SEnji Cooper .readahead_pages = 0, 539b29e1426SEnji Cooper .flags = SF_USER_READAHEAD 540b29e1426SEnji Cooper }, 541b29e1426SEnji Cooper #endif 542b29e1426SEnji Cooper { 543b29e1426SEnji Cooper .readahead_pages = number_pages, 544b29e1426SEnji Cooper .flags = 0 545b29e1426SEnji Cooper }, 546b29e1426SEnji Cooper { 547b29e1426SEnji Cooper .readahead_pages = number_pages, 548b29e1426SEnji Cooper .flags = SF_NOCACHE 549b29e1426SEnji Cooper }, 550b29e1426SEnji Cooper #ifdef SF_USER_READAHEAD 551b29e1426SEnji Cooper { 552b29e1426SEnji Cooper .readahead_pages = number_pages, 553b29e1426SEnji Cooper .flags = SF_NOCACHE|SF_USER_READAHEAD 554b29e1426SEnji Cooper }, 555b29e1426SEnji Cooper #endif 556b29e1426SEnji Cooper { 557b29e1426SEnji Cooper .readahead_pages = number_pages, 558b29e1426SEnji Cooper .flags = SF_NOCACHE 559b29e1426SEnji Cooper }, 560b29e1426SEnji Cooper { 561b29e1426SEnji Cooper .readahead_pages = number_pages, 562b29e1426SEnji Cooper .flags = SF_NODISKIO 563b29e1426SEnji Cooper } 564b29e1426SEnji Cooper }; 565b29e1426SEnji Cooper 566b29e1426SEnji Cooper atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); 567b29e1426SEnji Cooper for (i = 0; i < nitems(testcases); i++) { 568b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_RDONLY); 569b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 570b29e1426SEnji Cooper 571b29e1426SEnji Cooper port = generate_random_port(i * __LINE__ + domain); 572b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 573b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 574b29e1426SEnji Cooper 575b29e1426SEnji Cooper server_pid = atf_utils_fork(); 576b29e1426SEnji Cooper if (server_pid == 0) { 577b29e1426SEnji Cooper (void)close(client_sock); 578b29e1426SEnji Cooper server_cat(DESTINATION_FILE, server_sock, pattern_size); 579b29e1426SEnji Cooper _exit(0); 580b29e1426SEnji Cooper } else 581b29e1426SEnji Cooper (void)close(server_sock); 582b29e1426SEnji Cooper 583b29e1426SEnji Cooper nbytes = 0; 584b29e1426SEnji Cooper offset = 0; 585b29e1426SEnji Cooper error = sendfile(fd, client_sock, offset, nbytes, NULL, NULL, 586b29e1426SEnji Cooper SF_FLAGS(testcases[i].readahead_pages, testcases[i].flags)); 587b29e1426SEnji Cooper ATF_CHECK_EQ_MSG(error, 0, "sendfile testcase #%d failed: %s", 588b29e1426SEnji Cooper i, strerror(errno)); 589b29e1426SEnji Cooper (void)close(client_sock); 590b29e1426SEnji Cooper 591b29e1426SEnji Cooper atf_utils_wait(server_pid, 0, "", ""); 592b29e1426SEnji Cooper verify_source_and_dest(DESTINATION_FILE, fd, offset, nbytes); 593b29e1426SEnji Cooper 594b29e1426SEnji Cooper (void)close(fd); 595b29e1426SEnji Cooper } 596b29e1426SEnji Cooper } 597b29e1426SEnji Cooper 598b29e1426SEnji Cooper ATF_TC(flags_v4); 599b29e1426SEnji Cooper ATF_TC_HEAD(flags_v4, tc) 600b29e1426SEnji Cooper { 601b29e1426SEnji Cooper 602b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", "Verify flags functionality (IPv4)"); 603b29e1426SEnji Cooper } 604b29e1426SEnji Cooper ATF_TC_BODY(flags_v4, tc) 605b29e1426SEnji Cooper { 606b29e1426SEnji Cooper 607b29e1426SEnji Cooper flags_test(AF_INET); 608b29e1426SEnji Cooper } 609b29e1426SEnji Cooper 610b29e1426SEnji Cooper ATF_TC(flags_v6); 611b29e1426SEnji Cooper ATF_TC_HEAD(flags_v6, tc) 612b29e1426SEnji Cooper { 613b29e1426SEnji Cooper 614b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", "Verify flags functionality (IPv6)"); 615b29e1426SEnji Cooper } 616b29e1426SEnji Cooper ATF_TC_BODY(flags_v6, tc) 617b29e1426SEnji Cooper { 618b29e1426SEnji Cooper 619b29e1426SEnji Cooper flags_test(AF_INET6); 620b29e1426SEnji Cooper } 621b29e1426SEnji Cooper 622b29e1426SEnji Cooper static void 623b29e1426SEnji Cooper hdtr_positive_test(int domain) 624b29e1426SEnji Cooper { 625b29e1426SEnji Cooper struct iovec headers[1], trailers[1]; 626b29e1426SEnji Cooper struct testcase { 627b29e1426SEnji Cooper bool include_headers, include_trailers; 628b29e1426SEnji Cooper } testcases[] = { 629b29e1426SEnji Cooper /* This is covered in `:fd_positive_file` */ 630b29e1426SEnji Cooper #if 0 631b29e1426SEnji Cooper { 632b29e1426SEnji Cooper .include_headers = false, 633b29e1426SEnji Cooper .include_trailers = false 634b29e1426SEnji Cooper }, 635b29e1426SEnji Cooper #endif 636b29e1426SEnji Cooper { 637b29e1426SEnji Cooper .include_headers = true, 638b29e1426SEnji Cooper .include_trailers = false 639b29e1426SEnji Cooper }, 640b29e1426SEnji Cooper { 641b29e1426SEnji Cooper .include_headers = false, 642b29e1426SEnji Cooper .include_trailers = true 643b29e1426SEnji Cooper }, 644b29e1426SEnji Cooper { 645b29e1426SEnji Cooper .include_headers = true, 646b29e1426SEnji Cooper .include_trailers = true 647b29e1426SEnji Cooper } 648b29e1426SEnji Cooper }; 649b29e1426SEnji Cooper off_t offset; 650b29e1426SEnji Cooper size_t nbytes; 651b29e1426SEnji Cooper int client_sock, error, fd, fd2, i, port, rc, server_sock; 652b29e1426SEnji Cooper pid_t server_pid; 653b29e1426SEnji Cooper 654b29e1426SEnji Cooper headers[0].iov_base = "This is a header"; 655b29e1426SEnji Cooper headers[0].iov_len = strlen(headers[0].iov_base); 656b29e1426SEnji Cooper trailers[0].iov_base = "This is a trailer"; 657b29e1426SEnji Cooper trailers[0].iov_len = strlen(trailers[0].iov_base); 658b29e1426SEnji Cooper offset = 0; 659b29e1426SEnji Cooper nbytes = 0; 660b29e1426SEnji Cooper 661b29e1426SEnji Cooper atf_tc_expect_fail( 662b29e1426SEnji Cooper "The header/trailer testcases fail today with a data mismatch; " 663b29e1426SEnji Cooper "bug # 234809"); 664b29e1426SEnji Cooper 665b29e1426SEnji Cooper for (i = 0; i < nitems(testcases); i++) { 666b29e1426SEnji Cooper struct sf_hdtr hdtr; 667b29e1426SEnji Cooper char *pattern; 668b29e1426SEnji Cooper 669b29e1426SEnji Cooper if (testcases[i].include_headers) { 670b29e1426SEnji Cooper hdtr.headers = headers; 671b29e1426SEnji Cooper hdtr.hdr_cnt = nitems(headers); 672b29e1426SEnji Cooper } else { 673b29e1426SEnji Cooper hdtr.headers = NULL; 674b29e1426SEnji Cooper hdtr.hdr_cnt = 0; 675b29e1426SEnji Cooper } 676b29e1426SEnji Cooper 677b29e1426SEnji Cooper if (testcases[i].include_trailers) { 678b29e1426SEnji Cooper hdtr.trailers = trailers; 679b29e1426SEnji Cooper hdtr.trl_cnt = nitems(trailers); 680b29e1426SEnji Cooper } else { 681b29e1426SEnji Cooper hdtr.trailers = NULL; 682b29e1426SEnji Cooper hdtr.trl_cnt = 0; 683b29e1426SEnji Cooper } 684b29e1426SEnji Cooper 685b29e1426SEnji Cooper port = generate_random_port(i * __LINE__ + domain); 686b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 687b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 688b29e1426SEnji Cooper 689b29e1426SEnji Cooper rc = asprintf(&pattern, "%s%s%s", 690de00e09dSEnji Cooper testcases[i].include_headers ? (char *)headers[0].iov_base : "", 691b29e1426SEnji Cooper DETERMINISTIC_PATTERN, 692de00e09dSEnji Cooper testcases[i].include_trailers ? (char *)trailers[0].iov_base : ""); 693b29e1426SEnji Cooper ATF_REQUIRE_MSG(rc != -1, "asprintf failed: %s", strerror(errno)); 694b29e1426SEnji Cooper 695b29e1426SEnji Cooper atf_utils_create_file(SOURCE_FILE ".full", "%s", pattern); 696b29e1426SEnji Cooper atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); 697b29e1426SEnji Cooper 698b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_RDONLY); 699b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 700b29e1426SEnji Cooper 701b29e1426SEnji Cooper fd2 = open(SOURCE_FILE ".full", O_RDONLY); 702b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd2 != -1, "open failed: %s", strerror(errno)); 703b29e1426SEnji Cooper 704b29e1426SEnji Cooper server_pid = atf_utils_fork(); 705b29e1426SEnji Cooper if (server_pid == 0) { 706b29e1426SEnji Cooper (void)close(client_sock); 707b29e1426SEnji Cooper server_cat(DESTINATION_FILE, server_sock, 708b29e1426SEnji Cooper strlen(pattern)); 709b29e1426SEnji Cooper _exit(0); 710b29e1426SEnji Cooper } else 711b29e1426SEnji Cooper (void)close(server_sock); 712b29e1426SEnji Cooper 713b29e1426SEnji Cooper error = sendfile(fd, client_sock, offset, nbytes, &hdtr, 714b29e1426SEnji Cooper NULL, SF_FLAGS(0, 0)); 715b29e1426SEnji Cooper ATF_CHECK_EQ_MSG(error, 0, "sendfile testcase #%d failed: %s", 716b29e1426SEnji Cooper i, strerror(errno)); 717b29e1426SEnji Cooper (void)close(client_sock); 718b29e1426SEnji Cooper 719b29e1426SEnji Cooper atf_utils_wait(server_pid, 0, "", ""); 720b29e1426SEnji Cooper verify_source_and_dest(DESTINATION_FILE, fd2, offset, nbytes); 721b29e1426SEnji Cooper 722b29e1426SEnji Cooper (void)close(fd); 723b29e1426SEnji Cooper (void)close(fd2); 724b29e1426SEnji Cooper free(pattern); 725b29e1426SEnji Cooper pattern = NULL; 726b29e1426SEnji Cooper } 727b29e1426SEnji Cooper } 728b29e1426SEnji Cooper 729b29e1426SEnji Cooper ATF_TC(hdtr_positive_v4); 730b29e1426SEnji Cooper ATF_TC_HEAD(hdtr_positive_v4, tc) 731b29e1426SEnji Cooper { 732b29e1426SEnji Cooper 733b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 734b29e1426SEnji Cooper "Verify positive hdtr functionality (IPv4)"); 735b29e1426SEnji Cooper } 736b29e1426SEnji Cooper ATF_TC_BODY(hdtr_positive_v4, tc) 737b29e1426SEnji Cooper { 738b29e1426SEnji Cooper 739b29e1426SEnji Cooper hdtr_positive_test(AF_INET); 740b29e1426SEnji Cooper } 741b29e1426SEnji Cooper 742b29e1426SEnji Cooper ATF_TC(hdtr_positive_v6); 743b29e1426SEnji Cooper ATF_TC_HEAD(hdtr_positive_v6, tc) 744b29e1426SEnji Cooper { 745b29e1426SEnji Cooper 746b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 747b29e1426SEnji Cooper "Verify positive hdtr functionality (IPv6)"); 748b29e1426SEnji Cooper } 749b29e1426SEnji Cooper ATF_TC_BODY(hdtr_positive_v6, tc) 750b29e1426SEnji Cooper { 751b29e1426SEnji Cooper 752b29e1426SEnji Cooper hdtr_positive_test(AF_INET); 753b29e1426SEnji Cooper } 754b29e1426SEnji Cooper 755b29e1426SEnji Cooper static void 756b29e1426SEnji Cooper hdtr_negative_bad_pointers_test(int domain) 757b29e1426SEnji Cooper { 758b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 759b29e1426SEnji Cooper struct sf_hdtr *hdtr1, hdtr2, hdtr3; 760b29e1426SEnji Cooper 761b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 762b29e1426SEnji Cooper 763b29e1426SEnji Cooper hdtr1 = (struct sf_hdtr*)-1; 764b29e1426SEnji Cooper 765b29e1426SEnji Cooper memset(&hdtr2, 0, sizeof(hdtr2)); 766b29e1426SEnji Cooper hdtr2.hdr_cnt = 1; 767b29e1426SEnji Cooper hdtr2.headers = (struct iovec*)-1; 768b29e1426SEnji Cooper 769b29e1426SEnji Cooper memset(&hdtr3, 0, sizeof(hdtr3)); 770b29e1426SEnji Cooper hdtr3.trl_cnt = 1; 771b29e1426SEnji Cooper hdtr3.trailers = (struct iovec*)-1; 772b29e1426SEnji Cooper 773b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_CREAT|O_RDWR); 774b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 775b29e1426SEnji Cooper 776b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 777b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 778b29e1426SEnji Cooper 779b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, hdtr1, NULL, SF_FLAGS(0, 0)); 780b29e1426SEnji Cooper ATF_CHECK_ERRNO(EFAULT, error == -1); 781b29e1426SEnji Cooper 782b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, &hdtr2, NULL, SF_FLAGS(0, 0)); 783b29e1426SEnji Cooper ATF_CHECK_ERRNO(EFAULT, error == -1); 784b29e1426SEnji Cooper 785b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, &hdtr3, NULL, SF_FLAGS(0, 0)); 786b29e1426SEnji Cooper ATF_CHECK_ERRNO(EFAULT, error == -1); 787b29e1426SEnji Cooper 788b29e1426SEnji Cooper (void)close(fd); 789b29e1426SEnji Cooper (void)close(client_sock); 790b29e1426SEnji Cooper (void)close(server_sock); 791b29e1426SEnji Cooper } 792b29e1426SEnji Cooper 793b29e1426SEnji Cooper ATF_TC(hdtr_negative_bad_pointers_v4); 794b29e1426SEnji Cooper ATF_TC_HEAD(hdtr_negative_bad_pointers_v4, tc) 795b29e1426SEnji Cooper { 796b29e1426SEnji Cooper 797b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 798b29e1426SEnji Cooper "Verify that bad pointers for hdtr storage result in EFAULT (IPv4)"); 799b29e1426SEnji Cooper } 800b29e1426SEnji Cooper ATF_TC_BODY(hdtr_negative_bad_pointers_v4, tc) 801b29e1426SEnji Cooper { 802b29e1426SEnji Cooper 803b29e1426SEnji Cooper hdtr_negative_bad_pointers_test(AF_INET); 804b29e1426SEnji Cooper } 805b29e1426SEnji Cooper 806b29e1426SEnji Cooper ATF_TC(hdtr_negative_bad_pointers_v6); 807b29e1426SEnji Cooper ATF_TC_HEAD(hdtr_negative_bad_pointers_v6, tc) 808b29e1426SEnji Cooper { 809b29e1426SEnji Cooper 810b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 811b29e1426SEnji Cooper "Verify that bad pointers for hdtr storage result in EFAULT (IPv6)"); 812b29e1426SEnji Cooper } 813b29e1426SEnji Cooper ATF_TC_BODY(hdtr_negative_bad_pointers_v6, tc) 814b29e1426SEnji Cooper { 815b29e1426SEnji Cooper 816b29e1426SEnji Cooper hdtr_negative_bad_pointers_test(AF_INET6); 817b29e1426SEnji Cooper } 818b29e1426SEnji Cooper 819b29e1426SEnji Cooper static void 820b29e1426SEnji Cooper offset_negative_value_less_than_zero_test(int domain) 821b29e1426SEnji Cooper { 822b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 823b29e1426SEnji Cooper 824b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 825b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 826b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 827b29e1426SEnji Cooper 828b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_CREAT|O_RDWR); 829b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 830b29e1426SEnji Cooper 831b29e1426SEnji Cooper error = sendfile(fd, client_sock, -1, 0, NULL, NULL, SF_FLAGS(0, 0)); 832b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(EINVAL, error == -1); 833b29e1426SEnji Cooper 834b29e1426SEnji Cooper (void)close(fd); 835b29e1426SEnji Cooper (void)close(client_sock); 836b29e1426SEnji Cooper (void)close(server_sock); 837b29e1426SEnji Cooper } 838b29e1426SEnji Cooper 839b29e1426SEnji Cooper ATF_TC(offset_negative_value_less_than_zero_v4); 840b29e1426SEnji Cooper ATF_TC_HEAD(offset_negative_value_less_than_zero_v4, tc) 841b29e1426SEnji Cooper { 842b29e1426SEnji Cooper 843b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 844b29e1426SEnji Cooper "Verify that a negative offset results in EINVAL (IPv4)"); 845b29e1426SEnji Cooper } 846b29e1426SEnji Cooper ATF_TC_BODY(offset_negative_value_less_than_zero_v4, tc) 847b29e1426SEnji Cooper { 848b29e1426SEnji Cooper 849b29e1426SEnji Cooper offset_negative_value_less_than_zero_test(AF_INET); 850b29e1426SEnji Cooper } 851b29e1426SEnji Cooper 852b29e1426SEnji Cooper ATF_TC(offset_negative_value_less_than_zero_v6); 853b29e1426SEnji Cooper ATF_TC_HEAD(offset_negative_value_less_than_zero_v6, tc) 854b29e1426SEnji Cooper { 855b29e1426SEnji Cooper 856b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 857b29e1426SEnji Cooper "Verify that a negative offset results in EINVAL (IPv6)"); 858b29e1426SEnji Cooper } 859b29e1426SEnji Cooper ATF_TC_BODY(offset_negative_value_less_than_zero_v6, tc) 860b29e1426SEnji Cooper { 861b29e1426SEnji Cooper 862b29e1426SEnji Cooper offset_negative_value_less_than_zero_test(AF_INET6); 863b29e1426SEnji Cooper } 864b29e1426SEnji Cooper 865b29e1426SEnji Cooper static void 866b29e1426SEnji Cooper sbytes_positive_test(int domain) 867b29e1426SEnji Cooper { 868b29e1426SEnji Cooper size_t pattern_size = strlen(DETERMINISTIC_PATTERN); 869b29e1426SEnji Cooper off_t sbytes; 870b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 871b29e1426SEnji Cooper 872b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 873b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 874b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 875b29e1426SEnji Cooper 876b29e1426SEnji Cooper atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); 877b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_RDONLY); 878b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 879b29e1426SEnji Cooper 880b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, &sbytes, SF_FLAGS(0, 0)); 881b29e1426SEnji Cooper ATF_CHECK_EQ_MSG(error, 0, "sendfile failed: %s", strerror(errno)); 882b29e1426SEnji Cooper 883b29e1426SEnji Cooper (void)close(fd); 884b29e1426SEnji Cooper (void)close(client_sock); 885b29e1426SEnji Cooper (void)close(server_sock); 886b29e1426SEnji Cooper 887b29e1426SEnji Cooper ATF_CHECK_EQ_MSG(pattern_size, sbytes, 888b29e1426SEnji Cooper "the value returned by sbytes does not match the expected pattern " 889b29e1426SEnji Cooper "size"); 890b29e1426SEnji Cooper } 891b29e1426SEnji Cooper 892b29e1426SEnji Cooper ATF_TC(sbytes_positive_v4); 893b29e1426SEnji Cooper ATF_TC_HEAD(sbytes_positive_v4, tc) 894b29e1426SEnji Cooper { 895b29e1426SEnji Cooper 896b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 897b29e1426SEnji Cooper "Verify positive `sbytes` functionality (IPv4)"); 898b29e1426SEnji Cooper } 899b29e1426SEnji Cooper ATF_TC_BODY(sbytes_positive_v4, tc) 900b29e1426SEnji Cooper { 901b29e1426SEnji Cooper 902b29e1426SEnji Cooper sbytes_positive_test(AF_INET); 903b29e1426SEnji Cooper } 904b29e1426SEnji Cooper 905b29e1426SEnji Cooper ATF_TC(sbytes_positive_v6); 906b29e1426SEnji Cooper ATF_TC_HEAD(sbytes_positive_v6, tc) 907b29e1426SEnji Cooper { 908b29e1426SEnji Cooper 909b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 910b29e1426SEnji Cooper "Verify positive `sbytes` functionality (IPv6)"); 911b29e1426SEnji Cooper } 912b29e1426SEnji Cooper ATF_TC_BODY(sbytes_positive_v6, tc) 913b29e1426SEnji Cooper { 914b29e1426SEnji Cooper 915b29e1426SEnji Cooper sbytes_positive_test(AF_INET6); 916b29e1426SEnji Cooper } 917b29e1426SEnji Cooper 918b29e1426SEnji Cooper static void 919b29e1426SEnji Cooper sbytes_negative_test(int domain) 920b29e1426SEnji Cooper { 921b29e1426SEnji Cooper off_t *sbytes_p = (off_t*)-1; 922b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 923b29e1426SEnji Cooper 924b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 925b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 926b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 927b29e1426SEnji Cooper 928b29e1426SEnji Cooper atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); 929b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_RDONLY); 930b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 931b29e1426SEnji Cooper 932b29e1426SEnji Cooper atf_tc_expect_fail( 933b29e1426SEnji Cooper "bug 232210: EFAULT assert fails because copyout(9) call is not checked"); 934b29e1426SEnji Cooper 935b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, sbytes_p, SF_FLAGS(0, 0)); 936b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(EFAULT, error == -1); 937b29e1426SEnji Cooper 938b29e1426SEnji Cooper (void)close(fd); 939b29e1426SEnji Cooper (void)close(client_sock); 940b29e1426SEnji Cooper (void)close(server_sock); 941b29e1426SEnji Cooper } 942b29e1426SEnji Cooper 943b29e1426SEnji Cooper ATF_TC(sbytes_negative_v4); 944b29e1426SEnji Cooper ATF_TC_HEAD(sbytes_negative_v4, tc) 945b29e1426SEnji Cooper { 946b29e1426SEnji Cooper 947b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 948b29e1426SEnji Cooper "Verify negative `sbytes` functionality (IPv4)"); 949b29e1426SEnji Cooper } 950b29e1426SEnji Cooper ATF_TC_BODY(sbytes_negative_v4, tc) 951b29e1426SEnji Cooper { 952b29e1426SEnji Cooper 953b29e1426SEnji Cooper sbytes_negative_test(AF_INET); 954b29e1426SEnji Cooper } 955b29e1426SEnji Cooper 956b29e1426SEnji Cooper ATF_TC(sbytes_negative_v6); 957b29e1426SEnji Cooper ATF_TC_HEAD(sbytes_negative_v6, tc) 958b29e1426SEnji Cooper { 959b29e1426SEnji Cooper 960b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 961b29e1426SEnji Cooper "Verify negative `sbytes` functionality (IPv6)"); 962b29e1426SEnji Cooper } 963b29e1426SEnji Cooper ATF_TC_BODY(sbytes_negative_v6, tc) 964b29e1426SEnji Cooper { 965b29e1426SEnji Cooper 966b29e1426SEnji Cooper sbytes_negative_test(AF_INET6); 967b29e1426SEnji Cooper } 968b29e1426SEnji Cooper 969b29e1426SEnji Cooper static void 970b29e1426SEnji Cooper s_negative_not_connected_socket_test(int domain) 971b29e1426SEnji Cooper { 972b29e1426SEnji Cooper int client_sock, error, fd, port; 973b29e1426SEnji Cooper 974b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 975b29e1426SEnji Cooper client_sock = setup_tcp_server(domain, port); 976b29e1426SEnji Cooper 977b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_CREAT|O_RDWR); 978b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 979b29e1426SEnji Cooper 980b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, NULL, SF_FLAGS(0, 0)); 981b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(ENOTCONN, error == -1); 982b29e1426SEnji Cooper 983b29e1426SEnji Cooper (void)close(fd); 984b29e1426SEnji Cooper (void)close(client_sock); 985b29e1426SEnji Cooper } 986b29e1426SEnji Cooper 987b29e1426SEnji Cooper ATF_TC(s_negative_not_connected_socket_v4); 988b29e1426SEnji Cooper ATF_TC_HEAD(s_negative_not_connected_socket_v4, tc) 989b29e1426SEnji Cooper { 990b29e1426SEnji Cooper 991b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 992b29e1426SEnji Cooper "Verify that a non-connected SOCK_STREAM socket results in ENOTCONN (IPv4)"); 993b29e1426SEnji Cooper } 994b29e1426SEnji Cooper 995b29e1426SEnji Cooper ATF_TC_BODY(s_negative_not_connected_socket_v4, tc) 996b29e1426SEnji Cooper { 997b29e1426SEnji Cooper 998b29e1426SEnji Cooper s_negative_not_connected_socket_test(AF_INET); 999b29e1426SEnji Cooper } 1000b29e1426SEnji Cooper 1001b29e1426SEnji Cooper ATF_TC(s_negative_not_connected_socket_v6); 1002b29e1426SEnji Cooper ATF_TC_HEAD(s_negative_not_connected_socket_v6, tc) 1003b29e1426SEnji Cooper { 1004b29e1426SEnji Cooper 1005b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 1006b29e1426SEnji Cooper "Verify that a non-connected SOCK_STREAM socket results in ENOTCONN (IPv6)"); 1007b29e1426SEnji Cooper } 1008b29e1426SEnji Cooper 1009b29e1426SEnji Cooper ATF_TC_BODY(s_negative_not_connected_socket_v6, tc) 1010b29e1426SEnji Cooper { 1011b29e1426SEnji Cooper 1012b29e1426SEnji Cooper s_negative_not_connected_socket_test(AF_INET6); 1013b29e1426SEnji Cooper } 1014b29e1426SEnji Cooper 1015b29e1426SEnji Cooper ATF_TC(s_negative_not_descriptor); 1016b29e1426SEnji Cooper ATF_TC_HEAD(s_negative_not_descriptor, tc) 1017b29e1426SEnji Cooper { 1018b29e1426SEnji Cooper 1019b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 1020b29e1426SEnji Cooper "Verify that an invalid file descriptor, e.g., -1, fails with EBADF"); 1021b29e1426SEnji Cooper } 1022b29e1426SEnji Cooper 1023b29e1426SEnji Cooper ATF_TC_BODY(s_negative_not_descriptor, tc) 1024b29e1426SEnji Cooper { 1025b29e1426SEnji Cooper int client_sock, error, fd; 1026b29e1426SEnji Cooper 1027b29e1426SEnji Cooper client_sock = -1; 1028b29e1426SEnji Cooper 1029b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_CREAT|O_RDWR); 1030b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 1031b29e1426SEnji Cooper 1032b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, NULL, SF_FLAGS(0, 0)); 1033b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, error == -1); 1034b29e1426SEnji Cooper 1035b29e1426SEnji Cooper (void)close(fd); 1036b29e1426SEnji Cooper } 1037b29e1426SEnji Cooper 1038b29e1426SEnji Cooper ATF_TC(s_negative_not_socket_file_descriptor); 1039b29e1426SEnji Cooper ATF_TC_HEAD(s_negative_not_socket_file_descriptor, tc) 1040b29e1426SEnji Cooper { 1041b29e1426SEnji Cooper 1042b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 1043b29e1426SEnji Cooper "Verify that a non-socket file descriptor fails with ENOTSOCK"); 1044b29e1426SEnji Cooper } 1045b29e1426SEnji Cooper 1046b29e1426SEnji Cooper ATF_TC_BODY(s_negative_not_socket_file_descriptor, tc) 1047b29e1426SEnji Cooper { 1048b29e1426SEnji Cooper int client_sock, error, fd; 1049b29e1426SEnji Cooper 1050b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_CREAT|O_RDWR); 1051b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 1052b29e1426SEnji Cooper 1053b29e1426SEnji Cooper client_sock = open(_PATH_DEVNULL, O_WRONLY); 1054b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 1055b29e1426SEnji Cooper 1056b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, NULL, SF_FLAGS(0, 0)); 1057b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(ENOTSOCK, error == -1); 1058b29e1426SEnji Cooper 1059b29e1426SEnji Cooper (void)close(fd); 1060b29e1426SEnji Cooper (void)close(client_sock); 1061b29e1426SEnji Cooper } 1062b29e1426SEnji Cooper 1063b29e1426SEnji Cooper static void 1064b29e1426SEnji Cooper s_negative_udp_socket_test(int domain) 1065b29e1426SEnji Cooper { 1066b29e1426SEnji Cooper int client_sock, error, fd, port; 1067b29e1426SEnji Cooper 1068b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 1069b29e1426SEnji Cooper client_sock = setup_client(domain, SOCK_DGRAM, port); 1070b29e1426SEnji Cooper 1071b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_CREAT|O_RDWR); 1072b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 1073b29e1426SEnji Cooper 1074b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, NULL, SF_FLAGS(0, 0)); 1075b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(EINVAL, error == -1); 1076b29e1426SEnji Cooper 1077b29e1426SEnji Cooper (void)close(fd); 1078b29e1426SEnji Cooper (void)close(client_sock); 1079b29e1426SEnji Cooper } 1080b29e1426SEnji Cooper 1081b29e1426SEnji Cooper ATF_TC(s_negative_udp_socket_v4); 1082b29e1426SEnji Cooper ATF_TC_HEAD(s_negative_udp_socket_v4, tc) 1083b29e1426SEnji Cooper { 1084b29e1426SEnji Cooper 1085b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 1086b29e1426SEnji Cooper "Verify that a non-SOCK_STREAM type socket results in EINVAL (IPv4)"); 1087b29e1426SEnji Cooper } 1088b29e1426SEnji Cooper ATF_TC_BODY(s_negative_udp_socket_v4, tc) 1089b29e1426SEnji Cooper { 1090b29e1426SEnji Cooper 1091b29e1426SEnji Cooper s_negative_udp_socket_test(AF_INET); 1092b29e1426SEnji Cooper } 1093b29e1426SEnji Cooper 1094b29e1426SEnji Cooper ATF_TC(s_negative_udp_socket_v6); 1095b29e1426SEnji Cooper ATF_TC_HEAD(s_negative_udp_socket_v6, tc) 1096b29e1426SEnji Cooper { 1097b29e1426SEnji Cooper 1098b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 1099b29e1426SEnji Cooper "Verify that a non-SOCK_STREAM type socket results in EINVAL (IPv6)"); 1100b29e1426SEnji Cooper } 1101b29e1426SEnji Cooper ATF_TC_BODY(s_negative_udp_socket_v6, tc) 1102b29e1426SEnji Cooper { 1103b29e1426SEnji Cooper 1104b29e1426SEnji Cooper s_negative_udp_socket_test(AF_INET6); 1105b29e1426SEnji Cooper } 1106b29e1426SEnji Cooper 1107b29e1426SEnji Cooper ATF_TP_ADD_TCS(tp) 1108b29e1426SEnji Cooper { 1109b29e1426SEnji Cooper 1110b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, fd_positive_file_v4); 1111b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, fd_positive_file_v6); 1112b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, fd_positive_shm_v4); 1113b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, fd_positive_shm_v6); 1114b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, fd_negative_bad_fd_v4); 1115b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, fd_negative_bad_fd_v6); 1116b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, flags_v4); 1117b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, flags_v6); 1118b29e1426SEnji Cooper /* 1119b29e1426SEnji Cooper * TODO: the negative case for SF_NODISKIO (returns EBUSY if file in 1120b29e1426SEnji Cooper * use) is not covered yet. 1121b29e1426SEnji Cooper * 1122b29e1426SEnji Cooper * Need to lock a file in a subprocess in write mode, then try and 1123b29e1426SEnji Cooper * send the data in read mode with sendfile. 1124b29e1426SEnji Cooper * 1125b29e1426SEnji Cooper * This should work with FFS/UFS, but there are no guarantees about 1126b29e1426SEnji Cooper * other filesystem implementations of sendfile(2), e.g., ZFS. 1127b29e1426SEnji Cooper */ 1128b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, hdtr_positive_v4); 1129b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, hdtr_positive_v6); 1130b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, hdtr_negative_bad_pointers_v4); 1131b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, hdtr_negative_bad_pointers_v6); 1132b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, offset_negative_value_less_than_zero_v4); 1133b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, offset_negative_value_less_than_zero_v6); 1134b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, sbytes_positive_v4); 1135b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, sbytes_positive_v6); 1136b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, sbytes_negative_v4); 1137b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, sbytes_negative_v6); 1138b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, s_negative_not_connected_socket_v4); 1139b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, s_negative_not_connected_socket_v6); 1140b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, s_negative_not_descriptor); 1141b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, s_negative_not_socket_file_descriptor); 1142b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, s_negative_udp_socket_v4); 1143b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, s_negative_udp_socket_v6); 1144b29e1426SEnji Cooper 1145b29e1426SEnji Cooper return (atf_no_error()); 1146b29e1426SEnji Cooper } 1147