Here's the delta of what was lost with cvs.apache.org filling up...

I introduced APR_UNKFILE to distinguish files we don't know about
from NOFILE.  I introduced tests for DIRENT_INODE and DIRENT_TYPE
to identify the dirent members for inode and filetype.  And I updated
the dir.c code for unix to take advantage of those changes, as well
as covered the UNKFILE condition in apr_stat.

Bill
Index: acconfig.h
===================================================================
RCS file: /home/cvs/apr/acconfig.h,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -r1.62 -r1.63
--- acconfig.h  14 Nov 2002 23:52:56 -0000      1.62
+++ acconfig.h  14 Dec 2002 05:55:03 -0000      1.63
@@ -7,6 +7,8 @@
 #undef USE_THREADS
 #undef EGD_DEFAULT_SOCKET
 #undef HAVE_isascii
+#undef DIRENT_INODE
+#undef DIRENT_TYPE
 
 /* Cross process serialization techniques */
 #undef USE_FLOCK_SERIALIZE
Index: configure.in
===================================================================
RCS file: /home/cvs/apr/configure.in,v
retrieving revision 1.506
retrieving revision 1.507
diff -u -r1.506 -r1.507
--- configure.in        2 Dec 2002 16:07:09 -0000       1.506
+++ configure.in        14 Dec 2002 05:55:03 -0000      1.507
@@ -887,6 +887,8 @@
 AC_SUBST(have_memmove)
 
 APR_CHECK_SIGWAIT_ONE_ARG
+APR_CHECK_DIRENT_INODE
+APR_CHECK_DIRENT_TYPE
 
 dnl ----------------------------- Checks for Any required Headers
 AC_HEADER_STDC
Index: build/apr_common.m4
===================================================================
RCS file: /home/cvs/apr/build/apr_common.m4,v
retrieving revision 1.46
retrieving revision 1.48
diff -u -r1.46 -r1.48
--- build/apr_common.m4 14 Nov 2002 18:30:02 -0000      1.46
+++ build/apr_common.m4 14 Dec 2002 06:04:02 -0000      1.48
@@ -529,6 +529,64 @@
 fi
 ])
 
+dnl
+dnl APR_CHECK_DIRENT_INODE
+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_INODE, [
+AC_CACHE_CHECK([for inode member of struct dirent], apr_cv_dirent_inode, [
+apr_cv_dirent_inode=no
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <dirent.h>
+],[
+#ifdef d_ino
+#undef d_ino
+#endif
+struct dirent de; de.d_fileno;
+], apr_cv_dirent_inode=d_fileno)
+if test "$apr_cv_dirent_inode" = "no"; then
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <dirent.h>
+],[
+#ifdef d_fileno
+#undef d_fileno
+#endif
+struct dirent de; de.d_ino;
+], apr_cv_dirent_inode=d_ino)
+fi
+])
+if test "$apr_cv_dirent_inode" != "no"; then
+  AC_DEFINE_UNQUOTED(DIRENT_INODE, $apr_cv_dirent_inode)
+fi
+])
+
+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  Note that this is worthless without DT_xxx macros, so
+dnl  look for one while we are at it.
+dnl
+AC_DEFUN(APR_CHECK_DIRENT_TYPE,[
+AC_CACHE_CHECK([for file type member of struct dirent], apr_cv_dirent_type,[
+apr_cv_dirent_type=no
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <dirent.h>
+],[
+struct dirent de; de.d_type = DT_REG;
+], apr_cv_dirent_type=d_type)
+])
+if test "$apr_cv_dirent_type" != "no"; then
+  AC_DEFINE_UNQUOTED(DIRENT_TYPE, $apr_cv_dirent_type) 
+fi
+])
 
 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
retrieving revision 1.65
diff -u -r1.64 -r1.65
--- file_io/unix/dir.c  1 Jul 2002 14:04:58 -0000       1.64
+++ file_io/unix/dir.c  14 Dec 2002 05:55:03 -0000      1.65
@@ -140,12 +140,42 @@
     return apr_pool_cleanup_run(thedir->pool, thedir, dir_cleanup);
 }
 
