standards/186028: incorrect return values for posix_fallocate()

Konstantin Belousov kostikbel at gmail.com
Thu Jan 23 09:40:28 UTC 2014


On Thu, Jan 23, 2014 at 08:58:58AM +0000, Gennady Proskurin wrote:
> 
> >Number:         186028
> >Category:       standards
> >Synopsis:       incorrect return values for posix_fallocate()
> >Confidential:   no
> >Severity:       non-critical
> >Priority:       low
> >Responsible:    freebsd-standards
> >State:          open
> >Quarter:        
> >Keywords:       
> >Date-Required:
> >Class:          sw-bug
> >Submitter-Id:   current-users
> >Arrival-Date:   Thu Jan 23 09:00:00 UTC 2014
> >Closed-Date:
> >Last-Modified:
> >Originator:     Gennady Proskurin
> >Release:        FreeBSD 11.0-CURRENT
> >Organization:
> >Environment:
> FreeBSD gpr.nnz-home.ru 11.0-CURRENT FreeBSD 11.0-CURRENT #0 r260472+743aa78(svn_head): Fri Jan 10 05:28:05 MSK 2014     gpr at gpr.nnz-home.ru:/usr/obj/usr/src/freebsd-head/sys/GPR  amd64
> >Description:
> In case of error, posix_fallocate() should return error code itself, but in FreeBSD it returns -1 and sets errno.
> 
> Quote from standard:
> http://pubs.opengroup.org/onlinepubs/009695399/functions/posix_fallocate.html
> RETURN VALUE
>     Upon successful completion, posix_fallocate() shall return zero; otherwise, an error number shall be returned to indicate the error.
> 
> 
> Quote from freebsd man:
> RETURN VALUES
>      If successful, posix_fallocate() returns zero.  It returns -1 on failure,
>      and sets errno to indicate the error.
> 
> >How-To-Repeat:
> test program attached
> >Fix:
> 
> 
> Patch attached with submission follows:
> 
> #include <fcntl.h>
> #include <errno.h>
> #include <string.h>
> #include <stdio.h>
> 
> int main()
> {
> 	int ret;
> 	int err;
> 
> 	errno = 0;
> 	ret = posix_fallocate(-1 /* emulate EBADF error */, 0, 1);
> 	err = errno;
> 	printf("return value : %i   strerror: %s\n", ret, strerror(ret));
> 	printf("errno        : %i   strerror: %s\n", err, strerror(err));
> }
> 

Indeed.  Linux also seems to have the conforming behaviour, according
to their man page, which also explicitely states that errno is not set.

Try this.

diff --git a/lib/libc/sys/posix_fallocate.2 b/lib/libc/sys/posix_fallocate.2
index 087c68c..ee6fcc4 100644
--- a/lib/libc/sys/posix_fallocate.2
+++ b/lib/libc/sys/posix_fallocate.2
@@ -83,9 +83,9 @@ that reduces the file size to a size smaller than
 If successful,
 .Fn posix_fallocate
 returns zero.
-It returns -1 on failure, and sets
+It returns error on failure, without setting
 .Va errno
-to indicate the error.
+variable.
 .Sh ERRORS
 Possible failure conditions:
 .Bl -tag -width Er
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 719a057..e4ffbe4 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -2995,8 +2995,9 @@ freebsd32_posix_fallocate(struct thread *td,
     struct freebsd32_posix_fallocate_args *uap)
 {
 
-	return (kern_posix_fallocate(td, uap->fd,
-	    PAIR32TO64(off_t, uap->offset), PAIR32TO64(off_t, uap->len)));
+	td->td_retval[0] = kern_posix_fallocate(td, uap->fd,
+	    PAIR32TO64(off_t, uap->offset), PAIR32TO64(off_t, uap->len));
+	return (0);
 }
 
 int
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index dbad1ae..b864c90 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -4584,7 +4584,9 @@ int
 sys_posix_fallocate(struct thread *td, struct posix_fallocate_args *uap)
 {
 
-	return (kern_posix_fallocate(td, uap->fd, uap->offset, uap->len));
+	td->td_retval[0] = kern_posix_fallocate(td, uap->fd, uap->offset,
+	    uap->len);
+	return (0);
 }
 
 /*
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 834 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/freebsd-standards/attachments/20140123/7a8d2db5/attachment-0001.sig>


More information about the freebsd-standards mailing list