daemon: Change chdir to use openat/fdopendir.
authorRichard Jones <rjones@redhat.com>
Mon, 26 Oct 2009 13:00:46 +0000 (13:00 +0000)
committerRichard Jones <rjones@redhat.com>
Mon, 26 Oct 2009 15:09:06 +0000 (15:09 +0000)
Uses Gnulib implementation of openat which should be portable.

daemon/.gitignore
daemon/m4/gnulib-cache.m4
daemon/realpath.c
m4/.gitignore

index 11d8699..6a67b90 100644 (file)
@@ -2,10 +2,31 @@ build-aux
 lib
 link-warning.h
 m4/00gnulib.m4
+m4/alloca.m4
+m4/canonicalize-lgpl.m4
+m4/chdir-long.m4
+m4/chown.m4
+m4/close.m4
+m4/d-ino.m4
+m4/dirent_h.m4
+m4/dirfd.m4
+m4/dirname.m4
+m4/dos.m4
+m4/double-slash-root.m4
+m4/dup2.m4
+m4/eealloc.m4
 m4/errno_h.m4
 m4/error.m4
 m4/exitfail.m4
 m4/extensions.m4
+m4/fchdir.m4
+m4/fclose.m4
+m4/fcntl-safer.m4
+m4/fcntl_h.m4
+m4/getcwd-abort-bug.m4
+m4/getcwd-path-max.m4
+m4/getcwd.m4
+m4/getpagesize.m4
 m4/gnulib-common.m4
 m4/gnulib-comp.m4
 m4/gnulib-tool.m4
@@ -13,20 +34,41 @@ m4/hash.m4
 m4/include_next.m4
 m4/inline.m4
 m4/inttostr.m4
+m4/lchown.m4
 m4/longlong.m4
+m4/lstat.m4
+m4/malloc.m4
+m4/malloca.m4
 m4/manywarnings.m4
+m4/memchr.m4
+m4/mempcpy.m4
+m4/memrchr.m4
+m4/mmap-anon.m4
+m4/mode_t.m4
 m4/multiarch.m4
 m4/onceonly.m4
+m4/open.m4
+m4/openat.m4
+m4/pathmax.m4
+m4/readlink.m4
+m4/save-cwd.m4
 m4/stdbool.m4
 m4/stddef_h.m4
 m4/stdint.m4
+m4/stdio_h.m4
 m4/stdlib_h.m4
 m4/strerror.m4
 m4/string_h.m4
+m4/strndup.m4
+m4/strnlen.m4
+m4/sys_stat_h.m4
+m4/unistd-safer.m4
 m4/unistd_h.m4
 m4/warnings.m4
 m4/wchar.m4
 m4/wchar_t.m4
 m4/wint_t.m4
 m4/xalloc.m4
+m4/xgetcwd.m4
+m4/xstrndup.m4
 tests
index df69113..2157ceb 100644 (file)
@@ -15,7 +15,7 @@
 
 
 # Specification in the form of a command-line invocation:
-#   gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --with-tests --no-libtool --macro-prefix=gl c-ctype hash ignore-value manywarnings warnings
+#   gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --with-tests --no-libtool --macro-prefix=gl c-ctype hash ignore-value manywarnings openat warnings
 
 # Specification in the form of a few gnulib-tool.m4 macro invocations:
 gl_LOCAL_DIR([])
@@ -24,6 +24,7 @@ gl_MODULES([
   hash
   ignore-value
   manywarnings
+  openat
   warnings
 ])
 gl_AVOID([])
index bfe8e67..0dc5fa5 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <limits.h>
 #include <sys/types.h>
 #include <dirent.h>
 
-#include "ignore-value.h"
+#include "openat.h"
 
 #include "daemon.h"
 #include "actions.h"
@@ -52,9 +53,13 @@ do_case_sensitive_path (const char *path)
 {
   char ret[PATH_MAX+1] = "/";
   size_t next = 1;
+  int fd_cwd;
 
-  /* MUST chdir ("/") before leaving this function. */
-  if (chdir (sysroot) == -1) {
+  /* 'fd_cwd' here is a surrogate for the current working directory, so
+   * that we don't have to actually call chdir(2).
+   */
+  fd_cwd = open (sysroot, O_RDONLY | O_DIRECTORY);
+  if (fd_cwd == -1) {
     reply_with_perror ("%s", sysroot);
     return NULL;
   }
@@ -93,7 +98,12 @@ do_case_sensitive_path (const char *path)
     /* Read the current directory looking (case insensitively) for
      * this element of the path.
      */
-    DIR *dir = opendir (".");
+    int fd2 = dup (fd_cwd); /* because closedir will close it */
+    if (fd2 == -1) {
+      reply_with_perror ("dup");
+      goto error;
+    }
+    DIR *dir = fdopendir (fd2);
     if (dir == NULL) {
       reply_with_perror ("opendir");
       goto error;
@@ -136,10 +146,15 @@ do_case_sensitive_path (const char *path)
     next += i;
 
     /* Is it a directory?  Try going into it. */
-    if (chdir (d->d_name) == -1) {
+    fd2 = openat (fd_cwd, d->d_name, O_RDONLY | O_DIRECTORY);
+    int err = errno;
+    close (fd_cwd);
+    fd_cwd = fd2;
+    errno = err;
+    if (fd_cwd == -1) {
       /* ENOTDIR is OK provided we've reached the end of the path. */
       if (errno != ENOTDIR) {
-        reply_with_perror ("chdir: %s", d->d_name);
+        reply_with_perror ("openat: %s", d->d_name);
         goto error;
       }
 
@@ -150,7 +165,7 @@ do_case_sensitive_path (const char *path)
     }
   }
 
-  ignore_value (chdir ("/"));
+  close (fd_cwd);
 
   ret[next] = '\0';
   char *retp = strdup (ret);
@@ -161,6 +176,6 @@ do_case_sensitive_path (const char *path)
   return retp;                  /* caller frees */
 
  error:
-  ignore_value (chdir ("/"));
+  close (fd_cwd);
   return NULL;
 }
index f158aa3..d5082d7 100644 (file)
@@ -90,3 +90,36 @@ xsize.m4
 /netinet_in_h.m4
 /sockpfaf.m4
 /sys_socket_h.m4
+/canonicalize-lgpl.m4
+/chdir-long.m4
+/chown.m4
+/close.m4
+/d-ino.m4
+/dirent_h.m4
+/dirfd.m4
+/dirname.m4
+/dos.m4
+/double-slash-root.m4
+/dup2.m4
+/fchdir.m4
+/fclose.m4
+/fcntl-safer.m4
+/fcntl_h.m4
+/getcwd-abort-bug.m4
+/getcwd-path-max.m4
+/getcwd.m4
+/lchown.m4
+/lstat.m4
+/malloc.m4
+/mempcpy.m4
+/memrchr.m4
+/mode_t.m4
+/open.m4
+/openat.m4
+/pathmax.m4
+/readlink.m4
+/save-cwd.m4
+/sys_stat_h.m4
+/unistd-safer.m4
+/xgetcwd.m4
+/xstrndup.m4