X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fopenat-proc.c;h=2e2e966bc74820766c02b06c321c82290f46850d;hb=50901279d8e42ea4bccc2eef0a6b11e7c3dde4cf;hp=4a470c5b9d0dc5cf34c18623c9762c6ed7619dfd;hpb=5bf4ad0bfa91baa20e4f39f47bfb8b4dd00df720;p=gnulib.git diff --git a/lib/openat-proc.c b/lib/openat-proc.c index 4a470c5b9..2e2e966bc 100644 --- a/lib/openat-proc.c +++ b/lib/openat-proc.c @@ -31,7 +31,6 @@ #include #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, @@ -75,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); } }