bug-gnulib
[Top][All Lists]
Advanced

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

Re: dirent.h on MSVC


From: Bruno Haible
Subject: Re: dirent.h on MSVC
Date: Tue, 13 Sep 2011 01:40:01 +0200
User-agent: KMail/1.13.6 (Linux/2.6.37.6-0.5-desktop; KDE/4.6.0; x86_64; ; )

Here comes a working implementation of the <dirent.h> function for MSVC.

I'm not implementing telldir() and seekdir() because these functions
  - are marked as XSI in POSIX,
  - would be inefficient
  - are anyway unreliable (if the contents of the directory has changed).

Note that
  - 'readdir' depends on 'largefile', because of readdir64 on glibc and
    (similarly) Solaris and MacOS X systems,
  - 'opendir' and 'rewinddir' depend on 'largefile' as well, because
    MacOS X has the functions opendir$INODE64$UNIX2003 and
    rewinddir$INODE64$UNIX2003.


2011-09-12  Bruno Haible  <address@hidden>

        New modules 'opendir', 'readdir', 'rewinddir', 'closedir'.
        * lib/dirent.in.h (struct dirent): New type.
        (DT_UNKNOWN, DT_FIFO, DT_CHR, DT_DIR, DT_BLK, DT_REG, DT_LNK, DT_SOCK,
        DT_WHT): New macros.
        (DIR): New type.
        (opendir, closedir): Declare only if the module 'opendir' is enabled.
        (readdir, rewinddir): New declarations.
        * lib/dirent-private.h: New file.
        * lib/opendir.c: New file.
        * lib/readdir.c: New file.
        * lib/rewinddir.c: New file.
        * lib/closedir.c: New file.
        * lib/fchdir.c (rpl_closedir, rpl_opendir): Remove functions.
        * m4/opendir.m4: New file.
        * m4/readdir.m4: New file.
        * m4/rewinddir.m4: New file.
        * m4/closedir.m4: New file.
        * m4/fchdir.m4 (gl_FUNC_FCHDIR): Don't set REPLACE_OPENDIR,
        REPLACE_CLOSEDIR here.
        * m4/dirent_h.m4 (gl_DIRENT_H): Also check whether closedir, opendir,
        readdir, rewinddir are declared.
        (gl_DIRENT_H_DEFAULTS): Initialize GNULIB_OPENDIR, GNULIB_READDIR,
        GNULIB_REWINDDIR, GNULIB_CLOSEDIR, HAVE_OPENDIR, HAVE_READDIR,
        HAVE_REWINDDIR, HAVE_CLOSEDIR.
        * modules/dirent (Makefile.am): Substitute GNULIB_OPENDIR,
        GNULIB_READDIR, GNULIB_REWINDDIR, GNULIB_CLOSEDIR, HAVE_OPENDIR,
        HAVE_READDIR, HAVE_REWINDDIR, HAVE_CLOSEDIR.
        * modules/opendir: New file.
        * modules/readdir: New file.
        * modules/rewinddir: New file.
        * modules/closedir: New file.
        * doc/posix-functions/opendir.texi: Mention the 'opendir' module.
        * doc/posix-functions/readdir.texi: Mention the 'readdir' module.
        * doc/posix-functions/rewinddir.texi: Mention the 'rewinddir' module.
        * doc/posix-functions/closedir.texi: Mention the 'closedir' module.
        * NEWS: Mention the 'fchdir' change.

============================= lib/dirent-private.h =============================
/* Private details of the DIR type.
   Copyright (C) 2011 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef _DIRENT_PRIVATE_H
#define _DIRENT_PRIVATE_H 1

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

struct gl_directory
{
  /* Status, or error code to produce in next readdir() call.
     -2 means the end of the directory is already reached,
     -1 means the entry was already filled by FindFirstFile,
     0 means the entry needs to be filled using FindNextFile.
     A positive value is an error code.  */
  int status;
  /* Handle, reading the directory, at current position.  */
  HANDLE current;
  /* Found directory entry.  */
  WIN32_FIND_DATA entry;
  /* Argument to pass to FindFirstFile.  It consists of the absolutized
     directory name, followed by a directory separator and the wildcards.  */
  char dir_name_mask[1];
};

