Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 5 Feb 2012 11:42:53 GMT
From:      Nicolas Bourdaud <nicolas.bourdaud@gmail.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/164793: 'write' system call violates POSIX standard
Message-ID:  <201202051142.q15Bgrh6041302@red.freebsd.org>
Resent-Message-ID: <201202051150.q15Bo9ci028970@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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 <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <string.h>

#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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202051142.q15Bgrh6041302>