kern/164793: 'write' system call violates POSIX standard
Nicolas Bourdaud
nicolas.bourdaud at gmail.com
Sun Feb 5 11:50:09 UTC 2012
>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 at 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:
More information about the freebsd-bugs
mailing list