X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fopenat-proc.c;h=2e2e966bc74820766c02b06c321c82290f46850d;hb=1d71dc7c690b5fe61e3e0c06303ffb59434bba4b;hp=34c74a70849065b415a72731a97737e9169be2ad;hpb=2392b18099a64ffb7aa2cf4fa3c81da96d2a5fc1;p=gnulib.git diff --git a/lib/openat-proc.c b/lib/openat-proc.c index 34c74a708..2e2e966bc 100644 --- a/lib/openat-proc.c +++ b/lib/openat-proc.c @@ -30,9 +30,7 @@ #include #include -#include "dirname.h" #include "intprops.h" -#include "same-inode.h" /* The results of open() in this file are not used with fchdir, and we do not leak fds to any single-threaded code that could use stdio, @@ -76,20 +74,20 @@ openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file) problem is exhibited on code that built on Solaris 8 and running on Solaris 10. */ - int proc_self_fd = open ("/proc/self/fd", O_SEARCH); + int proc_self_fd = open ("/proc/self/fd", + O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NONBLOCK); if (proc_self_fd < 0) proc_status = -1; else { - struct stat proc_self_fd_dotdot_st; - struct stat proc_self_st; - char dotdot_buf[PROC_SELF_FD_NAME_SIZE_BOUND (sizeof ".." - 1)]; - sprintf (dotdot_buf, PROC_SELF_FD_FORMAT, proc_self_fd, ".."); - proc_status = - ((stat (dotdot_buf, &proc_self_fd_dotdot_st) == 0 - && stat ("/proc/self", &proc_self_st) == 0 - && SAME_INODE (proc_self_fd_dotdot_st, proc_self_st)) - ? 1 : -1); + /* Detect whether /proc/self/fd/%i/../fd exists, where %i is the + number of a file descriptor open on /proc/self/fd. On Linux, + that name resolves to /proc/self/fd, which was opened above. + However, on Solaris, it may resolve to /proc/self/fd/fd, which + cannot exist, since all names in /proc/self/fd are numeric. */ + char dotdot_buf[PROC_SELF_FD_NAME_SIZE_BOUND (sizeof "../fd" - 1)]; + sprintf (dotdot_buf, PROC_SELF_FD_FORMAT, proc_self_fd, "../fd"); + proc_status = access (dotdot_buf, F_OK) ? -1 : 1; close (proc_self_fd); } }