18a272653SPeter Holm#!/bin/sh 28a272653SPeter Holm 38a272653SPeter Holm# 48a272653SPeter Holm# Copyright (c) 2010 Peter Holm <pho@FreeBSD.org> 58a272653SPeter Holm# All rights reserved. 68a272653SPeter Holm# 78a272653SPeter Holm# Redistribution and use in source and binary forms, with or without 88a272653SPeter Holm# modification, are permitted provided that the following conditions 98a272653SPeter Holm# are met: 108a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright 118a272653SPeter Holm# notice, this list of conditions and the following disclaimer. 128a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright 138a272653SPeter Holm# notice, this list of conditions and the following disclaimer in the 148a272653SPeter Holm# documentation and/or other materials provided with the distribution. 158a272653SPeter Holm# 168a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 178a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 188a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 198a272653SPeter Holm# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 208a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 218a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 228a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 238a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 248a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 258a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 268a272653SPeter Holm# SUCH DAMAGE. 278a272653SPeter Holm# 288a272653SPeter Holm 298a272653SPeter Holm# Test scenario for sendfile corruption of read only input file 308a272653SPeter Holm 318a272653SPeter Holm# Scenario by Ming Fu <Ming Fu watchguard com> 328a272653SPeter Holm 338a272653SPeter Holm. ../default.cfg 348a272653SPeter Holm 358a272653SPeter Holmodir=`pwd` 368a272653SPeter Holm 378a272653SPeter Holmcd /tmp 388a272653SPeter Holmsed '1,/^EOF/d' < $odir/$0 > sendfile2.c 398a272653SPeter Holmmycc -o sendfile2 -Wall sendfile2.c 408a272653SPeter Holmrm -f sendfile2.c 418a272653SPeter Holm[ -d "$RUNDIR" ] || mkdir -p $RUNDIR 428a272653SPeter Holmcd $RUNDIR 438a272653SPeter Holm 448a272653SPeter Holmdd if=/dev/random of=large bs=1m count=3 status=none 458a272653SPeter Holmmd1=`md5 large` 468a272653SPeter Holm 478a272653SPeter Holmnc -l 7000 > lf & 488a272653SPeter Holmsleep 0.1 498a272653SPeter Holm/tmp/sendfile2 508a272653SPeter Holmkill $! 2>/dev/null 518a272653SPeter Holmwait 528a272653SPeter Holm 538a272653SPeter Holmmd2=`md5 large` 548a272653SPeter Holm[ "$md1" != "$md2" ] && printf "%s\n%s\n" "$md1" "$md2" 558a272653SPeter Holm 568a272653SPeter Holmrm -f /tmp/sendfile2 large lf 578a272653SPeter Holmexit 588a272653SPeter HolmEOF 598a272653SPeter Holm#include <sys/types.h> 608a272653SPeter Holm#include <arpa/inet.h> 618a272653SPeter Holm#include <err.h> 628a272653SPeter Holm#include <fcntl.h> 638a272653SPeter Holm#include <netdb.h> 648a272653SPeter Holm#include <netinet/in.h> 658a272653SPeter Holm#include <stdio.h> 668a272653SPeter Holm#include <string.h> 678a272653SPeter Holm#include <strings.h> 688a272653SPeter Holm#include <sys/select.h> 698a272653SPeter Holm#include <sys/socket.h> 708a272653SPeter Holm#include <sys/stat.h> 718a272653SPeter Holm#include <sys/types.h> 728a272653SPeter Holm#include <sys/uio.h> 738a272653SPeter Holm#include <unistd.h> 748a272653SPeter Holm 758a272653SPeter Holmint 768a272653SPeter Holmmain () { 778a272653SPeter Holm int s, f; 788a272653SPeter Holm struct sockaddr_in addr; 798a272653SPeter Holm struct hostent *hostent; 808a272653SPeter Holm int flags; 818a272653SPeter Holm char str[32]="\r\n800\r\n"; 828a272653SPeter Holm char *p = str; 838a272653SPeter Holm struct stat sb; 848a272653SPeter Holm int n; 858a272653SPeter Holm fd_set wset; 868a272653SPeter Holm int64_t size; 878a272653SPeter Holm off_t sbytes; 888a272653SPeter Holm off_t sent = 0; 898a272653SPeter Holm int chunk; 908a272653SPeter Holm 918a272653SPeter Holm alarm(120); 928a272653SPeter Holm s = socket(AF_INET, SOCK_STREAM, 0); 938a272653SPeter Holm bzero(&addr, sizeof(addr)); 948a272653SPeter Holm addr.sin_family = AF_INET; 958a272653SPeter Holm addr.sin_port = htons(7000); 968a272653SPeter Holm hostent = gethostbyname ("localhost"); 978a272653SPeter Holm memcpy (&addr.sin_addr.s_addr, hostent->h_addr, 988a272653SPeter Holm sizeof (struct in_addr)); 998a272653SPeter Holm 1008a272653SPeter Holm n = connect(s, (struct sockaddr *)&addr, sizeof (addr)); 1018a272653SPeter Holm if (n < 0) 1028a272653SPeter Holm warn ("fail to connect"); 1038a272653SPeter Holm flags = fcntl(s, F_GETFL); 1048a272653SPeter Holm flags |= O_NONBLOCK; 105*8d72c409SPeter Holm fcntl(s, F_SETFL, flags); 1068a272653SPeter Holm 1078a272653SPeter Holm f = open("large", O_RDONLY); 1088a272653SPeter Holm if (f < 0) 1098a272653SPeter Holm warn("fail to open file"); 1108a272653SPeter Holm n = fstat(f, &sb); 1118a272653SPeter Holm if (n < 0) 1128a272653SPeter Holm warn("fstat failed"); 1138a272653SPeter Holm 1148a272653SPeter Holm size = sb.st_size; 1158a272653SPeter Holm chunk = 0; 1168a272653SPeter Holm while (size > 0) { 1178a272653SPeter Holm FD_ZERO(&wset); 1188a272653SPeter Holm FD_SET(s, &wset); 1198a272653SPeter Holm n = select(f+1, NULL, &wset, NULL, NULL); 1208a272653SPeter Holm if (n < 0) 1218a272653SPeter Holm continue; 1228a272653SPeter Holm if (chunk > 0) { 1238a272653SPeter Holm sbytes = 0; 1248a272653SPeter Holm n = sendfile(f, s, sent, chunk, NULL, &sbytes, 0); 1258a272653SPeter Holm if (n < 0) 1268a272653SPeter Holm continue; 1278a272653SPeter Holm chunk -= sbytes; 1288a272653SPeter Holm size -= sbytes; 1298a272653SPeter Holm sent += sbytes; 1308a272653SPeter Holm continue; 1318a272653SPeter Holm } 1328a272653SPeter Holm if (size > 2048) 1338a272653SPeter Holm chunk = 2048; 1348a272653SPeter Holm else 1358a272653SPeter Holm chunk = size; 1368a272653SPeter Holm n = sprintf(str, "\r\n%x\r\n", 2048); 1378a272653SPeter Holm p = str; 1388a272653SPeter Holm write(s, p, n); 1398a272653SPeter Holm } 1408a272653SPeter Holm 1418a272653SPeter Holm return (0); 1428a272653SPeter Holm} 143