From 82bf7d1b42dc970e704f9347862594445f4a22dd Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Sat, 19 Sep 2009 05:50:30 -0600 Subject: [PATCH] openat: move fstatat and unlinkat into correct files Code motion, should be no semantic changes. * m4/openat.m4 (gl_FUNC_OPENAT): Adjust which files will be compiled. * lib/openat.c (fstatat, unlinkat): Move... * lib/fstatat.c (fstatat): ...into correct files. * lib/unlinkat.c (unlinkat): Likewise. Signed-off-by: Eric Blake --- ChangeLog | 7 +++++++ lib/fstatat.c | 48 ++++++++++++++++++++++++++++++++++++++++++++- lib/openat.c | 62 ---------------------------------------------------------- lib/unlinkat.c | 30 +++++++++++++++++++++++++++- m4/openat.m4 | 4 ++-- 5 files changed, 85 insertions(+), 66 deletions(-) diff --git a/ChangeLog b/ChangeLog index 99e084097..1b9f09a9c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2009-09-19 Eric Blake + openat: move fstatat and unlinkat into correct files + * m4/openat.m4 (gl_FUNC_OPENAT): Adjust which files will be + compiled. + * lib/openat.c (fstatat, unlinkat): Move... + * lib/fstatat.c (fstatat): ...into correct files. + * lib/unlinkat.c (unlinkat): Likewise. + openat: fix unlinkat bugs on Solaris 9 * lib/unlinkat.c (unlinkat): New file. * modules/openat (Depends-on): Add unlink. diff --git a/lib/fstatat.c b/lib/fstatat.c index 59d742224..1c6c2d30b 100644 --- a/lib/fstatat.c +++ b/lib/fstatat.c @@ -25,7 +25,9 @@ #include #include -#undef fstatat +#if HAVE_FSTATAT + +# undef fstatat /* fstatat should always follow symbolic links that end in /, but on Solaris 9 it doesn't if AT_SYMLINK_NOFOLLOW is specified. @@ -62,3 +64,47 @@ rpl_fstatat (int fd, char const *file, struct stat *st, int flag) } return result; } + +#else /* !HAVE_FSTATAT */ + +/* On mingw, the gnulib defines `stat' as a function-like + macro; but using it in AT_FUNC_F2 causes compilation failure + because the preprocessor sees a use of a macro that requires two + arguments but is only given one. Hence, we need an inline + forwarder to get past the preprocessor. */ +static inline int +stat_func (char const *name, struct stat *st) +{ + return stat (name, st); +} + +/* Likewise, if there is no native `lstat', then the gnulib + defined it as stat, which also needs adjustment. */ +# if !HAVE_LSTAT +# undef lstat +# define lstat stat_func +# endif + +/* Replacement for Solaris' function by the same name. + + First, try to simulate it via l?stat ("/proc/self/fd/FD/FILE"). + Failing that, simulate it via save_cwd/fchdir/(stat|lstat)/restore_cwd. + If either the save_cwd or the restore_cwd fails (relatively unlikely), + then give a diagnostic and exit nonzero. + Otherwise, this function works just like Solaris' fstatat. */ + +# define AT_FUNC_NAME fstatat +# define AT_FUNC_F1 lstat +# define AT_FUNC_F2 stat_func +# define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW +# define AT_FUNC_POST_FILE_PARAM_DECLS , struct stat *st, int flag +# define AT_FUNC_POST_FILE_ARGS , st +# include "at-func.c" +# undef AT_FUNC_NAME +# undef AT_FUNC_F1 +# undef AT_FUNC_F2 +# undef AT_FUNC_USE_F1_COND +# undef AT_FUNC_POST_FILE_PARAM_DECLS +# undef AT_FUNC_POST_FILE_ARGS + +#endif /* !HAVE_FSTATAT */ diff --git a/lib/openat.c b/lib/openat.c index a0d0ab455..2a194e885 100644 --- a/lib/openat.c +++ b/lib/openat.c @@ -156,65 +156,3 @@ openat_needs_fchdir (void) return needs_fchdir; } - -/* On mingw, the gnulib defines `stat' as a function-like - macro; but using it in AT_FUNC_F2 causes compilation failure - because the preprocessor sees a use of a macro that requires two - arguments but is only given one. Hence, we need an inline - forwarder to get past the preprocessor. */ -static inline int -stat_func (char const *name, struct stat *st) -{ - return stat (name, st); -} - -/* Likewise, if there is no native `lstat', then the gnulib - defined it as stat, which also needs adjustment. */ -#if !HAVE_LSTAT -# undef lstat -# define lstat stat_func -#endif - -/* Replacement for Solaris' function by the same name. - - First, try to simulate it via l?stat ("/proc/self/fd/FD/FILE"). - Failing that, simulate it via save_cwd/fchdir/(stat|lstat)/restore_cwd. - If either the save_cwd or the restore_cwd fails (relatively unlikely), - then give a diagnostic and exit nonzero. - Otherwise, this function works just like Solaris' fstatat. */ - -#define AT_FUNC_NAME fstatat -#define AT_FUNC_F1 lstat -#define AT_FUNC_F2 stat_func -#define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW -#define AT_FUNC_POST_FILE_PARAM_DECLS , struct stat *st, int flag -#define AT_FUNC_POST_FILE_ARGS , st -#include "at-func.c" -#undef AT_FUNC_NAME -#undef AT_FUNC_F1 -#undef AT_FUNC_F2 -#undef AT_FUNC_USE_F1_COND -#undef AT_FUNC_POST_FILE_PARAM_DECLS -#undef AT_FUNC_POST_FILE_ARGS - -/* Replacement for Solaris' function by the same name. - - First, try to simulate it via (unlink|rmdir) ("/proc/self/fd/FD/FILE"). - Failing that, simulate it via save_cwd/fchdir/(unlink|rmdir)/restore_cwd. - If either the save_cwd or the restore_cwd fails (relatively unlikely), - then give a diagnostic and exit nonzero. - Otherwise, this function works just like Solaris' unlinkat. */ - -#define AT_FUNC_NAME unlinkat -#define AT_FUNC_F1 rmdir -#define AT_FUNC_F2 unlink -#define AT_FUNC_USE_F1_COND AT_REMOVEDIR -#define AT_FUNC_POST_FILE_PARAM_DECLS , int flag -#define AT_FUNC_POST_FILE_ARGS /* empty */ -#include "at-func.c" -#undef AT_FUNC_NAME -#undef AT_FUNC_F1 -#undef AT_FUNC_F2 -#undef AT_FUNC_USE_F1_COND -#undef AT_FUNC_POST_FILE_PARAM_DECLS -#undef AT_FUNC_POST_FILE_ARGS diff --git a/lib/unlinkat.c b/lib/unlinkat.c index bf5d5b896..73022529e 100644 --- a/lib/unlinkat.c +++ b/lib/unlinkat.c @@ -28,7 +28,9 @@ #include "openat.h" -#undef unlinkat +#if HAVE_UNLINKAT + +# undef unlinkat /* unlinkat without AT_REMOVEDIR does not honor trailing / on Solaris 9. Solve it in a similar manner to unlink. */ @@ -75,3 +77,29 @@ rpl_unlinkat (int fd, char const *name, int flag) result = unlinkat (fd, name, flag); return result; } + +#else /* !HAVE_UNLINKAT */ + +/* Replacement for Solaris' function by the same name. + + First, try to simulate it via (unlink|rmdir) ("/proc/self/fd/FD/FILE"). + Failing that, simulate it via save_cwd/fchdir/(unlink|rmdir)/restore_cwd. + If either the save_cwd or the restore_cwd fails (relatively unlikely), + then give a diagnostic and exit nonzero. + Otherwise, this function works just like Solaris' unlinkat. */ + +# define AT_FUNC_NAME unlinkat +# define AT_FUNC_F1 rmdir +# define AT_FUNC_F2 unlink +# define AT_FUNC_USE_F1_COND AT_REMOVEDIR +# define AT_FUNC_POST_FILE_PARAM_DECLS , int flag +# define AT_FUNC_POST_FILE_ARGS /* empty */ +# include "at-func.c" +# undef AT_FUNC_NAME +# undef AT_FUNC_F1 +# undef AT_FUNC_F2 +# undef AT_FUNC_USE_F1_COND +# undef AT_FUNC_POST_FILE_PARAM_DECLS +# undef AT_FUNC_POST_FILE_ARGS + +#endif /* !HAVE_UNLINKAT */ diff --git a/m4/openat.m4 b/m4/openat.m4 index e02a11c24..b824393e5 100644 --- a/m4/openat.m4 +++ b/m4/openat.m4 @@ -1,4 +1,4 @@ -# serial 22 +# serial 23 # See if we need to use our replacement for Solaris' openat et al functions. dnl Copyright (C) 2004-2009 Free Software Foundation, Inc. @@ -25,7 +25,7 @@ AC_DEFUN([gl_FUNC_OPENAT], AC_LIBOBJ([openat-proc]) AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) AC_CHECK_FUNCS_ONCE([lchmod]) - AC_REPLACE_FUNCS([fchmodat mkdirat openat]) + AC_REPLACE_FUNCS([fchmodat fstatat mkdirat openat unlinkat]) AC_REQUIRE([AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK]) case $ac_cv_func_openat+$ac_cv_func_lstat_dereferences_slashed_symlink in yes+yes) ;; -- 2.11.0