[project @ 2004-08-24 19:26:45 by sof]
authorsof <unknown>
Tue, 24 Aug 2004 19:26:47 +0000 (19:26 +0000)
committersof <unknown>
Tue, 24 Aug 2004 19:26:47 +0000 (19:26 +0000)
Pair of new macros for checking how dirent.h is implemented. Needed
to deal with versioning issues under mingw only, but won't do
any harm on other plats. The macros are:

- FP_READDIR_EOF_ERRNO
     checks what readdir() sets errno to upon reaching end of a directory.
     (that value is available as READDIR_ERRNO_EOF in mk/config.h). Up
     until recently, mingw's readdir() did set errno rather than just
     leaving it alone.
- FP_DIRENT_FLAT_LAYOUT
     checks how 'struct dirent' is defined; defines
     config.h:STRUCT_DIRENT_FLAT_LAYOUT to 1 if 'struct dirent' is terminated
     with a d_name array. Up until recently, mingw didn't define it as such.

To be hooked up to libraries/base/{include/HsBase.h,cbits/dirUtils.c} and
quite possibly merged to STABLE.

aclocal.m4
configure.ac

index e2c46f7..0c25ba9 100644 (file)
@@ -1217,4 +1217,101 @@ AC_DEFINE([SUPPORTS_EMPTY_STRUCTS], [1], [Define to 1 if C compiler supports dec
 fi
 ])
 
+
+dnl @synopsis FP_READDIR_EOF_ERRNO
+dnl
+dnl Check what readdir() sets 'errno' to upon reaching 
+dnl end of directory; not setting it is the correct thing to do,
+dnl but mingw based versions have set it to ENOENT until recently
+dnl (summer 2004).
+dnl
+dnl
+AC_DEFUN(FP_READDIR_EOF_ERRNO,
+[AC_CACHE_CHECK([what readdir sets errno to upon EOF], fptools_cv_readdir_eof_errno,
+[AC_TRY_RUN([#include <dirent.h>
+#include <stdio.h>
+#include <errno.h>
+int
+main(argc, argv)
+int argc;
+char **argv;
+{
+  FILE *f=fopen("conftestval", "w");
+#if defined(__MINGW32__)
+  int fd = mkdir("testdir");
+#else
+  int fd = mkdir("testdir", 0666);
+#endif
+  DIR* dp;
+  struct dirent* de;
+  int err = 0;
+
+  if (!f) return 1;
+  if (fd == -1) { 
+     fprintf(stderr,"unable to create directory; quitting.\n");
+     return 1;
+  }
+  close(fd);
+  dp = opendir("testdir");
+  if (!dp) { 
+     fprintf(stderr,"unable to browse directory; quitting.\n");
+     rmdir("testdir");
+     return 1;
+  }
+
+  /* the assumption here is that readdir() will only return NULL
+   * due to reaching the end of the directory.
+   */
+  while (de = readdir(dp)) {
+       ;
+  }
+  err = errno;
+  fprintf(f,"%d", err);
+  fclose(f);
+  closedir(de);
+  rmdir("testdir");
+  return 0;
+}],fptools_cv_readdir_eof_errno=`cat conftestval`, fptools_cv_readdir_eof_errno=bogus, fptools_cv_readdir_eof_errno=0)])
+dnl the cross value is somewhat bogus.
+AC_DEFINE([READDIR_ERRNO_EOF], [$fptools_cv_readdir_eof_errno], [readdir() sets errno to this upon EOF])
+])
+
+dnl @synopsis FP_DIRENT_FLAT_LAYOUT
+dnl
+dnl Check whether 'struct dirent' (in dirent.h) has d_name defined
+dnl as being the final field in a struct, or a pointer to somewhere
+dnl else. The former is the standardly thing to do, but mingw defns
+dnl have for the longest time gone for the latter. They no longer do,
+dnl hence the need to configure test for this.
+dnl
+dnl
+AC_DEFUN(FP_DIRENT_FLAT_LAYOUT,
+[AC_CACHE_CHECK([if struct dirent layout is flat], fptools_cv_dirent_flat_layout,
+[AC_TRY_RUN([#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+int
+main(argc, argv)
+int argc;
+char **argv;
+{
+  struct dirent de;
+  /*
+   * Check whether d_name is defined as
+   *    struct dirent { .... ; char d_name[..]; } 
+   * or
+   *    struct dirent { .... ; char* d_name; } 
+   * 
+   * Returns 0 if the former.
+   */
+  memset(&de,0,sizeof(struct dirent));
+  return ((int)de.d_name == 0);
+}],fptools_cv_dirent_flat_layout=yes, fptools_cv_dirent_flat_layout=no, fptools_cv_dirent_flat_layout=yes)])
+dnl the cross value is somewhat bogus.
+if test "$fptools_cv_dirent_flat_layout" = yes; then
+AC_DEFINE([STRUCT_DIRENT_FLAT_LAYOUT], [1], [Define to 1 if struct dirent is a flat structure])
+fi
+])
+
+
 # LocalWords:  fi
index f7841b8..36677fa 100644 (file)
@@ -1513,6 +1513,10 @@ FPTOOLS_LD_X
 
 FP_EMPTY_STRUCTS
 
+dnl ** Check for idiosyncracies in some mingw impls of directory handling.
+FP_READDIR_EOF_ERRNO
+FP_DIRENT_FLAT_LAYOUT
+
 AC_MSG_CHECKING([for SIGPOLL])
 AC_EGREP_CPP(we_have_sigpoll,
 [#include <signal.h>