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)
|
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
|
#ifdef SYS_readlink
|
||||||
return syscall(SYS_readlink, path, buf, bufsize);
|
int r = __syscall(SYS_readlink, path, buf, bufsize);
|
||||||
#else
|
#else
|
||||||
return syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
|
int r = __syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
|
||||||
#endif
|
#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)
|
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