X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fgetcwd.c;h=6658ed58c0c4982bd073090956bec8c30ea15a56;hb=5a21606b0d57082670bd060d169492c2f3a410f2;hp=23b35de679d1e50f97d0b49cdd8932b4a9b2a3c4;hpb=4b57b2a1cba017e176f1992304b8c2900bbdb569;p=gnulib.git diff --git a/lib/getcwd.c b/lib/getcwd.c index 23b35de67..6658ed58c 100644 --- a/lib/getcwd.c +++ b/lib/getcwd.c @@ -1,25 +1,22 @@ -/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2004,2005,2006,2007 Free Software - Foundation, Inc. +/* Copyright (C) 1991-1999, 2004-2009 Free Software Foundation, Inc. This file is part of the GNU C Library. - 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 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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. */ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #if !_LIBC # include # include -# include "dirfd.h" #endif #include @@ -30,6 +27,14 @@ #include /* For AT_FDCWD on Solaris 9. */ +/* If this host provides the openat function, then enable + code below to make getcwd more efficient and robust. */ +#ifdef HAVE_OPENAT +# define HAVE_OPENAT_SUPPORT 1 +#else +# define HAVE_OPENAT_SUPPORT 0 +#endif + #ifndef __set_errno # define __set_errno(val) (errno = (val)) #endif @@ -54,20 +59,6 @@ #include -/* Work around a bug in Solaris 9 and 10: AT_FDCWD is positive. Its - value exceeds INT_MAX, so its use as an int doesn't conform to the - C standard, and GCC and Sun C complain in some cases. */ -#if 0 < AT_FDCWD && AT_FDCWD == 0xffd19553 -# undef AT_FDCWD -# define AT_FDCWD (-3041965) -#endif - -#ifdef ENAMETOOLONG -# define is_ENAMETOOLONG(x) ((x) == ENAMETOOLONG) -#else -# define is_ENAMETOOLONG(x) 0 -#endif - #ifndef MAX # define MAX(a, b) ((a) < (b) ? (b) : (a)) #endif @@ -90,7 +81,7 @@ #endif #if !_LIBC -# define __getcwd getcwd +# define __getcwd rpl_getcwd # define __lstat lstat # define __closedir closedir # define __opendir opendir @@ -98,7 +89,11 @@ #endif /* The results of opendir() in this file are not used with dirfd and fchdir, - therefore save some unnecessary recursion in fchdir.c. */ + and we do not leak fds to any single-threaded code that could use stdio, + therefore save some unnecessary recursion in fchdir.c. + FIXME - if the kernel ever adds support for multi-thread safety for + avoiding standard fds, then we should use opendir_safer and + openat_safer. */ #undef opendir #undef closedir @@ -123,7 +118,7 @@ __getcwd (char *buf, size_t size) DEEP_NESTING = 100 }; -#ifdef AT_FDCWD +#if HAVE_OPENAT_SUPPORT int fd = AT_FDCWD; bool fd_needs_closing = false; #else @@ -155,7 +150,7 @@ __getcwd (char *buf, size_t size) # undef getcwd dir = getcwd (buf, size); - if (dir || (errno != ERANGE && !is_ENAMETOOLONG (errno) && errno != ENOENT)) + if (dir || (errno != ERANGE && errno != ENAMETOOLONG && errno != ENOENT)) return dir; #endif @@ -204,7 +199,7 @@ __getcwd (char *buf, size_t size) bool use_d_ino = true; /* Look at the parent directory. */ -#ifdef AT_FDCWD +#if HAVE_OPENAT_SUPPORT fd = openat (fd, "..", O_RDONLY); if (fd < 0) goto lose; @@ -231,7 +226,7 @@ __getcwd (char *buf, size_t size) mount_point = dotdev != thisdev; /* Search for the last directory. */ -#ifdef AT_FDCWD +#if HAVE_OPENAT_SUPPORT dirstream = fdopendir (fd); if (dirstream == NULL) goto lose; @@ -287,7 +282,7 @@ __getcwd (char *buf, size_t size) { int entry_status; -#ifdef AT_FDCWD +#if HAVE_OPENAT_SUPPORT entry_status = fstatat (fd, d->d_name, &st, AT_SYMLINK_NOFOLLOW); #else /* Compute size needed for this file name, or for the file @@ -383,7 +378,7 @@ __getcwd (char *buf, size_t size) if (dirp == &dir[allocated - 1]) *--dirp = '/'; -#ifndef AT_FDCWD +#if ! HAVE_OPENAT_SUPPORT if (dotlist != dots) free (dotlist); #endif @@ -409,7 +404,7 @@ __getcwd (char *buf, size_t size) int save = errno; if (dirstream) __closedir (dirstream); -#ifdef AT_FDCWD +#if HAVE_OPENAT_SUPPORT if (fd_needs_closing) close (fd); #else