stat: new module, for mingw bug
[gnulib.git] / lib / openat.c
index e1471b8..a0d0ab4 100644 (file)
 #include "openat-priv.h"
 #include "save-cwd.h"
 
-/* We can't use "fcntl--.h", so that openat_safer does not interfere.  */
-#if GNULIB_FCNTL_SAFER
-# include "fcntl-safer.h"
-# undef open
-# define open open_safer
-#endif
-
 /* Replacement for Solaris' openat function.
    <http://www.google.com/search?q=openat+site:docs.sun.com>
    First, try to simulate it via open ("/proc/self/fd/FD/FILE").
@@ -124,7 +117,13 @@ openat_permissive (int fd, char const *file, int flags, mode_t mode,
       if (save_ok && restore_cwd (&saved_cwd) != 0)
        {
          if (! cwd_errno)
-           openat_restore_fail (errno);
+           {
+             /* Don't write a message to just-created fd 2.  */
+             saved_errno = errno;
+             if (err == STDERR_FILENO)
+               close (err);
+             openat_restore_fail (saved_errno);
+           }
          *cwd_errno = errno;
        }
     }
@@ -158,6 +157,24 @@ openat_needs_fchdir (void)
   return needs_fchdir;
 }
 
+/* On mingw, the gnulib <sys/stat.h> 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
+   <sys/stat.h> 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.
    <http://www.google.com/search?q=fstatat+site:docs.sun.com>
    First, try to simulate it via l?stat ("/proc/self/fd/FD/FILE").
@@ -168,7 +185,7 @@ openat_needs_fchdir (void)
 
 #define AT_FUNC_NAME fstatat
 #define AT_FUNC_F1 lstat
-#define AT_FUNC_F2 stat
+#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