#endif /* _DIRENT_PRIVATE_H */
================================ lib/opendir.c ================================
/* Start reading the entries of a directory.
   Copyright (C) 2006-2011 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <config.h>

/* Specification.  */
#include <dirent.h>

#if HAVE_OPENDIR

/* Override opendir(), to keep track of the open file descriptors.
   Needed because there is a function dirfd().  */

#else

# include <errno.h>
# include <stddef.h>
# include <stdlib.h>

# include "dirent-private.h"
# include "filename.h"

#endif

DIR *
opendir (const char *dir_name)
{
#if HAVE_OPENDIR
# undef opendir
  DIR *dirp;

  dirp = opendir (dir_name);
  if (dirp == NULL)
    return NULL;

#else

  char dir_name_mask[MAX_PATH + 1 + 1 + 1];
  int status;
  HANDLE current;
  WIN32_FIND_DATA entry;
  struct gl_directory *dirp;

  if (dir_name[0] == '\0')
    {
      errno = ENOENT;
      return NULL;
    }

  /* Make the dir_name absolute, so that we continue reading the same
     directory if the current directory changed between this opendir()
     call and a subsequent rewinddir() call.  */
  if (!GetFullPathName (dir_name, MAX_PATH, dir_name_mask, NULL))
    {
      errno = EINVAL;
      return NULL;
    }

  /* Append the mask.
     "*" and "*.*" appear to be equivalent.  */
  {
    char *p;

    p = dir_name_mask + strlen (dir_name_mask);
    if (p > dir_name_mask && !ISSLASH (p[-1]))
      *p++ = '\\';
    *p++ = '*';
    *p = '\0';
  }

  /* Start searching the directory.  */
  status = -1;
  current = FindFirstFile (dir_name_mask, &entry);
  if (current == INVALID_HANDLE_VALUE)
    {
      switch (GetLastError ())
        {
        case ERROR_FILE_NOT_FOUND:
          status = -2;
          break;
        case ERROR_PATH_NOT_FOUND:
          errno = ENOENT;
          return NULL;
        case ERROR_DIRECTORY:
          errno = ENOTDIR;
          return NULL;
        case ERROR_ACCESS_DENIED:
          errno = EACCES;
          return NULL;
        default:
          errno = EIO;
          return NULL;
        }
    }

  /* Allocate the result.  */
  dirp =
    (struct gl_directory *)
    malloc (offsetof (struct gl_directory, dir_name_mask[0])
            + strlen (dir_name_mask) + 1);
  if (dirp == NULL)
    {
      if (current != INVALID_HANDLE_VALUE)
        FindClose (current);
      errno = ENOMEM;
      return NULL;
    }
  dirp->status = status;
  dirp->current = current;
  if (status == -1)
    memcpy (&dirp->entry, &entry, sizeof (WIN32_FIND_DATA));
  strcpy (dirp->dir_name_mask, dir_name_mask);

#endif

#if REPLACE_FCHDIR
  {
    int fd = dirfd (dirp);
    if (0 <= fd && _gl_register_fd (fd, dir_name) != fd)
      {
        int saved_errno = errno;
        closedir (dirp);
        errno = saved_errno;
        return NULL;
      }
  }
#endif

  return dirp;
}
================================ lib/readdir.c ================================
/* Read the next entry of a directory.
   Copyright (C) 2011 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <config.h>

/* Specification.  */
#include <dirent.h>

#include <errno.h>
#include <stddef.h>

#include "dirent-private.h"

