4 # SPDX-License-Identifier: BSD-2-Clause-FreeBSD
6 # Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions
11 # 1. Redistributions of source code must retain the above copyright
12 # notice, this list of conditions and the following disclaimer.
13 # 2. Redistributions in binary form must reproduce the above copyright
14 # notice, this list of conditions and the following disclaimer in the
15 # documentation and/or other materials provided with the distribution.
17 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 # Variation of sendfile21.sh: without the use of socketpair().
34 [ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
39 sed '1,/^EOF/d' < $odir/$0 > $dir/sendfile22.c
40 mycc -o sendfile22 -Wall -Wextra -O0 -g sendfile22.c || exit 1
45 mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
46 [ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
47 mdconfig -a -t swap -s 1g -u $mdstart
48 bsdlabel -w md$mdstart auto
50 newfs $newfs_flags -n md$mdstart > /dev/null
51 mount /dev/md$mdstart $mntpoint
55 dd if=/dev/random of=input bs=4k count=100 status=none
57 (cd $odir/../testcases/swap; ./swap -t 5m -i 20 -l 100 > /dev/null) &
61 while [ $((` date +%s` - start)) -lt 180 ]; do
63 umount $mntpoint 2>/dev/null # busy umount
66 cmp -s input output || break
67 [ `stat -f '%z' input` -ne ` stat -f '%z' output` ] && break
70 while pgrep -q swap; do
73 cmp -s input output || { echo "Loop #$n"; ls -l; s=1; }
75 [ -f sendfile22.core -a $s -eq 0 ] &&
76 { ls -l sendfile22.core; mv sendfile22.core $dir; s=1; }
80 mount | grep -q "on $mntpoint " || break
81 umount $mntpoint && break || sleep 10
83 { echo FATAL; fstat -mf $mntpoint; exit 1; }
85 mdconfig -d -u $mdstart
86 rm -rf $dir/sendfile22
90 #include <sys/param.h>
91 #include <sys/fcntl.h>
93 #include <sys/socket.h>
98 #include <netinet/in.h>
114 struct sockaddr_in inetaddr, inetpeer;
115 struct hostent *hostent;
117 off_t i, j, rd, written, pos;
119 int error, from, i1, msgsock, n, on, port, r, status, tcpsock, to;
121 const char *from_name, *to_name;
127 if ((from = open(from_name, O_RDONLY)) == -1)
128 err(1, "open read %s", from_name);
130 if ((error = fstat(from, &st)) == -1)
131 err(1, "stat %s", from_name);
137 setproctitle("parent");
141 for (i1 = 1; i1 < 5; i1++) {
142 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
143 err(1, "socket(), %s:%d", __FILE__, __LINE__);
145 if (setsockopt(tcpsock,
146 SOL_SOCKET, SO_REUSEADDR, (char *)&on,
148 err(1, "setsockopt(), %s:%d", __FILE__,
151 hostent = gethostbyname ("localhost");
152 bzero((char *) &inetaddr, sizeof(inetaddr));
153 memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr,
154 sizeof (struct in_addr));
156 inetaddr.sin_family = AF_INET;
157 inetaddr.sin_port = htons(port);
158 inetaddr.sin_len = sizeof(inetaddr);
160 r = connect(tcpsock, (struct sockaddr *) &inetaddr,
168 err(1, "connect(), %s:%d", __FILE__, __LINE__);
170 if ((cp = mmap(NULL, st.st_size, PROT_READ,
171 MAP_PRIVATE, from, 0)) == MAP_FAILED)
173 if (fsync(from) == -1)
176 for (i = 0, j = 0; i < st.st_size; i += PAGE_SIZE, j++) {
179 if (msync(cp + i, PAGE_SIZE, MS_INVALIDATE)
181 err(1, "msync(), j = %d", (int)j);
184 if (munmap(cp, st.st_size) == -1)
189 error = sendfile(from, tcpsock, pos, st.st_size -
190 pos, NULL, &written, 0);
193 if (written != st.st_size)
194 fprintf(stderr, "sendfile sent %d bytes\n",
197 if (pos == st.st_size)
200 if (pos != st.st_size)
201 fprintf(stderr, "%d written, expected %d\n",
202 (int)pos, (int)st.st_size);
204 if (waitpid(pid, &status, 0) != pid)
205 err(1, "waitpid(%d)", pid);
207 setproctitle("child");
211 if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
212 err(1, "socket(), %s:%d", __FILE__, __LINE__);
214 if (setsockopt(tcpsock,
215 SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
216 err(1, "setsockopt(), %s:%d", __FILE__, __LINE__);
218 inetaddr.sin_family = AF_INET;
219 inetaddr.sin_addr.s_addr = INADDR_ANY;
220 inetaddr.sin_port = htons(port);
221 inetaddr.sin_len = sizeof(inetaddr);
224 (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0)
225 err(1, "bind(), %s:%d", __FILE__, __LINE__);
227 if (listen(tcpsock, 5) < 0)
228 err(1, "listen(), %s:%d", __FILE__, __LINE__);
230 len = sizeof(inetpeer);
231 if ((msgsock = accept(tcpsock,
232 (struct sockaddr *)&inetpeer, &len)) < 0)
233 err(1, "accept(), %s:%d", __FILE__, __LINE__);
235 if ((to = open(to_name, O_RDWR | O_CREAT, DEFFILEMODE)) ==
237 err(1, "open write %s", to_name);
241 n = read(msgsock, buf, sizeof(buf));
247 if (write(to, buf, n) != n)
251 if (rd != st.st_size)
252 fprintf(stderr, "Short read %d, expected %d\n",
253 (int)rd, (int)st.st_size);
267 if ((pid = fork()) == 0)
271 if (waitpid(pid, &status, 0) == -1)
272 err(1, "waitpid(%d)", pid);
274 if (WIFSIGNALED(status))
276 "pid %d exit signal %d\n",
277 pid, WTERMSIG(status));
279 e += status == 0 ? 0 : 1;