X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fopenat-proc.c;h=25384127ebf944f7aeb83ef11e40ef19afb34776;hb=3213c107e7632d3b7e462c06acaefde7d50e5067;hp=ff2fff0033a7a5cbb4d68e822ef91484a69f66c9;hpb=854ebf64dc7dae95a43a4e139e075156d2add805;p=gnulib.git diff --git a/lib/openat-proc.c b/lib/openat-proc.c index ff2fff003..25384127e 100644 --- a/lib/openat-proc.c +++ b/lib/openat-proc.c @@ -1,11 +1,11 @@ /* Create /proc/self/fd-related names for subfiles of open directories. - Copyright (C) 2006 Free Software Foundation, Inc. + Copyright (C) 2006, 2009-2010 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,8 +13,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software Foundation, - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* Written by Paul Eggert. */ @@ -28,6 +27,7 @@ #include #include +#include #include "dirname.h" #include "intprops.h" @@ -35,7 +35,10 @@ #include "xalloc.h" /* The results of open() in this file are not used with fchdir, - therefore save some unnecessary work in fchdir.c. */ + and we do not leak fds to any single-threaded code that could use stdio, + therefore save some unnecessary work in fchdir.c. + FIXME - if the kernel ever adds support for multi-thread safety for + avoiding standard fds, then we should use open_safer. */ #undef open #undef close @@ -55,32 +58,39 @@ openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char const *file) { static int proc_status = 0; + /* Make sure the caller gets ENOENT when appropriate. */ + if (!*file) + { + buf[0] = '\0'; + return buf; + } + if (! proc_status) { /* Set PROC_STATUS to a positive value if /proc/self/fd is - reliable, and a negative value otherwise. Solaris 10 - /proc/self/fd mishandles "..", and any file name might expand - to ".." after symbolic link expansion, so avoid /proc/self/fd - if it mishandles "..". Solaris 10 has openat, but this - problem is exhibited on code that built on Solaris 8 and - running on Solaris 10. */ + reliable, and a negative value otherwise. Solaris 10 + /proc/self/fd mishandles "..", and any file name might expand + to ".." after symbolic link expansion, so avoid /proc/self/fd + if it mishandles "..". Solaris 10 has openat, but this + problem is exhibited on code that built on Solaris 8 and + running on Solaris 10. */ int proc_self_fd = open ("/proc/self/fd", O_RDONLY); if (proc_self_fd < 0) - proc_status = -1; + 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); - close (proc_self_fd); - } + { + 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); + close (proc_self_fd); + } } if (proc_status < 0)