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