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}