diff options
author | wrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68> | 2002-12-14 05:55:03 +0000 |
---|---|---|
committer | wrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68> | 2002-12-14 05:55:03 +0000 |
commit | 658e82da40a93793098ab685cbd44a3f56d51ce4 (patch) | |
tree | 53815c6d833cff39ef1077913d8d08efbc65a551 | |
parent | b4208a90d00b7f0e267ae28590e55f052a353f63 (diff) | |
download | libapr-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.h | 2 | ||||
-rw-r--r-- | build/apr_common.m4 | 60 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | file_io/unix/dir.c | 64 |
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; |