summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68>2002-12-14 05:55:03 +0000
committerwrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68>2002-12-14 05:55:03 +0000
commit658e82da40a93793098ab685cbd44a3f56d51ce4 (patch)
tree53815c6d833cff39ef1077913d8d08efbc65a551
parentb4208a90d00b7f0e267ae28590e55f052a353f63 (diff)
downloadlibapr-658e82da40a93793098ab685cbd44a3f56d51ce4.tar.gz
Introduce detection of dirent->d_fileno (or ->d_ino) and dirent->d_type
and fill out the apr_fileinfo_t members from apr_dir_read. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@64169 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--acconfig.h2
-rw-r--r--build/apr_common.m460
-rw-r--r--configure.in2
-rw-r--r--file_io/unix/dir.c64
4 files changed, 116 insertions, 12 deletions
diff --git a/acconfig.h b/acconfig.h
index c0f25434e..cf48df04d 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -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
diff --git a/build/apr_common.m4 b/build/apr_common.m4
index 963ef9db7..a084096b1 100644
--- a/build/apr_common.m4
+++ b/build/apr_common.m4
@@ -529,6 +529,66 @@ if test "$ac_cv_crypt_r_style" = "struct_crypt_data_gnu_source"; then
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
+AC_MSG_RESULT($apr_cv_dirent_inode)
+])
+
+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
+AC_MSG_RESULT($apr_cv_dirent_type)
+])
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;
diff --git a/configure.in b/configure.in
index 2e6562005..b5da45b2f 100644
--- a/configure.in
+++ b/configure.in
@@ -887,6 +887,8 @@ AC_SUBST(mmap)
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
diff --git a/file_io/unix/dir.c b/file_io/unix/dir.c
index 8160a02be..0af39f3ba 100644
--- a/file_io/unix/dir.c
+++ b/file_io/unix/dir.c
@@ -140,12 +140,42 @@ apr_status_t apr_dir_close(apr_dir_t *thedir)
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 @@ apr_status_t apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
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 @@ apr_status_t apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
*/
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;