With all forewarning that I'm not a great .m4 hacker, and the OSX
box's power adapter went kaput, here's a patch to simplify the
filetype_from_mode() function and stock ->filetype and ->inode
when available. Guaranteed to have one(+) typo :-)
Bill
Index: configure.in
===================================================================
RCS file: /home/cvs/apr/configure.in,v
retrieving revision 1.506
diff -u -r1.506 configure.in
--- configure.in 2 Dec 2002 16:07:09 -0000 1.506
+++ configure.in 10 Dec 2002 08:20:10 -0000
@@ -875,6 +875,9 @@
AC_CHECK_FUNCS(memmove, [ have_memmove="1" ], [have_memmove="0" ])
AC_CHECK_FUNCS([getpass getpassphrase gmtime_r localtime_r hstrerror mkstemp])
+APR_CHECK_DIRENT_FILENO
+APR_CHECK_DIRENT_TYPE
+
AC_SUBST(fork)
AC_SUBST(have_inet_addr)
AC_SUBST(tcp_nodelay_inherited)
Index: build/apr_common.m4
===================================================================
RCS file: /home/cvs/apr/build/apr_common.m4,v
retrieving revision 1.46
diff -u -r1.46 apr_common.m4
--- build/apr_common.m4 14 Nov 2002 18:30:02 -0000 1.46
+++ build/apr_common.m4 10 Dec 2002 08:20:10 -0000
@@ -476,6 +476,7 @@
fi
AC_MSG_RESULT([$msg])
] )
+
dnl
dnl APR_CHECK_CRYPT_R_STYLE
dnl
@@ -529,6 +530,72 @@
fi
])
+dnl
+dnl APR_CHECK_DIRENT_FILENO
+dnl
+dnl Decide if d_fileno or d_ino are available in the dirent
+dnl structure on this platform. Single UNIX Spec says d_ino,
+dnl BSD uses d_fileno. Undef to find the real beast.
+dnl
+AC_DEFUN(APR_CHECK_DIRENT_FILENO,[
+AC_MSG_CHECKING(for dirent.d_fileno or .d_ino)
+ac_cv_dirent_inode=none
+APR_TRY_COMPILE([
+#include <dirent.h>
+#ifdef d_ino
+#undef d_ino
+#endif
+], [
+struct dirent de;
+de.d_fileno = 1;
+], ac_cv_dirent_inode=d_fileno)
+if test "$ac_cv_dirent_inode" = "d_fileno"; then
+ AC_DEFINE(DIRENT_INODE, "d_fileno", [Define if dirent has d_fileno member])
+ msg="d_fileno"
+else
+APR_TRY_COMPILE([
+#include <dirent.h>
+#ifdef d_fileno
+#undef d_fileno
+#endif
+], [
+struct dirent de;
+de.d_ino = 1;
+], ac_cv_dirent_inode=d_ino)
+if test "$ac_cv_dirent_inode" = "d_ino"; then
+ AC_DEFINE(DIRENT_INODE, "d_ino", [Define if dirent has d_ino member])
+ msg="d_ino"
+else
+ msg="no"
+fi
+fi
+AC_MSG_RESULT([$msg])
+] )
+
+dnl
+dnl APR_CHECK_DIRENT_TYPE
+dnl
+dnl Decide if d_type is available in the dirent structure
+dnl on this platform. Not part of the Single UNIX Spec
+dnl
+AC_DEFUN(APR_CHECK_DIRENT_TYPE,[
+AC_MSG_CHECKING(for dirent.d_type)
+ac_cv_dirent_d_type=no
+APR_TRY_COMPILE_NO_WARNING([
+#include <dirent.h>
+main()
+{
+ struct dirent de;
+ de.d_type = DT_REG;
+}], ac_cv_dirent_d_type=yes)
+if test "$ac_cv_dirent_d_type" = yes; then
+ AC_DEFINE(DIRENT_TYPE, "d_type", [Define if dirent has d_type member])
+ msg="yes"
+else
+ msg="no"
+fi
+AC_MSG_RESULT([$msg])
+] )
dnl the following is a newline, a space, a tab, and a backslash (the
dnl backslash is used by the shell to skip newlines, but m4 sees it;
Index: file_io/unix/dir.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/dir.c,v
retrieving revision 1.64
diff -u -r1.64 dir.c
--- file_io/unix/dir.c 1 Jul 2002 14:04:58 -0000 1.64
+++ file_io/unix/dir.c 10 Dec 2002 08:20:11 -0000
@@ -182,8 +182,15 @@
/* What we already know - and restrict the wanted test below to stat
* only if stat will give us what this platform supports, and we can't
* get it from the platform.
- * XXX: Optimize here with d_fileno, d_type etc by platform */
- wanted &= ~(APR_FINFO_NAME);
+ */
+ wanted &= ~( APR_FINFO_NAME
+#ifdef DIRENT_TYPE
+ | APR_FINFO_TYPE
+#endif
+#ifdef DIRENT_INODE
+ | APR_FINFO_INODE
+#endif
+ );
if (wanted)
{
char fspec[APR_PATH_MAX];
@@ -213,6 +220,31 @@
finfo->valid |= APR_FINFO_NAME;
/* XXX: Optimize here with d_fileno, d_type etc by platform */
finfo->name = thedir->entry->d_name;
+#ifdef DIRENT_TYPE
+ switch (thedir->entry->DIRENT_TYPE) {
+ case DT_REG:
+ finfo->filetype = APR_REG; break;
+ case DT_DIR:
+ finfo->filetype = APR_DIR; break;
+ case DT_LNK:
+ finfo->filetype = APR_LNK; break;
+ case DT_CHR:
+ finfo->filetype = APR_CHR; break;
+ case DT_BLK:
+ finfo->filetype = APR_BLK; break;
+ case DT_FIFO:
+ finfo->filetype = APR_PIPE; break;
+#if !defined(BEOS) && defined(DT_SOCK)
+ case DT_SOCK:
+ finfo->filetype = APR_SOCK; break;
+#endif
+ default:
+ finfo->filetype = APR_NOFILE;
+ }
+#endif
+#ifdef DIRENT_INODE
+ finfo->inode = thedir->entry->DIRENT_INODE
+#endif
if (wanted)
return APR_INCOMPLETE;
Index: file_io/unix/filestat.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/filestat.c,v
retrieving revision 1.57
diff -u -r1.57 filestat.c
--- file_io/unix/filestat.c 22 Sep 2002 19:26:41 -0000 1.57
+++ file_io/unix/filestat.c 10 Dec 2002 08:20:11 -0000
@@ -60,24 +60,28 @@
static apr_filetype_e filetype_from_mode(mode_t mode)
{
- apr_filetype_e type = APR_NOFILE;
+ apr_filetype_e type;
- if (S_ISREG(mode))
- type = APR_REG;
- if (S_ISDIR(mode))
- type = APR_DIR;
- if (S_ISCHR(mode))
- type = APR_CHR;
- if (S_ISBLK(mode))
- type = APR_BLK;
- if (S_ISFIFO(mode))
- type = APR_PIPE;
- if (S_ISLNK(mode))
- type = APR_LNK;
-#if !defined(BEOS) && defined(S_ISSOCK)
- if (S_ISSOCK(mode))
- type = APR_SOCK;
+ switch (type & S_IFMT) {
+ case S_IFREG:
+ type = APR_REG; break;
+ case S_IFDIR:
+ type = APR_DIR; break;
+ case S_IFLNK:
+ type = APR_LNK; break;
+ case S_IFCHR:
+ type = APR_CHR; break;
+ case S_IFBLK:
+ type = APR_BLK; break;
+ case S_IFFIFO:
+ type = APR_PIPE; break;
+#if !defined(BEOS) && defined(S_IFSOCK)
+ case S_IFSOCK:
+ type = APR_SOCK; break;
#endif
+ default:
+ type = APR_NOFILE;
+ }
return type;
}