struct dirent *
readdir (DIR *dirp)
{
  char type;
  struct dirent *result;

  /* There is no need to add code to produce entries for "." and "..".
     According to the POSIX:2008 section "4.12 Pathname Resolution"
     <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html>
     "." and ".." are syntactic entities.
     POSIX also says:
       "If entries for dot or dot-dot exist, one entry shall be returned
        for dot and one entry shall be returned for dot-dot; otherwise,
        they shall not be returned."  */

  switch (dirp->status)
    {
    case -2:
      /* End of directory already reached.  */
      return NULL;
    case -1:
      break;
    case 0:
      if (!FindNextFile (dirp->current, &dirp->entry))
        {
          switch (GetLastError ())
            {
            case ERROR_NO_MORE_FILES:
              dirp->status = -2;
              return NULL;
            default:
              errno = EIO;
              return NULL;
            }
        }
      break;
    default:
      errno = dirp->status;
      return NULL;
    }

  dirp->status = 0;

  if (dirp->entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    type = DT_DIR;
  else if (dirp->entry.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
    type = DT_LNK;
  else if ((dirp->entry.dwFileAttributes
            & ~(FILE_ATTRIBUTE_READONLY
                | FILE_ATTRIBUTE_HIDDEN
                | FILE_ATTRIBUTE_SYSTEM
                | FILE_ATTRIBUTE_ARCHIVE
                | FILE_ATTRIBUTE_NORMAL
                | FILE_ATTRIBUTE_TEMPORARY
                | FILE_ATTRIBUTE_SPARSE_FILE
                | FILE_ATTRIBUTE_COMPRESSED
                | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
                | FILE_ATTRIBUTE_ENCRYPTED)) == 0)
    /* Devices like COM1, LPT1, NUL would also have the attributes 0x20 but
       they cannot occur here.  */
    type = DT_REG;
  else
    type = DT_UNKNOWN;

  /* Reuse the memory of dirp->entry for the result.  */
  result =
    (struct dirent *)
    ((char *) dirp->entry.cFileName - offsetof (struct dirent, d_name[0]));
  result->d_type = type;

  return result;
}
=============================== lib/rewinddir.c ===============================
/* Restart reading the entries of a directory from the beginning.
   Copyright (C) 2011 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <config.h>

/* Specification.  */
#include <dirent.h>

#include <errno.h>

#include "dirent-private.h"

void
rewinddir (DIR *dirp)
{
  /* Like in closedir().  */
  if (dirp->current != INVALID_HANDLE_VALUE)
    FindClose (dirp->current);

  /* Like in opendir().  */
  dirp->status = -1;
  dirp->current = FindFirstFile (dirp->dir_name_mask, &dirp->entry);
  if (dirp->current == INVALID_HANDLE_VALUE)
    {
      switch (GetLastError ())
        {
        case ERROR_FILE_NOT_FOUND:
          dirp->status = -2;
          break;
        default:
          /* Save the error code for the next readdir() call.  */
          dirp->status = ENOENT;
          break;
        }
    }
}
================================ lib/closedir.c ================================
/* Stop reading the entries of a directory.
   Copyright (C) 2006-2011 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <config.h>

/* Specification.  */
#include <dirent.h>

#if HAVE_CLOSEDIR

/* Override closedir(), to keep track of the open file descriptors.
   Needed because there is a function dirfd().  */

#else

# include <stdlib.h>

# include "dirent-private.h"

#endif

int
closedir (DIR *dirp)
{
# if REPLACE_FCHDIR
  int fd = dirfd (dirp);
# endif
  int retval;

#if HAVE_CLOSEDIR
# undef closedir

  retval = closedir (dirp);

#else

  if (dirp->current != INVALID_HANDLE_VALUE)
    FindClose (dirp->current);
  free (dirp);

  retval = 0;

#endif

#if REPLACE_FCHDIR
  if (retval >= 0)
    _gl_unregister_fd (fd);
#endif
  return retval;
}
================================ m4/opendir.m4 ================================
# opendir.m4 serial 1
dnl Copyright (C) 2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.

AC_DEFUN([gl_FUNC_OPENDIR],
[
  AC_REQUIRE([gl_DIRENT_H_DEFAULTS])

  AC_CHECK_FUNCS([opendir])
  if test $ac_cv_func_opendir = no; then
    HAVE_OPENDIR=0
  fi
  dnl Replace opendir() for supporting the gnulib-defined fchdir() function,
  dnl to keep fchdir's bookkeeping up-to-date.
  m4_ifdef([gl_FUNC_FCHDIR], [
    gl_TEST_FCHDIR
    if test $HAVE_FCHDIR = 0; then
      REPLACE_OPENDIR=1
    fi
  ])
])
================================ m4/readdir.m4 ================================
# readdir.m4 serial 1
dnl Copyright (C) 2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.

AC_DEFUN([gl_FUNC_READDIR],
[
  AC_REQUIRE([gl_DIRENT_H_DEFAULTS])

  AC_CHECK_FUNCS([readdir])
  if test $ac_cv_func_readdir = no; then
    HAVE_READDIR=0
  fi
])
=============================== m4/rewinddir.m4 ===============================
# rewinddir.m4 serial 1
dnl Copyright (C) 2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.

AC_DEFUN([gl_FUNC_REWINDDIR],
[
  AC_REQUIRE([gl_DIRENT_H_DEFAULTS])

  AC_CHECK_FUNCS([rewinddir])
  if test $ac_cv_func_rewinddir = no; then
    HAVE_REWINDDIR=0
  fi
])
================================ m4/closedir.m4 ================================
# closedir.m4 serial 1
dnl Copyright (C) 2011 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.

AC_DEFUN([gl_FUNC_CLOSEDIR],
[
  AC_REQUIRE([gl_DIRENT_H_DEFAULTS])

  AC_CHECK_FUNCS([closedir])
  if test $ac_cv_func_closedir = no; then
    HAVE_CLOSEDIR=0
  fi
  dnl Replace closedir() for supporting the gnulib-defined fchdir() function,
  dnl to keep fchdir's bookkeeping up-to-date.
  m4_ifdef([gl_FUNC_FCHDIR], [
    gl_TEST_FCHDIR
    if test $HAVE_FCHDIR = 0; then
      REPLACE_CLOSEDIR=1
    fi
  ])
])
=============================== modules/opendir ===============================
Description:
opendir() function: start reading the entries of a directory

Files:
lib/opendir.c
lib/dirent-private.h
m4/opendir.m4

Depends-on:
dirent
largefile
filename        [test $HAVE_OPENDIR = 0 || test $REPLACE_OPENDIR = 1]

configure.ac:
gl_FUNC_OPENDIR
if test $HAVE_OPENDIR = 0 || test $REPLACE_OPENDIR = 1; then
  AC_LIBOBJ([opendir])
fi
gl_DIRENT_MODULE_INDICATOR([opendir])

Makefile.am:

Include:
<dirent.h>

License:
LGPL

Maintainer:
Bruno Haible
=============================== modules/readdir ===============================
Description:
readdir() function: read the next entry of a directory

Files:
lib/readdir.c
lib/dirent-private.h
m4/readdir.m4

Depends-on:
dirent
largefile

configure.ac:
gl_FUNC_READDIR
if test $HAVE_READDIR = 0; then
  AC_LIBOBJ([readdir])
fi
gl_DIRENT_MODULE_INDICATOR([readdir])

Makefile.am:

Include:
<dirent.h>

License:
LGPL

Maintainer:
Bruno Haible
============================== modules/rewinddir ==============================
Description:
rewinddir() function: restart reading the entries of a directory from the
beginning

Files:
lib/rewinddir.c
lib/dirent-private.h
m4/rewinddir.m4

Depends-on:
dirent
largefile

configure.ac:
gl_FUNC_REWINDDIR
if test $HAVE_REWINDDIR = 0; then
  AC_LIBOBJ([rewinddir])
fi
gl_DIRENT_MODULE_INDICATOR([rewinddir])

Makefile.am:

Include:
<dirent.h>

License:
LGPL

Maintainer:
Bruno Haible
=============================== modules/closedir ===============================
Description:
closedir() function: stop reading the entries of a directory

Files:
lib/closedir.c
lib/dirent-private.h
m4/closedir.m4

Depends-on:
dirent

configure.ac:
gl_FUNC_CLOSEDIR
if test $HAVE_CLOSEDIR = 0 || test $REPLACE_CLOSEDIR = 1; then
  AC_LIBOBJ([closedir])
fi
gl_DIRENT_MODULE_INDICATOR([closedir])

Makefile.am:

Include:
<dirent.h>

License:
LGPL

Maintainer:
Bruno Haible
================================================================================
--- NEWS.orig   Tue Sep 13 00:26:06 2011
+++ NEWS        Tue Sep 13 00:12:44 2011
@@ -12,6 +12,12 @@
 
 Date        Modules         Changes
 
+2011-09-12  fchdir          This module no longer overrides the functions
+                            opendir() and closedir(), unless the modules
+                            'opendir' and 'closedir' are in use, respectively.
+                            If you use opendir(), please use module 'opendir'.
+                            If you use closedir(), please use module 
'closedir'.
+
 2011-08-04  pathmax         The header file "pathmax.h" no longer defines
                             PATH_MAX on GNU/Hurd. Please use one of the methods
                             listed in pathmax.h to ensure your package is
--- doc/posix-functions/closedir.texi.orig      Tue Sep 13 00:26:06 2011
+++ doc/posix-functions/closedir.texi   Mon Sep 12 03:16:49 2011
@@ -4,15 +4,15 @@
 
 POSIX specification:@* 
@url{http://www.opengroup.org/onlinepubs/9699919799/functions/closedir.html}
 
-Gnulib module: ---
+Gnulib module: closedir
 
 Portability problems fixed by Gnulib:
 @itemize
address@hidden
+This function is missing on some platforms:
+MSVC 9.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
address@hidden
-This function is missing on some platforms:
-MSVC 9.
 @end itemize
--- doc/posix-functions/opendir.texi.orig       Tue Sep 13 00:26:06 2011
+++ doc/posix-functions/opendir.texi    Mon Sep 12 03:17:06 2011
@@ -4,18 +4,18 @@
 
 POSIX specification:@* 
@url{http://www.opengroup.org/onlinepubs/9699919799/functions/opendir.html}
 
-Gnulib module: ---
+Gnulib module: opendir
 
 Portability problems fixed by Gnulib:
 @itemize
address@hidden
+This function is missing on some platforms:
+MSVC 9.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-This function is missing on some platforms:
-MSVC 9.
address@hidden
 On platforms where @code{off_t} is a 32-bit type, this function may not
 work correctly on huge directories larger than 2 GB.  Also, on platforms
 where @code{ino_t} is a 32-bit type, this function may report inode numbers
--- doc/posix-functions/readdir.texi.orig       Tue Sep 13 00:26:06 2011
+++ doc/posix-functions/readdir.texi    Mon Sep 12 03:17:17 2011
@@ -4,18 +4,18 @@
 
 POSIX specification:@* 
@url{http://www.opengroup.org/onlinepubs/9699919799/functions/readdir.html}
 
-Gnulib module: ---
+Gnulib module: readdir
 
 Portability problems fixed by Gnulib:
 @itemize
address@hidden
+This function is missing on some platforms:
+MSVC 9.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-This function is missing on some platforms:
-MSVC 9.
address@hidden
 On platforms where @code{off_t} is a 32-bit type, this function may not
 work correctly on huge directories larger than 2 GB.  Also, on platforms
 where @code{ino_t} is a 32-bit type, this function may report inode numbers
--- doc/posix-functions/rewinddir.texi.orig     Tue Sep 13 00:26:06 2011
+++ doc/posix-functions/rewinddir.texi  Mon Sep 12 03:17:31 2011
@@ -4,18 +4,18 @@
 
 POSIX specification:@* 
@url{http://www.opengroup.org/onlinepubs/9699919799/functions/rewinddir.html}
 
-Gnulib module: ---
+Gnulib module: rewinddir
 
 Portability problems fixed by Gnulib:
 @itemize
address@hidden
+This function is missing on some platforms:
+MSVC 9.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-This function is missing on some platforms:
-MSVC 9.
address@hidden
 On platforms where @code{long int} is a 32-bit type, this function may not
 work correctly on huge directories larger than 2 GB.  The fix is to use
 the @code{AC_SYS_LARGEFILE} macro (only on MacOS X systems).
--- lib/dirent.in.h.orig        Tue Sep 13 00:26:06 2011
+++ lib/dirent.in.h     Mon Sep 12 21:58:08 2011
@@ -32,6 +32,29 @@
 /* Get ino_t.  Needed on some systems, including glibc 2.8.  */
 #include <sys/types.h>
 
+#if address@hidden@
+/* Define types DIR and 'struct dirent'.  */
+# if !GNULIB_defined_struct_dirent
+struct dirent
+{
+  char d_type;
+  char d_name[1];
+};
+/* Possible values for 'd_type'.  */
+#  define DT_UNKNOWN 0
+#  define DT_FIFO    1          /* FIFO */
+#  define DT_CHR     2          /* character device */
+#  define DT_DIR     4          /* directory */
+#  define DT_BLK     6          /* block device */
+#  define DT_REG     8          /* regular file */
+#  define DT_LNK    10          /* symbolic link */
+#  define DT_SOCK   12          /* socket */
+#  define DT_WHT    14          /* whiteout */
+typedef struct gl_directory DIR;
+#  define GNULIB_defined_struct_dirent 1
+# endif
+#endif
+
 /* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
 
 /* The definition of _GL_ARG_NONNULL is copied here.  */
@@ -41,16 +64,79 @@
 
 /* Declare overridden functions.  */
 
-#if @REPLACE_CLOSEDIR@
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-#  define closedir rpl_closedir
-# endif
-_GL_FUNCDECL_RPL (closedir, int, (DIR *) _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL (closedir, int, (DIR *));
-#else
-_GL_CXXALIAS_SYS (closedir, int, (DIR *));
+#if @GNULIB_OPENDIR@
+# if @REPLACE_OPENDIR@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef opendir
+#   define opendir rpl_opendir
+#  endif
+_GL_FUNCDECL_RPL (opendir, DIR *, (const char *dir_name) _GL_ARG_NONNULL 
((1)));
+_GL_CXXALIAS_RPL (opendir, DIR *, (const char *dir_name));
+# else
+#  if address@hidden@
+_GL_FUNCDECL_SYS (opendir, DIR *, (const char *dir_name) _GL_ARG_NONNULL 
((1)));
+#  endif
+_GL_CXXALIAS_SYS (opendir, DIR *, (const char *dir_name));
+# endif
+_GL_CXXALIASWARN (opendir);
+#elif defined GNULIB_POSIXCHECK
+# undef opendir
+# if HAVE_RAW_DECL_OPENDIR
+_GL_WARN_ON_USE (opendir, "opendir is not portable - "
+                 "use gnulib module opendir for portability");
+# endif
+#endif
+
+#if @GNULIB_READDIR@
+# if address@hidden@
+_GL_FUNCDECL_SYS (readdir, struct dirent *, (DIR *dirp) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (readdir, struct dirent *, (DIR *dirp));
+_GL_CXXALIASWARN (readdir);
+#elif defined GNULIB_POSIXCHECK
+# undef readdir
+# if HAVE_RAW_DECL_READDIR
+_GL_WARN_ON_USE (readdir, "readdir is not portable - "
+                 "use gnulib module readdir for portability");
+# endif
 #endif
+
+#if @GNULIB_REWINDDIR@
+# if address@hidden@
+_GL_FUNCDECL_SYS (rewinddir, void, (DIR *dirp) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (rewinddir, void, (DIR *dirp));
+_GL_CXXALIASWARN (rewinddir);
+#elif defined GNULIB_POSIXCHECK
+# undef rewinddir
+# if HAVE_RAW_DECL_REWINDDIR
+_GL_WARN_ON_USE (rewinddir, "rewinddir is not portable - "
+                 "use gnulib module rewinddir for portability");
+# endif
+#endif
+
+#if @GNULIB_CLOSEDIR@
+# if @REPLACE_CLOSEDIR@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef closedir
+#   define closedir rpl_closedir
+#  endif
+_GL_FUNCDECL_RPL (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (closedir, int, (DIR *dirp));
+# else
+#  if address@hidden@
+_GL_FUNCDECL_SYS (closedir, int, (DIR *dirp) _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (closedir, int, (DIR *dirp));
+# endif
 _GL_CXXALIASWARN (closedir);
+#elif defined GNULIB_POSIXCHECK
+# undef closedir
+# if HAVE_RAW_DECL_CLOSEDIR
+_GL_WARN_ON_USE (closedir, "closedir is not portable - "
+                 "use gnulib module closedir for portability");
+# endif
+#endif
 
 #if @GNULIB_DIRFD@
 /* Return the file descriptor associated with the given directory stream,
@@ -111,17 +197,6 @@
 # endif
 #endif
 
-#if @REPLACE_OPENDIR@
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-#  define opendir rpl_opendir
-# endif
-_GL_FUNCDECL_RPL (opendir, DIR *, (const char *) _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL (opendir, DIR *, (const char *));
-#else
-_GL_CXXALIAS_SYS (opendir, DIR *, (const char *));
-#endif
-_GL_CXXALIASWARN (opendir);
-
 #if @GNULIB_SCANDIR@
 /* Scan the directory DIR, calling FILTER on each directory entry.
    Entries for which FILTER returns nonzero are individually malloc'd,
--- lib/fchdir.c.orig   Tue Sep 13 00:26:06 2011
+++ lib/fchdir.c        Mon Sep 12 22:16:53 2011
@@ -211,42 +211,6 @@
 }
 #endif
 
-/* Override opendir() and closedir(), to keep track of the open file
-   descriptors.  Needed because there is a function dirfd().  */
-
-int
-rpl_closedir (DIR *dp)
-#undef closedir
-{
-  int fd = dirfd (dp);
-  int retval = closedir (dp);
-
-  if (retval >= 0)
-    _gl_unregister_fd (fd);
-  return retval;
-}
-
-DIR *
-rpl_opendir (const char *filename)
-#undef opendir
-{
-  DIR *dp;
-
-  dp = opendir (filename);
-  if (dp != NULL)
-    {
-      int fd = dirfd (dp);
-      if (0 <= fd && _gl_register_fd (fd, filename) != fd)
-        {
-          int saved_errno = errno;
-          closedir (dp);
-          errno = saved_errno;
-          return NULL;
-        }
-    }
-  return dp;
-}
-
 /* Override dup(), to keep track of open file descriptors.  */
 
 int
--- m4/dirent_h.m4.orig Tue Sep 13 00:26:06 2011
+++ m4/dirent_h.m4      Mon Sep 12 22:00:11 2011
@@ -1,4 +1,4 @@
-# dirent_h.m4 serial 15
+# dirent_h.m4 serial 16
 dnl Copyright (C) 2008-2011 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -24,7 +24,7 @@
   dnl Check for declarations of anything we want to poison if the
   dnl corresponding gnulib module is not in use.
   gl_WARN_ON_USE_PREPARE([[#include <dirent.h>
-    ]], [alphasort dirfd fdopendir scandir])
+    ]], [alphasort closedir dirfd fdopendir opendir readdir rewinddir scandir])
 ])
 
 AC_DEFUN([gl_DIRENT_MODULE_INDICATOR],
@@ -39,18 +39,26 @@
 AC_DEFUN([gl_DIRENT_H_DEFAULTS],
 [
   AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) dnl for REPLACE_FCHDIR
+  GNULIB_OPENDIR=0;     AC_SUBST([GNULIB_OPENDIR])
+  GNULIB_READDIR=0;     AC_SUBST([GNULIB_READDIR])
+  GNULIB_REWINDDIR=0;   AC_SUBST([GNULIB_REWINDDIR])
+  GNULIB_CLOSEDIR=0;    AC_SUBST([GNULIB_CLOSEDIR])
   GNULIB_DIRFD=0;       AC_SUBST([GNULIB_DIRFD])
   GNULIB_FDOPENDIR=0;   AC_SUBST([GNULIB_FDOPENDIR])
   GNULIB_SCANDIR=0;     AC_SUBST([GNULIB_SCANDIR])
   GNULIB_ALPHASORT=0;   AC_SUBST([GNULIB_ALPHASORT])
   dnl Assume proper GNU behavior unless another module says otherwise.
+  HAVE_OPENDIR=1;       AC_SUBST([HAVE_OPENDIR])
+  HAVE_READDIR=1;       AC_SUBST([HAVE_READDIR])
+  HAVE_REWINDDIR=1;     AC_SUBST([HAVE_REWINDDIR])
+  HAVE_CLOSEDIR=1;      AC_SUBST([HAVE_CLOSEDIR])
   HAVE_DECL_DIRFD=1;    AC_SUBST([HAVE_DECL_DIRFD])
   HAVE_DECL_FDOPENDIR=1;AC_SUBST([HAVE_DECL_FDOPENDIR])
   HAVE_FDOPENDIR=1;     AC_SUBST([HAVE_FDOPENDIR])
   HAVE_SCANDIR=1;       AC_SUBST([HAVE_SCANDIR])
   HAVE_ALPHASORT=1;     AC_SUBST([HAVE_ALPHASORT])
+  REPLACE_OPENDIR=0;    AC_SUBST([REPLACE_OPENDIR])
   REPLACE_CLOSEDIR=0;   AC_SUBST([REPLACE_CLOSEDIR])
   REPLACE_DIRFD=0;      AC_SUBST([REPLACE_DIRFD])
   REPLACE_FDOPENDIR=0;  AC_SUBST([REPLACE_FDOPENDIR])
-  REPLACE_OPENDIR=0;    AC_SUBST([REPLACE_OPENDIR])
 ])
--- m4/fchdir.m4.orig   Tue Sep 13 00:26:06 2011
+++ m4/fchdir.m4        Mon Sep 12 22:10:46 2011
@@ -1,4 +1,4 @@
-# fchdir.m4 serial 17
+# fchdir.m4 serial 18
 dnl Copyright (C) 2006-2011 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -24,8 +24,6 @@
     dnl We must also replace anything that can manipulate a directory fd,
     dnl to keep our bookkeeping up-to-date.  We don't have to replace
     dnl fstatat, since no platform has fstatat but lacks fchdir.
-    REPLACE_OPENDIR=1
-    REPLACE_CLOSEDIR=1
     REPLACE_DUP=1
     AC_CACHE_CHECK([whether open can visit directories],
       [gl_cv_func_open_directory_works],
--- modules/dirent.orig Tue Sep 13 00:26:06 2011
+++ modules/dirent      Mon Sep 12 22:02:52 2011
@@ -29,19 +29,27 @@
              -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
              -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
              -e 's|@''NEXT_DIRENT_H''@|$(NEXT_DIRENT_H)|g' \
+             -e 's/@''GNULIB_OPENDIR''@/$(GNULIB_OPENDIR)/g' \
+             -e 's/@''GNULIB_READDIR''@/$(GNULIB_READDIR)/g' \
+             -e 's/@''GNULIB_REWINDDIR''@/$(GNULIB_REWINDDIR)/g' \
+             -e 's/@''GNULIB_CLOSEDIR''@/$(GNULIB_CLOSEDIR)/g' \
              -e 's/@''GNULIB_DIRFD''@/$(GNULIB_DIRFD)/g' \
              -e 's/@''GNULIB_FDOPENDIR''@/$(GNULIB_FDOPENDIR)/g' \
              -e 's/@''GNULIB_SCANDIR''@/$(GNULIB_SCANDIR)/g' \
              -e 's/@''GNULIB_ALPHASORT''@/$(GNULIB_ALPHASORT)/g' \
+             -e 's/@''HAVE_OPENDIR''@/$(HAVE_OPENDIR)/g' \
+             -e 's/@''HAVE_READDIR''@/$(HAVE_READDIR)/g' \
+             -e 's/@''HAVE_REWINDDIR''@/$(HAVE_REWINDDIR)/g' \
+             -e 's/@''HAVE_CLOSEDIR''@/$(HAVE_CLOSEDIR)/g' \
              -e 's|@''HAVE_DECL_DIRFD''@|$(HAVE_DECL_DIRFD)|g' \
              -e 's|@''HAVE_DECL_FDOPENDIR''@|$(HAVE_DECL_FDOPENDIR)|g' \
              -e 's|@''HAVE_FDOPENDIR''@|$(HAVE_FDOPENDIR)|g' \
              -e 's|@''HAVE_SCANDIR''@|$(HAVE_SCANDIR)|g' \
              -e 's|@''HAVE_ALPHASORT''@|$(HAVE_ALPHASORT)|g' \
+             -e 's|@''REPLACE_OPENDIR''@|$(REPLACE_OPENDIR)|g' \
              -e 's|@''REPLACE_CLOSEDIR''@|$(REPLACE_CLOSEDIR)|g' \
              -e 's|@''REPLACE_DIRFD''@|$(REPLACE_DIRFD)|g' \
              -e 's|@''REPLACE_FDOPENDIR''@|$(REPLACE_FDOPENDIR)|g' \
-             -e 's|@''REPLACE_OPENDIR''@|$(REPLACE_OPENDIR)|g' \
              -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
              -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
              -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \

-- 
In memoriam Steve Biko <http://en.wikipedia.org/wiki/Steve_Biko>



reply via email to

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