Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Feb 2012 18:38:00 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Nicolas Bourdaud <nicolas.bourdaud@gmail.com>
Cc:        freebsd-standards@freebsd.org
Subject:   Re: write system call violates POSIX standard
Message-ID:  <20120215163800.GA3283@deviant.kiev.zoral.com.ua>
In-Reply-To: <4F3BC2DB.6080703@gmail.com>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
On Wed, Feb 15, 2012 at 03:36:11PM +0100, Nicolas Bourdaud wrote:
> [resent since the signature messed my previous message on the mailing
> list archive]
> 
> Hi all,
> 
> 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
> 
> 
> I have provided a small test to verify the problem (fsize-lim.c).
> 
> I have also created a bug report but I have been advised to post on this
> mailing list anyway:
> http://www.freebsd.org/cgi/query-pr.cgi?pr=164793
> 
> 
> Best regards
> 
> Nicolas
> 
> test file: fsize-lim.c:
> 
> #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);
> 	getrlimit(RLIMIT_FSIZE, &lim);
> 	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;
> }

It seems that you are right.

A solution could be to return an error if uio->uio_offset itself is
larger them RLIMIT_FSIZE. If it is less then the limit, the function
could trim the supplied uio at the RLIMIT_FSIZE value instead.

Do you want to work on the patch ?

[-- Attachment #2 --]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (FreeBSD)

iEYEARECAAYFAk8732gACgkQC3+MBN1Mb4itxACg9PwlSrxjdyO8oy92PHMXxkpO
V+IAn3yMTyl62vfoASXQm4XcdH3GVlNe
=E/dV
-----END PGP SIGNATURE-----
help

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