NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
standards/49684: readlinkat(2) is not compliant
>Number: 49684
>Category: standards
>Synopsis: readlinkat(2) is not compliant
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: standards-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Feb 21 23:15:00 +0000 2015
>Originator: Pierre Pronchery
>Release: NetBSD 7.0_BETA
>Organization:
The NetBSD Foundation
>Environment:
>Description:
There is a discrepancy between the manual page for readlinkat(2) and the
actual prototype for this system call as found in /usr/include/unistd.h.
The manual page says:
ssize_t
readlinkat(int fd, const char * restrict path, char * restrict buf,
size_t bufsiz);
Whereas the header actually contains:
int
readlinkat(int fd, const char *, char *, size_t);
The issue is therefore with the return value, respectively typed ssize_t
and int. Somewhat interestingly, I noticed this because of a build issue
in a software project failing to recognize support of readlinkat(2) in
NetBSD, and then providing a conflicting prototype for it.
Last but not least, according to The Open Group Base Specifications
Issue 7, the prototype should be:
ssize_t
readlinkat(int fd, const char *restrict path, char *restrict buf,
size_t bufsize);
Just like the manual says. I am afraid this may involve an ABI update in
NetBSD's libc, but I do not know for sure as of now.
A quick look at the functions surrounding readlinkat(2) in unistd.h:
- linkat() is fine
- renameat() is fine
- faccessat() is fine
- fchownat() apparently not in the specification online
- symlinkat() is fine
- unlinkat() is fine
Likewise readlink(2) looks good to me. My immediate knowledge does not
allow me to be sure whether the actual implementation in
sys/kern/vfs_syscalls.c is impacted at all. It seems to be that the
result might be truncated from sizeof(ssize_t) to sizeof(int) on some
platforms (like every 32-bits I know). But I will welcome a better
expertise here.
>How-To-Repeat:
Build wip/pkg15 1.4.99.11nb4 from pkgsrc on NetBSD 7.0_BETA or newer.
>Fix:
Probably involves modifying /usr/include/unistd.h as follows:
Index: include/unistd.h
===================================================================
RCS file: /cvsroot/src/include/unistd.h,v
retrieving revision 1.143
diff -p -u -r1.143 unistd.h
--- include/unistd.h 26 Sep 2014 19:28:03 -0000 1.143
+++ include/unistd.h 21 Feb 2015 22:41:29 -0000
@@ -308,7 +308,7 @@ int linkat(int, const char *, int, const
int renameat(int, const char *, int, const char *);
int faccessat(int, const char *, int, int);
int fchownat(int, const char *, uid_t, gid_t, int);
-int readlinkat(int, const char *, char *, size_t);
+ssize_t readlinkat(int, const char *, char *, size_t);
int symlinkat(const char *, int, const char *);
int unlinkat(int, const char *, int);
#endif
Then also syscalls.master:
Index: sys/kern/syscalls.master
===================================================================
RCS file: /cvsroot/src/sys/kern/syscalls.master,v
retrieving revision 1.271
diff -p -u -r1.271 syscalls.master
--- sys/kern/syscalls.master 10 Feb 2015 15:07:39 -0000 1.271
+++ sys/kern/syscalls.master 21 Feb 2015 22:59:07 -0000
@@ -919,7 +919,7 @@
const struct timespec *tptr, int flag); }
468 STD RUMP { int|sys||openat(int fd, const char *path, \
int oflags, ... mode_t mode); }
-469 STD RUMP { int|sys||readlinkat(int fd, const char *path, \
+469 STD RUMP { ssize_t|sys||readlinkat(int fd, const char *path, \
char *buf, size_t bufsize); }
470 STD RUMP { int|sys||symlinkat(const char *path1, int fd, \
const char *path2); }
(then of course re-generating everything related)
>Unformatted:
Built on February 16th 2015, up to tickets #500 and #501 applied.
(EdgeBSD's commit ID c2bd92a3)
Home |
Main Index |
Thread Index |
Old Index