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>
