bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: bug#13516: tests/rm/unread3 fails on Mac OS X 10.8


From: Paul Eggert
Subject: Re: bug#13516: tests/rm/unread3 fails on Mac OS X 10.8
Date: Thu, 24 Jan 2013 09:03:27 -0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130110 Thunderbird/17.0.2

Thanks, could you please try the following patch?
This is a gnulib patch, so it also fixes modules/fdopendir --
you needn't worry about that part of the patch,
as it doesn't apply to coreutils.
I'm CC'ing this possible patch to bug-gnulib to give
the Gnulib people a heads-up.

By the way, do you happen to know why OS X doesn't
yet support fdopendir?  It's been in the standard for ages.
Do the OSX maintainers plan to implement it eventually?

----

Break a recursive loop between fdopendir and save_cwd.
Reported for OS X 10.8 by Assaf Gordon in <http://bugs.gnu.org/13516>.
* lib/fdopendir.c [!HAVE_FDOPENDIR]: Don't include save-cwd.h.
(fdopendir): Don't try to invoke getcwd via save_cwd,
since it invokes us.  Instead, merely open the working directory
and return a failure indication if that fails.
(fdopendir_with_dup): Second arg is now a fd (or -1), not a
struct saved_cwd * (or 0).  All uses changed.
* modules/fdopendir (Depends-on): Remove save-cwd.
diff --git a/lib/fdopendir.c b/lib/fdopendir.c
index 63e06b9..25e984b 100644
--- a/lib/fdopendir.c
+++ b/lib/fdopendir.c
@@ -27,7 +27,6 @@

 # include "openat.h"
 # include "openat-priv.h"
-# include "save-cwd.h"

 # if GNULIB_DIRENT_SAFER
 #  include "dirent--.h"
@@ -37,15 +36,15 @@
 #  define REPLACE_FCHDIR 0
 # endif

-static DIR *fdopendir_with_dup (int, int, struct saved_cwd const *);
-static DIR *fd_clone_opendir (int, struct saved_cwd const *);
+static DIR *fdopendir_with_dup (int, int, int);
+static DIR *fd_clone_opendir (int, int);

 /* Replacement for POSIX fdopendir.

    First, try to simulate it via opendir ("/proc/self/fd/...").  Failing
    that, simulate it by using fchdir metadata, or by doing
-   save_cwd/fchdir/opendir(".")/restore_cwd.
-   If either the save_cwd or the restore_cwd fails (relatively unlikely),
+   open(".")/fchdir/opendir(".")/fchdir.
+   If the final fchdir fails (relatively unlikely),
    then give a diagnostic and exit nonzero.

    If successful, the resulting stream is based on FD in
@@ -65,19 +64,19 @@ static DIR *fd_clone_opendir (int, struct saved_cwd const 
*);
 DIR *
 fdopendir (int fd)
 {
-  DIR *dir = fdopendir_with_dup (fd, -1, NULL);
+  DIR *dir = fdopendir_with_dup (fd, -1, -1);

   if (! REPLACE_FCHDIR && ! dir)
     {
       int saved_errno = errno;
       if (EXPECTED_ERRNO (saved_errno))
         {
-          struct saved_cwd cwd;
-          if (save_cwd (&cwd) != 0)
-            openat_save_fail (errno);
-          dir = fdopendir_with_dup (fd, -1, &cwd);
+          int cwd = open (".", O_SEARCH);
+          if (cwd < 0)
+            return 0;
+          dir = fdopendir_with_dup (fd, -1, cwd);
           saved_errno = errno;
-          free_cwd (&cwd);
+          close (cwd);
           errno = saved_errno;
         }
     }
@@ -93,11 +92,11 @@ fdopendir (int fd)
    That way, barring race conditions, fd_clone_opendir returns a
    stream whose file descriptor is FD.

-   If REPLACE_CHDIR or CWD is null, use opendir ("/proc/self/fd/...",
+   If REPLACE_CHDIR or CWD < 0, use opendir ("/proc/self/fd/...",
    falling back on fchdir metadata.  Otherwise, CWD is a saved version
-   of the working directory; use fchdir/opendir(".")/restore_cwd(CWD).  */
+   of the working directory; use fchdir/opendir(".")/fchdir(CWD).  */
 static DIR *
-fdopendir_with_dup (int fd, int older_dupfd, struct saved_cwd const *cwd)
+fdopendir_with_dup (int fd, int older_dupfd, int cwd)
 {
   int dupfd = dup (fd);
   if (dupfd < 0 && errno == EMFILE)
@@ -137,9 +136,9 @@ fdopendir_with_dup (int fd, int older_dupfd, struct 
saved_cwd const *cwd)
    the caller's responsibility both to close FD and (if the result is
    not null) to closedir the result.  */
 static DIR *
-fd_clone_opendir (int fd, struct saved_cwd const *cwd)
+fd_clone_opendir (int fd, int cwd)
 {
-  if (REPLACE_FCHDIR || ! cwd)
+  if (REPLACE_FCHDIR || cwd < 0)
     {
       DIR *dir = NULL;
       int saved_errno = EOPNOTSUPP;
@@ -170,7 +169,7 @@ fd_clone_opendir (int fd, struct saved_cwd const *cwd)
         {
           DIR *dir = opendir (".");
           int saved_errno = errno;
-          if (restore_cwd (cwd) != 0)
+          if (fchdir (cwd) != 0)
             openat_restore_fail (errno);
           errno = saved_errno;
           return dir;
diff --git a/modules/fdopendir b/modules/fdopendir
index ee9a875..3d99472 100644
--- a/modules/fdopendir
+++ b/modules/fdopendir
@@ -15,7 +15,6 @@ fchdir          [test $HAVE_FDOPENDIR = 0]
 fstat           [test $HAVE_FDOPENDIR = 0]
 openat-die      [test $HAVE_FDOPENDIR = 0]
 opendir         [test $HAVE_FDOPENDIR = 0]
-save-cwd        [test $HAVE_FDOPENDIR = 0]

 configure.ac:
 gl_FUNC_FDOPENDIR



reply via email to

[Prev in Thread] Current Thread [Next in Thread]