mirror of git://git.musl-libc.org/musl
work around linux bug in readlink syscall with zero buffer size
linux fails with EINVAL when a zero buffer size is passed to the syscall. this is non-conforming because POSIX already defines EINVAL with a significantly different meaning: the target is not a symlink. since the request is semantically valid, patch it up by using a dummy buffer of length one, and truncating the return value to zero if it succeeds.
This commit is contained in:
parent
c17cda6d61
commit
e2fa720be7
|
@ -4,9 +4,16 @@
|
|||
|
||||
ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
|
||||
{
|
||||
char dummy[1];
|
||||
if (!bufsize) {
|
||||
buf = dummy;
|
||||
bufsize = 1;
|
||||
}
|
||||
#ifdef SYS_readlink
|
||||
return syscall(SYS_readlink, path, buf, bufsize);
|
||||
int r = __syscall(SYS_readlink, path, buf, bufsize);
|
||||
#else
|
||||
return syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
|
||||
int r = __syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
|
||||
#endif
|
||||
if (buf == dummy && r > 0) r = 0;
|
||||
return __syscall_ret(r);
|
||||
}
|
||||
|
|
|
@ -3,5 +3,12 @@
|
|||
|
||||
ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf, size_t bufsize)
|
||||
{
|
||||
return syscall(SYS_readlinkat, fd, path, buf, bufsize);
|
||||
char dummy[1];
|
||||
if (!bufsize) {
|
||||
buf = dummy;
|
||||
bufsize = 1;
|
||||
}
|
||||
int r = __syscall(SYS_readlinkat, fd, path, buf, bufsize);
|
||||
if (buf == dummy && r > 0) r = 0;
|
||||
return __syscall_ret(r);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue