From owner-freebsd-bugs@FreeBSD.ORG Thu Feb 21 16:00:06 2008 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 41F7216A405 for ; Thu, 21 Feb 2008 16:00:06 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 24A4713C468 for ; Thu, 21 Feb 2008 16:00:06 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id m1LG06wT063214 for ; Thu, 21 Feb 2008 16:00:06 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m1LG05MK063213; Thu, 21 Feb 2008 16:00:05 GMT (envelope-from gnats) Resent-Date: Thu, 21 Feb 2008 16:00:05 GMT Resent-Message-Id: <200802211600.m1LG05MK063213@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Dan Nelson Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4EB2316A400 for ; Thu, 21 Feb 2008 15:54:16 +0000 (UTC) (envelope-from dan@dan.emsphone.com) Received: from dan.emsphone.com (dan.emsphone.com [199.67.51.101]) by mx1.freebsd.org (Postfix) with ESMTP id 1A41F13C448 for ; Thu, 21 Feb 2008 15:54:15 +0000 (UTC) (envelope-from dan@dan.emsphone.com) Received: (from dan@localhost) by dan.emsphone.com (8.14.2/8.14.2) id m1LFsEcb074499; Thu, 21 Feb 2008 09:54:14 -0600 (CST) (envelope-from dan) Message-Id: <200802211554.m1LFsEcb074499@dan.emsphone.com> Date: Thu, 21 Feb 2008 09:54:14 -0600 (CST) From: Dan Nelson To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: kern/120948: sendfile(2) doesn't send trailers X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 Feb 2008 16:00:06 -0000 >Number: 120948 >Category: kern >Synopsis: sendfile(2) doesn't send trailers >Confidential: no >Severity: serious >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Feb 21 16:00:05 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Dan Nelson >Release: FreeBSD 7.0-PRERELEASE i386 >Organization: The Allant Group >Environment: System: FreeBSD dan.emsphone.com 7.0-PRERELEASE FreeBSD 7.0-PRERELEASE #534: Thu Feb 21 09:24:12 CST 2008 zsh@dan.emsphone.com:/usr/src-7/sys/i386/compile/DANSMP i386 >Description: rev 1.240 of uipc_syscalls.c converted the "send file" part of sendfile(2) from a counted for-loop to an infinite loop, but the code for breaking out of the loop jumps to the wrong place on success, and the code for sending the trailer is never called. >How-To-Repeat: Try the following program. Example of correct output: Should receive 48 bytes: rv=0, count=48 rv=48, data=<[this is header]FreeBSD 7.0-PRER[this is trailr]> #include #include #include #include #include #include #include #include #include int main(void) { int socks[3]; int fd; unsigned int len; int rv; char buffer[8192]; off_t count = 0; struct sockaddr_in sin; struct iovec h, t; struct sf_hdtr hdtr; printf("Should receive 48 bytes:\n"); memset(socks, 0, sizeof(socks)); socks[0] = socket(PF_INET, SOCK_STREAM, 0); socks[1] = socket(PF_INET, SOCK_STREAM, 0); sin.sin_len = sizeof(sin); sin.sin_family = AF_INET; inet_aton("0.0.0.0", &sin.sin_addr); sin.sin_port = 0; bind(socks[0], &sin, sizeof(sin)); listen(socks[0], 16); len = sizeof(sin); getsockname(socks[0], &sin, &len); connect(socks[1], &sin, sizeof(sin)); socks[2] = accept(socks[0], NULL, 0); /* send 3 16-byte chunks: header, file, trailer */ h.iov_base = "[this is header]"; h.iov_len = strlen(h.iov_base); t.iov_base = "[this is trailr]"; t.iov_len = strlen(t.iov_base); hdtr.headers = &h; hdtr.hdr_cnt = 1; hdtr.trailers = &t; hdtr.trl_cnt = 1; fd = open("/etc/motd", O_RDONLY); rv = sendfile(fd, socks[1], 0, 16, &hdtr, &count, 0); printf("rv=%d, count=%lld\n", rv, count); sleep(1); memset(buffer, 0, 8192); rv = read(socks[2], &buffer, 8192); printf("rv=%d, data=<%s>\n", rv, buffer); return 0; } >Fix: This works for me: Index: uipc_syscalls.c =================================================================== RCS file: /home/ncvs/src/sys/kern/uipc_syscalls.c,v retrieving revision 1.259.2.2 diff -u -r1.259.2.2 uipc_syscalls.c --- uipc_syscalls.c 14 Feb 2008 11:44:59 -0000 1.259.2.2 +++ uipc_syscalls.c 21 Feb 2008 15:11:24 -0000 @@ -2172,7 +2172,9 @@ } /* Quit outer loop on error or when we're done. */ - if (error || done) + if (done) + break; + if (error) goto done; } >Release-Note: >Audit-Trail: >Unformatted: