sendfile.c (ed3d9b6e75a3c3f3a397e3adb892f9b3e6d4de06) | sendfile.c (f7754b09e2bc3c20e56dd8811c3289c6c9507c28) |
---|---|
1/*- 2 * Copyright (c) 2006 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 21 unchanged lines hidden (view full) --- 30#include <sys/socket.h> 31#include <sys/stat.h> 32 33#include <netinet/in.h> 34 35#include <err.h> 36#include <limits.h> 37#include <signal.h> | 1/*- 2 * Copyright (c) 2006 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 21 unchanged lines hidden (view full) --- 30#include <sys/socket.h> 31#include <sys/stat.h> 32 33#include <netinet/in.h> 34 35#include <err.h> 36#include <limits.h> 37#include <signal.h> |
38#include <stdint.h> |
|
38#include <stdio.h> 39#include <stdlib.h> 40#include <string.h> 41#include <unistd.h> 42 43/* 44 * Simple regression test for sendfile. Creates a file sized at three pages 45 * and then proceeds to send it over a series of sockets, exercising a number --- 28 unchanged lines hidden (view full) --- 74 *length = ntohl(th->th_length); 75 return (1); 76} 77 78static void 79signal_alarm(int signum) 80{ 81 | 39#include <stdio.h> 40#include <stdlib.h> 41#include <string.h> 42#include <unistd.h> 43 44/* 45 * Simple regression test for sendfile. Creates a file sized at three pages 46 * and then proceeds to send it over a series of sockets, exercising a number --- 28 unchanged lines hidden (view full) --- 75 *length = ntohl(th->th_length); 76 return (1); 77} 78 79static void 80signal_alarm(int signum) 81{ 82 |
83 (void)signum; |
|
82} 83 84static void 85setup_alarm(int seconds) 86{ 87 88 signal(SIGALRM, signal_alarm); 89 alarm(seconds); --- 12 unchanged lines hidden (view full) --- 102{ 103 u_int32_t header_length, offset, length, counter; 104 struct test_header th; 105 ssize_t len; 106 char ch; 107 108 len = read(accept_socket, &th, sizeof(th)); 109 if (len < 0) | 84} 85 86static void 87setup_alarm(int seconds) 88{ 89 90 signal(SIGALRM, signal_alarm); 91 alarm(seconds); --- 12 unchanged lines hidden (view full) --- 104{ 105 u_int32_t header_length, offset, length, counter; 106 struct test_header th; 107 ssize_t len; 108 char ch; 109 110 len = read(accept_socket, &th, sizeof(th)); 111 if (len < 0) |
110 err(-1, "read"); 111 if (len < sizeof(th)) 112 errx(-1, "read: %d", len); | 112 err(1, "read"); 113 if ((size_t)len < sizeof(th)) 114 errx(1, "read: %zd", len); |
113 114 if (test_th(&th, &header_length, &offset, &length) == 0) | 115 116 if (test_th(&th, &header_length, &offset, &length) == 0) |
115 errx(-1, "test_th: bad"); | 117 errx(1, "test_th: bad"); |
116 117 counter = 0; 118 while (1) { 119 len = read(accept_socket, &ch, sizeof(ch)); 120 if (len < 0) | 118 119 counter = 0; 120 while (1) { 121 len = read(accept_socket, &ch, sizeof(ch)); 122 if (len < 0) |
121 err(-1, "read"); | 123 err(1, "read"); |
122 if (len == 0) 123 break; 124 counter++; 125 /* XXXRW: Validate byte here. */ 126 } 127 if (counter != header_length + length) | 124 if (len == 0) 125 break; 126 counter++; 127 /* XXXRW: Validate byte here. */ 128 } 129 if (counter != header_length + length) |
128 errx(-1, "receive_test: expected (%d, %d) received %d", | 130 errx(1, "receive_test: expected (%d, %d) received %d", |
129 header_length, length, counter); 130} 131 132static void 133run_child(void) 134{ 135 int accept_socket; 136 --- 9 unchanged lines hidden (view full) --- 146static int 147new_test_socket(void) 148{ 149 struct sockaddr_in sin; 150 int connect_socket; 151 152 connect_socket = socket(PF_INET, SOCK_STREAM, 0); 153 if (connect_socket < 0) | 131 header_length, length, counter); 132} 133 134static void 135run_child(void) 136{ 137 int accept_socket; 138 --- 9 unchanged lines hidden (view full) --- 148static int 149new_test_socket(void) 150{ 151 struct sockaddr_in sin; 152 int connect_socket; 153 154 connect_socket = socket(PF_INET, SOCK_STREAM, 0); 155 if (connect_socket < 0) |
154 err(-1, "socket"); | 156 err(1, "socket"); |
155 156 bzero(&sin, sizeof(sin)); 157 sin.sin_len = sizeof(sin); 158 sin.sin_family = AF_INET; 159 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 160 sin.sin_port = htons(TEST_PORT); 161 162 if (connect(connect_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0) | 157 158 bzero(&sin, sizeof(sin)); 159 sin.sin_len = sizeof(sin); 160 sin.sin_family = AF_INET; 161 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 162 sin.sin_port = htons(TEST_PORT); 163 164 if (connect(connect_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0) |
163 err(-1, "connect"); | 165 err(1, "connect"); |
164 165 return (connect_socket); 166} 167 168static void 169init_th(struct test_header *th, u_int32_t header_length, u_int32_t offset, 170 u_int32_t length) 171{ --- 13 unchanged lines hidden (view full) --- 185 struct sf_hdtr hdtr, *hdtrp; 186 struct iovec headers; 187 char *header; 188 ssize_t len; 189 off_t off; 190 191 len = lseek(file_fd, 0, SEEK_SET); 192 if (len < 0) | 166 167 return (connect_socket); 168} 169 170static void 171init_th(struct test_header *th, u_int32_t header_length, u_int32_t offset, 172 u_int32_t length) 173{ --- 13 unchanged lines hidden (view full) --- 187 struct sf_hdtr hdtr, *hdtrp; 188 struct iovec headers; 189 char *header; 190 ssize_t len; 191 off_t off; 192 193 len = lseek(file_fd, 0, SEEK_SET); 194 if (len < 0) |
193 err(-1, "lseek"); | 195 err(1, "lseek"); |
194 if (len != 0) | 196 if (len != 0) |
195 errx(-1, "lseek: %d", len); | 197 errx(1, "lseek: %zd", len); |
196 197 init_th(&th, header_length, offset, length); 198 199 len = write(connect_socket, &th, sizeof(th)); 200 if (len < 0) | 198 199 init_th(&th, header_length, offset, length); 200 201 len = write(connect_socket, &th, sizeof(th)); 202 if (len < 0) |
201 err(-1, "send"); | 203 err(1, "send"); |
202 if (len != sizeof(th)) | 204 if (len != sizeof(th)) |
203 err(-1, "send: %d", len); | 205 err(1, "send: %zd", len); |
204 205 if (header_length != 0) { 206 header = malloc(header_length); 207 if (header == NULL) | 206 207 if (header_length != 0) { 208 header = malloc(header_length); 209 if (header == NULL) |
208 err(-1, "malloc"); | 210 err(1, "malloc"); |
209 hdtrp = &hdtr; 210 bzero(&headers, sizeof(headers)); 211 headers.iov_base = header; 212 headers.iov_len = header_length; 213 bzero(&hdtr, sizeof(hdtr)); 214 hdtr.headers = &headers; 215 hdtr.hdr_cnt = 1; 216 hdtr.trailers = NULL; 217 hdtr.trl_cnt = 0; 218 } else { 219 hdtrp = NULL; 220 header = NULL; 221 } 222 223 if (sendfile(file_fd, connect_socket, offset, length, hdtrp, &off, 224 0) < 0) | 211 hdtrp = &hdtr; 212 bzero(&headers, sizeof(headers)); 213 headers.iov_base = header; 214 headers.iov_len = header_length; 215 bzero(&hdtr, sizeof(hdtr)); 216 hdtr.headers = &headers; 217 hdtr.hdr_cnt = 1; 218 hdtr.trailers = NULL; 219 hdtr.trl_cnt = 0; 220 } else { 221 hdtrp = NULL; 222 header = NULL; 223 } 224 225 if (sendfile(file_fd, connect_socket, offset, length, hdtrp, &off, 226 0) < 0) |
225 err(-1, "sendfile"); | 227 err(1, "sendfile"); |
226 227 if (length == 0) { 228 struct stat sb; 229 230 if (fstat(file_fd, &sb) < 0) | 228 229 if (length == 0) { 230 struct stat sb; 231 232 if (fstat(file_fd, &sb) < 0) |
231 err(-1, "fstat"); | 233 err(1, "fstat"); |
232 length = sb.st_size; 233 } 234 235 if (off != length) { | 234 length = sb.st_size; 235 } 236 237 if (off != length) { |
236 errx(-1, "sendfile: off(%llu) != length(%llu)", off, 237 (unsigned long long)length); | 238 errx(1, "sendfile: off(%ju) != length(%ju)", 239 (uintmax_t)off, (uintmax_t)length); |
238 } 239 240 if (header != NULL) 241 free(header); 242} 243 244static void 245run_parent(void) --- 53 unchanged lines hidden (view full) --- 299 close(connect_socket); 300 301 sleep(1); 302 303 (void)kill(child_pid, SIGKILL); 304} 305 306int | 240 } 241 242 if (header != NULL) 243 free(header); 244} 245 246static void 247run_parent(void) --- 53 unchanged lines hidden (view full) --- 301 close(connect_socket); 302 303 sleep(1); 304 305 (void)kill(child_pid, SIGKILL); 306} 307 308int |
307main(int argc, char *argv[]) | 309main(void) |
308{ 309 char path[PATH_MAX], *page_buffer; 310 struct sockaddr_in sin; 311 int pagesize; 312 ssize_t len; 313 314 pagesize = getpagesize(); 315 page_buffer = malloc(TEST_PAGES * pagesize); 316 if (page_buffer == NULL) | 310{ 311 char path[PATH_MAX], *page_buffer; 312 struct sockaddr_in sin; 313 int pagesize; 314 ssize_t len; 315 316 pagesize = getpagesize(); 317 page_buffer = malloc(TEST_PAGES * pagesize); 318 if (page_buffer == NULL) |
317 err(-1, "malloc"); | 319 err(1, "malloc"); |
318 bzero(page_buffer, TEST_PAGES * pagesize); 319 320 listen_socket = socket(PF_INET, SOCK_STREAM, 0); 321 if (listen_socket < 0) | 320 bzero(page_buffer, TEST_PAGES * pagesize); 321 322 listen_socket = socket(PF_INET, SOCK_STREAM, 0); 323 if (listen_socket < 0) |
322 err(-1, "socket"); | 324 err(1, "socket"); |
323 324 bzero(&sin, sizeof(sin)); 325 sin.sin_len = sizeof(sin); 326 sin.sin_family = AF_INET; 327 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 328 sin.sin_port = htons(TEST_PORT); 329 330 snprintf(path, PATH_MAX, "/tmp/sendfile.XXXXXXXXXXXX"); 331 file_fd = mkstemp(path); 332 (void)unlink(path); 333 334 len = write(file_fd, page_buffer, TEST_PAGES * pagesize); 335 if (len < 0) | 325 326 bzero(&sin, sizeof(sin)); 327 sin.sin_len = sizeof(sin); 328 sin.sin_family = AF_INET; 329 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 330 sin.sin_port = htons(TEST_PORT); 331 332 snprintf(path, PATH_MAX, "/tmp/sendfile.XXXXXXXXXXXX"); 333 file_fd = mkstemp(path); 334 (void)unlink(path); 335 336 len = write(file_fd, page_buffer, TEST_PAGES * pagesize); 337 if (len < 0) |
336 err(-1, "write"); | 338 err(1, "write"); |
337 338 len = lseek(file_fd, 0, SEEK_SET); 339 if (len < 0) | 339 340 len = lseek(file_fd, 0, SEEK_SET); 341 if (len < 0) |
340 err(-1, "lseek"); | 342 err(1, "lseek"); |
341 if (len != 0) | 343 if (len != 0) |
342 errx(-1, "lseek: %d", len); | 344 errx(1, "lseek: %zd", len); |
343 344 if (bind(listen_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0) | 345 346 if (bind(listen_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0) |
345 err(-1, "bind"); | 347 err(1, "bind"); |
346 347 if (listen(listen_socket, -1) < 0) | 348 349 if (listen(listen_socket, -1) < 0) |
348 err(-1, "listen"); | 350 err(1, "listen"); |
349 350 parent_pid = getpid(); 351 child_pid = fork(); 352 if (child_pid < 0) | 351 352 parent_pid = getpid(); 353 child_pid = fork(); 354 if (child_pid < 0) |
353 err(-1, "fork"); | 355 err(1, "fork"); |
354 if (child_pid == 0) { 355 child_pid = getpid(); 356 run_child(); 357 } else 358 run_parent(); 359 360 return (0); 361} | 356 if (child_pid == 0) { 357 child_pid = getpid(); 358 run_child(); 359 } else 360 run_parent(); 361 362 return (0); 363} |