getcwd.c uses *at() function family iff AT_FDCWD is defined.
This approach does not work on GNU/kFreeBSD - FreeBSD kernel + GNU libc.
The kernel does not provide needed interfaces, and therefore glibc
provides only stub version for function from *at() family.
But the AT_FDCWD is declared and getcwd.c uses only native i.e. openat().
Please, could you change detection whether really use *at() function
family in getcwd.
Here's an untested patch.
Please test it.
Port to GNU/kFreeBSD - FreeBSD kernel + GNU libc,
which has no openat syscall, yet <fcntl.h> does define AT_FDCWD.
* lib/getcwd.c: Undef AT_FDCWD if there is no openat function.
* modules/getcwd (Depends-on): Add openat.
Reported by Petr Salinger.
I slightly changed the patch, to be consistent with approach in lib/fts.c.
It does work for GNU/kFreeBSD.
Many thanks
Petr
diff --git a/lib/getcwd.c b/lib/getcwd.c
index b8e9989..92eed98 100644
--- a/lib/getcwd.c
+++ b/lib/getcwd.c
@@ -61,6 +61,14 @@
# define AT_FDCWD (-3041965)
#endif
+/* If this host provides the openat and fstatat functions,
+ then we can speed up some code below. */
+#ifdef HAVE_OPENAT
+# define HAVE_OPENAT_SUPPORT 1
+#else
+# define HAVE_OPENAT_SUPPORT 0
+#endif
+
#ifdef ENAMETOOLONG
# define is_ENAMETOOLONG(x) ((x) == ENAMETOOLONG)
#else
@@ -122,7 +130,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
@@ -203,7 +211,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;
@@ -230,7 +238,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;
@@ -286,7 +294,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
@@ -382,7 +390,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
@@ -408,7 +416,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
diff --git a/modules/getcwd b/modules/getcwd
index 17687e7..46ecb03 100644
--- a/modules/getcwd
+++ b/modules/getcwd
@@ -12,6 +12,7 @@ mempcpy
d-ino
dirfd
extensions
+openat
stdbool
unistd
malloc-posix