From owner-freebsd-bugs@FreeBSD.ORG Sun Feb 5 11:50:09 2012 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 7FE8D106566B for ; Sun, 5 Feb 2012 11:50:09 +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 5BABB8FC12 for ; Sun, 5 Feb 2012 11:50:09 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q15Bo9nm028976 for ; Sun, 5 Feb 2012 11:50:09 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q15Bo9ci028970; Sun, 5 Feb 2012 11:50:09 GMT (envelope-from gnats) Resent-Date: Sun, 5 Feb 2012 11:50:09 GMT Resent-Message-Id: <201202051150.q15Bo9ci028970@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, Nicolas Bourdaud Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E64781065670 for ; Sun, 5 Feb 2012 11:42:53 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22]) by mx1.freebsd.org (Postfix) with ESMTP id BB03C8FC16 for ; Sun, 5 Feb 2012 11:42:53 +0000 (UTC) Received: from red.freebsd.org (localhost [127.0.0.1]) by red.freebsd.org (8.14.4/8.14.4) with ESMTP id q15BgrA0041310 for ; Sun, 5 Feb 2012 11:42:53 GMT (envelope-from nobody@red.freebsd.org) Received: (from nobody@localhost) by red.freebsd.org (8.14.4/8.14.4/Submit) id q15Bgrh6041302; Sun, 5 Feb 2012 11:42:53 GMT (envelope-from nobody) Message-Id: <201202051142.q15Bgrh6041302@red.freebsd.org> Date: Sun, 5 Feb 2012 11:42:53 GMT From: Nicolas Bourdaud To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/164793: 'write' system call violates POSIX standard 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: Sun, 05 Feb 2012 11:50:09 -0000 >Number: 164793 >Category: kern >Synopsis: 'write' system call violates POSIX standard >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Feb 05 11:50:08 UTC 2012 >Closed-Date: >Last-Modified: >Originator: Nicolas Bourdaud >Release: FreeBSD 9.0-RELEASE >Organization: >Environment: GNU/kFreeBSD debian-bsd-amd64 9.0-RELEASE FreeBSD 9.0-RELEASE #0: Tue Jan 3 07:46:30 UTC 2012 root@farrell.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC x86_64 amd64 Intel(R) Core(TM)2 Duo CPU E7500 @ 2.93GHz GNU/kFreeBSD >Description: When a write() cannot transfer as many bytes as requested (because of a file limit), it fails instead of transferring as many bytes as there is room to write. This is a violation of the POSIX standard: http://pubs.opengroup.org/onlinepubs/007904975/functions/write.html >How-To-Repeat: fsize-lim.c.txt (attached) illustrates the problem. With a freebsd kernel, the output is: failed when adding 27 bytes after 59994 bytes (error: File too large) The expected output (like with a linux kernel) should be: added 6 bytes instead of 27 bytes after 59994 bytes failed when adding 27 bytes after 60000 bytes (error: File too large) >Fix: Patch attached with submission follows: #include #include #include #include #include #include #include #include #include #include #define TARGETSIZE 80000 #define LIMSIZE 60000 #define PATTSIZE 27 int main(void) { struct rlimit lim; int fd; ssize_t retc; size_t count = 0; const char pattern[PATTSIZE] = "Hello world!"; signal(SIGXFSZ, SIG_IGN); lim.rlim_cur = LIMSIZE; setrlimit(RLIMIT_FSIZE, &lim); fd = open("result.txt", O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR); while (count < TARGETSIZE) { retc = write(fd, pattern, PATTSIZE); if (retc < PATTSIZE && retc > 0) fprintf(stderr, "added %zi bytes instead of %u bytes after %zu bytes\n", retc, PATTSIZE, count); else if (retc < 0) { fprintf(stderr, "failed when adding %u bytes after %zu bytes (error: %s)\n", PATTSIZE, count, strerror(errno)); break; } count += retc; } close(fd); return 0; } >Release-Note: >Audit-Trail: >Unformatted: