about summary refs log tree commit diff
path: root/sysdeps/mach/hurd/opendir.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/mach/hurd/opendir.c')
-rw-r--r--sysdeps/mach/hurd/opendir.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/sysdeps/mach/hurd/opendir.c b/sysdeps/mach/hurd/opendir.c
index c71cb18a65..175944418c 100644
--- a/sysdeps/mach/hurd/opendir.c
+++ b/sysdeps/mach/hurd/opendir.c
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <hurd.h>
 #include <hurd/fd.h>
+#include <not-cancel.h>
 #include "dirstream.h"
 
 
@@ -67,10 +68,45 @@ _hurd_fd_opendir (struct hurd_fd *d)
 }
 
 
+DIR *
+internal_function
+__opendirat (int dfd, const char *name)
+{
+  if (name[0] == '\0')
+    {
+      /* POSIX.1-1990 says an empty name gets ENOENT;
+	 but `open' might like it fine.  */
+      __set_errno (ENOENT);
+      return NULL;
+    }
+
+  int flags = O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC;
+  int fd;
+#ifdef IS_IN_rtld
+  assert (dfd == AT_FDCWD);
+  fd = open_not_cancel_2 (name, flags);
+#else
+  fd = openat_not_cancel_3 (dfd, name, flags);
+#endif
+  if (fd < 0)
+    return NULL;
+
+  /* Extract the pointer to the descriptor structure.  */
+  DIR *dirp = _hurd_fd_opendir (_hurd_fd_get (fd));
+  if (dirp == NULL)
+    __close (fd);
+
+  return dirp;
+}
+
+
 /* Open a directory stream on NAME.  */
 DIR *
 __opendir (const char *name)
 {
+#if 0 /* TODO.  */
+  return __opendirat (AT_FDCWD, name);
+#else
   if (name[0] == '\0')
     {
       /* POSIX.1-1990 says an empty name gets ENOENT;
@@ -89,5 +125,6 @@ __opendir (const char *name)
     __close (fd);
 
   return dirp;
+#endif
 }
 weak_alias (__opendir, opendir)