write system call violates POSIX standard

Konstantin Belousov kostikbel at gmail.com
Wed Feb 15 17:09:16 UTC 2012


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 ?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-standards/attachments/20120215/6447c85b/attachment.pgp


More information about the freebsd-standards mailing list