mirror of
https://git.musl-libc.org/git/musl
synced 2025-02-15 09:43:57 +03:00
fix failure of fchmod, fstat, fchdir, and fchown to produce EBADF
the workaround/fallback code for supporting O_PATH file descriptors when the kernel lacks support for performing these operations on them caused EBADF to get replaced by ENOENT (due to missing entry in /proc/self/fd). this is unlikely to affect real-world code (calls that might yield EBADF are generally unsafe, especially in library code) but it was breaking some test cases. the fix I've applied is something of a tradeoff: it adds one syscall to these operations on kernels where the workaround is needed. the alternative would be to catch ENOENT from the /proc lookup and translate it to EBADF, but I want to avoid doing that in the interest of not touching/depending on /proc at all in these functions as long as the kernel correctly supports the operations. this is following the general principle of isolating hacks to code paths that are taken on broken systems, and keeping the code for correct systems completely hack-free.
This commit is contained in:
parent
f89e298290
commit
65ea604c74
@ -1,5 +1,6 @@
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include "syscall.h"
|
||||
|
||||
void __procfdname(char *, unsigned);
|
||||
@ -7,7 +8,8 @@ void __procfdname(char *, unsigned);
|
||||
int fchmod(int fd, mode_t mode)
|
||||
{
|
||||
int ret = __syscall(SYS_fchmod, fd, mode);
|
||||
if (ret != -EBADF || fd < 0) return __syscall_ret(ret);
|
||||
if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
|
||||
return __syscall_ret(ret);
|
||||
|
||||
char buf[15+3*sizeof(int)];
|
||||
__procfdname(buf, fd);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include "syscall.h"
|
||||
#include "libc.h"
|
||||
|
||||
@ -8,7 +9,8 @@ void __procfdname(char *, unsigned);
|
||||
int fstat(int fd, struct stat *st)
|
||||
{
|
||||
int ret = __syscall(SYS_fstat, fd, st);
|
||||
if (ret != -EBADF || fd < 0) return __syscall_ret(ret);
|
||||
if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
|
||||
return __syscall_ret(ret);
|
||||
|
||||
char buf[15+3*sizeof(int)];
|
||||
__procfdname(buf, fd);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include "syscall.h"
|
||||
|
||||
void __procfdname(char *, unsigned);
|
||||
@ -7,7 +8,8 @@ void __procfdname(char *, unsigned);
|
||||
int fchdir(int fd)
|
||||
{
|
||||
int ret = __syscall(SYS_fchdir, fd);
|
||||
if (ret != -EBADF || fd < 0) return __syscall_ret(ret);
|
||||
if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
|
||||
return __syscall_ret(ret);
|
||||
|
||||
char buf[15+3*sizeof(int)];
|
||||
__procfdname(buf, fd);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include "syscall.h"
|
||||
|
||||
void __procfdname(char *, unsigned);
|
||||
@ -7,7 +8,8 @@ void __procfdname(char *, unsigned);
|
||||
int fchown(int fd, uid_t uid, gid_t gid)
|
||||
{
|
||||
int ret = __syscall(SYS_fchown, fd, uid, gid);
|
||||
if (ret != -EBADF || fd < 0) return __syscall_ret(ret);
|
||||
if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
|
||||
return __syscall_ret(ret);
|
||||
|
||||
char buf[15+3*sizeof(int)];
|
||||
__procfdname(buf, fd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user