+apr_filetype_e apr_filetype_from_dirent_type(int type)
+{
+    switch (type) {
+    case DT_REG:
+        return APR_REG;
+    case DT_DIR:
+        return APR_DIR;
+    case DT_LNK:
+        return APR_LNK;
+    case DT_CHR:
+        return APR_CHR;
+    case DT_BLK:
+        return APR_BLK;
+#if defined(DT_FIFO)
+    case DT_FIFO:
+        return APR_PIPE;
+#endif
+#if !defined(BEOS) && defined(DT_SOCK)
+    case DT_SOCK:
+        return APR_SOCK;
+#endif
+    default:
+        return APR_UNKFILE;
+    }
+}
+
+
 apr_status_t apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
                           apr_dir_t *thedir)
 {
     apr_status_t ret = 0;
+#ifdef DIRENT_TYPE
+    apr_filetype_e type;
+#endif
 #if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) \
-    && !defined(READDIR_IS_THREAD_SAFE)
+                    && !defined(READDIR_IS_THREAD_SAFE)
     struct dirent *retent;
 
     ret = readdir_r(thedir->dirstruct, thedir->entry, &retent);
@@ -179,26 +209,31 @@
         return ret;
     }
 
-    /* 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);
+#ifdef DIRENT_INODE
+    wanted &= ~APR_FINFO_INODE;
+#endif
+#ifdef DIRENT_TYPE
+    wanted &= ~APR_FINFO_TYPE;
+#endif
+
+    wanted &= ~APR_FINFO_NAME;
+
     if (wanted)
     {
         char fspec[APR_PATH_MAX];
         int off;
         apr_cpystrn(fspec, thedir->dirname, sizeof(fspec));
         off = strlen(fspec);
-        if (fspec[off - 1] != '/')
+        if ((fspec[off - 1] != '/') && (off + 1 < sizeof(fspec)))
             fspec[off++] = '/';
         apr_cpystrn(fspec + off, thedir->entry->d_name, sizeof(fspec) - off);
         ret = apr_lstat(finfo, fspec, wanted, thedir->pool);
+        /* We passed a stack name that will disappear */
+        finfo->fname = NULL;
     }
 
     if (wanted && (ret == APR_SUCCESS || ret == APR_INCOMPLETE)) {
         wanted &= ~finfo->valid;
-        ret = APR_SUCCESS;
     }
     else {
         /* We don't bail because we fail to stat, when we are only -required-
@@ -206,13 +241,18 @@
          */
         finfo->pool = thedir->pool;
         finfo->valid = 0;
+#ifdef DIRENT_TYPE
+        finfo->filetype = 
apr_type_from_dirent_type(thedir->entry->DIRENT_TYPE);
+        finfo->valid |= APR_FINFO_TYPE;
+#endif
+#ifdef DIRENT_INODE
+        finfo->inode = thedir->entry->DIRENT_INODE;
+        finfo->valid |= APR_FINFO_INODE;
+#endif
     }
 
-    /* We passed a stack name that is now gone */
-    finfo->fname = NULL;
+    finfo->name = apr_pstrdup(thedir->pool, thedir->entry->d_name);
     finfo->valid |= APR_FINFO_NAME;
-    /* XXX: Optimize here with d_fileno, d_type etc by platform */
-    finfo->name = thedir->entry->d_name;
 
     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.60
retrieving revision 1.61
diff -u -r1.60 -r1.61
--- file_io/unix/filestat.c     12 Dec 2002 20:43:14 -0000      1.60
+++ file_io/unix/filestat.c     14 Dec 2002 05:53:57 -0000      1.61
@@ -96,7 +96,7 @@
             type = APR_SOCK;
        } else
 #endif
-        type = APR_NOFILE;
+        type = APR_UNKFILE;
     }
     return type;
 }
Index: include/apr_file_info.h
===================================================================
RCS file: /home/cvs/apr/include/apr_file_info.h,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -r1.33 -r1.34
--- include/apr_file_info.h     10 Nov 2002 08:35:16 -0000      1.33
+++ include/apr_file_info.h     14 Dec 2002 05:52:56 -0000      1.34
@@ -86,7 +86,8 @@
     APR_BLK,            /**< a block device */
     APR_PIPE,           /**< a FIFO / pipe */
     APR_LNK,            /**< a symbolic link */
-    APR_SOCK            /**< a [unix domain] socket */
+    APR_SOCK,           /**< a [unix domain] socket */
+    APR_UNKFILE = 127   /**< a file of unknown type */
 } apr_filetype_e; 
 
 /**


Reply via email to