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