X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fopenat.c;h=7f92c7cc78dda84fba24c302d42500f3e9efe7c9;hb=8e99d1a0adfc4eb035e73219ef7001494ecb0c50;hp=49ecde883ffd23b5d3733020a7af14235ea64c3a;hpb=0632e115747ff96e93330c88f536d7354a7ce507;p=gnulib.git diff --git a/lib/openat.c b/lib/openat.c index 49ecde883..7f92c7cc7 100644 --- a/lib/openat.c +++ b/lib/openat.c @@ -26,6 +26,7 @@ #include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */ #include "fcntl--.h" +#include "lchown.h" #include "lstat.h" #include "openat-priv.h" #include "save-cwd.h" @@ -85,14 +86,23 @@ openat_permissive (int fd, char const *file, int flags, mode_t mode, return open (file, flags, mode); { - char *proc_file; - BUILD_PROC_NAME (proc_file, fd, file); - err = open (proc_file, flags, mode); - /* If the syscall succeeds, or if it fails with an unexpected - errno value, then return right away. Otherwise, fall through - and resort to using save_cwd/restore_cwd. */ - if (0 <= err || ! EXPECTED_ERRNO (errno)) - return err; + char buf[OPENAT_BUFFER_SIZE]; + char *proc_file = openat_proc_name (buf, fd, file); + if (proc_file) + { + int open_result = open (proc_file, flags, mode); + int open_errno = errno; + if (proc_file != buf) + free (proc_file); + /* If the syscall succeeds, or if it fails with an unexpected + errno value, then return right away. Otherwise, fall through + and resort to using save_cwd/restore_cwd. */ + if (0 <= open_result || ! EXPECTED_ERRNO (open_errno)) + { + errno = open_errno; + return open_result; + } + } } save_ok = (save_cwd (&saved_cwd) == 0); @@ -128,19 +138,23 @@ openat_permissive (int fd, char const *file, int flags, mode_t mode, bool openat_needs_fchdir (void) { - int fd2; + bool needs_fchdir = true; int fd = open ("/", O_RDONLY); - char *proc_file; - if (fd < 0) - return true; - BUILD_PROC_NAME (proc_file, fd, "."); - fd2 = open (proc_file, O_RDONLY); - close (fd); - if (0 <= fd2) - close (fd2); + if (0 <= fd) + { + char buf[OPENAT_BUFFER_SIZE]; + char *proc_file = openat_proc_name (buf, fd, "."); + if (proc_file) + { + needs_fchdir = false; + if (proc_file != buf) + free (proc_file); + } + close (fd); + } - return fd2 < 0; + return needs_fchdir; } #if !HAVE_FDOPENDIR @@ -164,10 +178,18 @@ fdopendir (int fd) int saved_errno; DIR *dir; - char *proc_file; - BUILD_PROC_NAME (proc_file, fd, "."); - dir = opendir (proc_file); - saved_errno = errno; + char buf[OPENAT_BUFFER_SIZE]; + char *proc_file = openat_proc_name (buf, fd, "."); + if (proc_file) + { + dir = opendir (proc_file); + saved_errno = errno; + } + else + { + dir = NULL; + saved_errno = EOPNOTSUPP; + } /* If the syscall fails with an expected errno value, resort to save_cwd/restore_cwd. */ @@ -195,6 +217,8 @@ fdopendir (int fd) if (dir) close (fd); + if (proc_file != buf) + free (proc_file); errno = saved_errno; return dir; }