diff options
Diffstat (limited to 'src/basic/fd-util.c')
-rw-r--r-- | src/basic/fd-util.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/src/basic/fd-util.c b/src/basic/fd-util.c index e085dc23b4..c06f2fac7e 100644 --- a/src/basic/fd-util.c +++ b/src/basic/fd-util.c @@ -23,6 +23,7 @@ #include "socket-util.h" #include "stdio-util.h" #include "util.h" +#include "tmpfile-util.h" int close_nointr(int fd) { assert(fd >= 0); @@ -113,7 +114,7 @@ FILE* safe_fclose(FILE *f) { if (f) { PROTECT_ERRNO; - assert_se(fclose_nointr(f) != EBADF); + assert_se(fclose_nointr(f) != -EBADF); } return NULL; @@ -277,7 +278,7 @@ int same_fd(int a, int b) { return true; if (r > 0) return false; - if (errno != ENOSYS) + if (!IN_SET(errno, ENOSYS, EACCES, EPERM)) return -errno; /* We don't have kcmp(), use fstat() instead. */ @@ -353,22 +354,22 @@ bool fdname_is_valid(const char *s) { } int fd_get_path(int fd, char **ret) { - _cleanup_close_ int dir = -1; - char fdname[DECIMAL_STR_MAX(int)]; + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; int r; - dir = open("/proc/self/fd/", O_CLOEXEC | O_DIRECTORY | O_PATH); - if (dir < 0) - /* /proc is not available or not set up properly, we're most likely - * in some chroot environment. */ - return errno == ENOENT ? -EOPNOTSUPP : -errno; + xsprintf(procfs_path, "/proc/self/fd/%i", fd); + r = readlink_malloc(procfs_path, ret); + if (r == -ENOENT) { + /* ENOENT can mean two things: that the fd does not exist or that /proc is not mounted. Let's make + * things debuggable and distuingish the two. */ - xsprintf(fdname, "%i", fd); + if (access("/proc/self/fd/", F_OK) < 0) + /* /proc is not available or not set up properly, we're most likely in some chroot + * environment. */ + return errno == ENOENT ? -EOPNOTSUPP : -errno; - r = readlinkat_malloc(dir, fdname, ret); - if (r == -ENOENT) - /* If the file doesn't exist the fd is invalid */ - return -EBADF; + return -EBADF; /* The directory exists, hence it's the fd that doesn't. */ + } return r; } @@ -648,7 +649,7 @@ int fd_duplicate_data_fd(int fd) { if ((size_t) isz >= DATA_FD_MEMORY_LIMIT) { - r = copy_bytes_full(fd, pipefds[1], DATA_FD_MEMORY_LIMIT, 0, &remains, &remains_size); + r = copy_bytes_full(fd, pipefds[1], DATA_FD_MEMORY_LIMIT, 0, &remains, &remains_size, NULL, NULL); if (r < 0 && r != -EAGAIN) return r; /* If we get EAGAIN it could be because of the source or because of * the destination fd, we can't know, as sendfile() and friends won't |