diff options
author | Richard Jones <rjones@redhat.com> | 2009-10-26 13:00:46 +0000 |
---|---|---|
committer | Richard Jones <rjones@redhat.com> | 2009-10-26 15:09:06 +0000 |
commit | 74bde73d5c60c13b894fa60fff680a447499c884 (patch) | |
tree | 382fc92891e690287f9fe5ff52d5ce764e71046b /daemon | |
parent | 9add3c10a3b769e309f476bd0fd05e2a7126d31d (diff) | |
download | libguestfs-74bde73d5c60c13b894fa60fff680a447499c884.tar.gz libguestfs-74bde73d5c60c13b894fa60fff680a447499c884.tar.xz libguestfs-74bde73d5c60c13b894fa60fff680a447499c884.zip |
daemon: Change chdir to use openat/fdopendir.
Uses Gnulib implementation of openat which should be portable.
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/.gitignore | 42 | ||||
-rw-r--r-- | daemon/m4/gnulib-cache.m4 | 3 | ||||
-rw-r--r-- | daemon/realpath.c | 31 |
3 files changed, 67 insertions, 9 deletions
diff --git a/daemon/.gitignore b/daemon/.gitignore index 11d8699b..6a67b90a 100644 --- a/daemon/.gitignore +++ b/daemon/.gitignore @@ -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 diff --git a/daemon/m4/gnulib-cache.m4 b/daemon/m4/gnulib-cache.m4 index df69113a..2157ceb8 100644 --- a/daemon/m4/gnulib-cache.m4 +++ b/daemon/m4/gnulib-cache.m4 @@ -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([]) diff --git a/daemon/realpath.c b/daemon/realpath.c index bfe8e676..0dc5fa5c 100644 --- a/daemon/realpath.c +++ b/daemon/realpath.c @@ -22,11 +22,12 @@ #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; } |