You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by jo...@apache.org on 2005/08/31 14:32:42 UTC

svn commit: r265032 - in /apr/apr/trunk: STATUS configure.in file_io/unix/dir.c file_io/unix/filestat.c include/arch/unix/apr_arch_file_io.h

Author: jorton
Date: Wed Aug 31 05:32:14 2005
New Revision: 265032

URL: http://svn.apache.org/viewcvs?rev=265032&view=rev
Log:
Add some workarounds for cases where readdir_r fails due to large
integers in struct dirent's d_ino or d_off fields in LFS builds (seen
in some peculiar NFS environments):

* configure.in: Check for readdir64_r for LFS builds.

* include/arch/unix/apr_arch_file_io.h (struct apr_dir_t): Use struct
dirent64 for entry field if readdir64_r is present.

* file_io/unix/dir.c (apr_dir_open): Use size of the entry field.
(apr_dir_read): Use readdir64_r if available; check for d_ino
overflow.

* file_io/unix/filestat.c (fill_out_finfo): Check for inode number
overflow.

Modified:
    apr/apr/trunk/STATUS
    apr/apr/trunk/configure.in
    apr/apr/trunk/file_io/unix/dir.c
    apr/apr/trunk/file_io/unix/filestat.c
    apr/apr/trunk/include/arch/unix/apr_arch_file_io.h

Modified: apr/apr/trunk/STATUS
URL: http://svn.apache.org/viewcvs/apr/apr/trunk/STATUS?rev=265032&r1=265031&r2=265032&view=diff
==============================================================================
--- apr/apr/trunk/STATUS (original)
+++ apr/apr/trunk/STATUS Wed Aug 31 05:32:14 2005
@@ -403,6 +403,8 @@
 
     * apr_hash_count() should take a const apr_hash_t * argument.
 
+    * apr_ino_t should be an ino64_t in LFS builds.
+
 Stuff for post 1.0:
 
     * Almost every API in APR depends on pools, but pool semantics

Modified: apr/apr/trunk/configure.in
URL: http://svn.apache.org/viewcvs/apr/apr/trunk/configure.in?rev=265032&r1=265031&r2=265032&view=diff
==============================================================================
--- apr/apr/trunk/configure.in (original)
+++ apr/apr/trunk/configure.in Wed Aug 31 05:32:14 2005
@@ -1258,7 +1258,7 @@
 if test "${ac_cv_sizeof_off_t}${apr_cv_use_lfs64}" = "4yes"; then
     # Enable LFS
     aprlfs=1
-    AC_CHECK_FUNCS([mmap64 sendfile64 sendfilev64 mkstemp64])
+    AC_CHECK_FUNCS([mmap64 sendfile64 sendfilev64 mkstemp64 readdir64_r])
 else
     aprlfs=0     
 fi

Modified: apr/apr/trunk/file_io/unix/dir.c
URL: http://svn.apache.org/viewcvs/apr/apr/trunk/file_io/unix/dir.c?rev=265032&r1=265031&r2=265032&view=diff
==============================================================================
--- apr/apr/trunk/file_io/unix/dir.c (original)
+++ apr/apr/trunk/file_io/unix/dir.c Wed Aug 31 05:32:14 2005
@@ -77,8 +77,8 @@
      * one-byte array.  Note: gcc evaluates this at compile time.
      */
     apr_size_t dirent_size = 
-        (sizeof((*new)->entry->d_name) > 1 ? 
-         sizeof(struct dirent) : sizeof (struct dirent) + 255);
+        sizeof(*(*new)->entry) +
+        (sizeof((*new)->entry->d_name) > 1 ? 0 : 255);
 
     (*new) = (apr_dir_t *)apr_palloc(pool, sizeof(apr_dir_t));
 
@@ -139,9 +139,28 @@
 #endif
 #if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) \
                     && !defined(READDIR_IS_THREAD_SAFE)
+#ifdef HAVE_READDIR64_R
+    struct dirent64 *retent;
+
+    /* If LFS is enabled and readdir64_r is available, readdir64_r is
+     * used in preference to readdir_r.  This allows directories to be
+     * read which contain a (64-bit) inode number which doesn't fit
+     * into the 32-bit apr_ino_t, iff the caller doesn't actually care
+     * about the inode number (i.e. wanted & APR_FINFO_INODE == 0).
+     * (such inodes may be seen in some wonky NFS environments)
+     *
+     * Similarly, if the d_off field cannot be reprented in a 32-bit
+     * offset, the libc readdir_r() would barf; using readdir64_r
+     * bypasses that case entirely since APR does not care about
+     * d_off. */
+
+    ret = readdir64_r(thedir->dirstruct, thedir->entry, &retent);
+#else
+
     struct dirent *retent;
 
     ret = readdir_r(thedir->dirstruct, thedir->entry, &retent);
+#endif
 
     /* Avoid the Linux problem where at end-of-directory thedir->entry
      * is set to NULL, but ret = APR_SUCCESS.
@@ -191,9 +210,20 @@
 #endif
 #ifdef DIRENT_INODE
     if (thedir->entry->DIRENT_INODE && thedir->entry->DIRENT_INODE != -1) {
-        wanted &= ~APR_FINFO_INODE;
+#ifdef HAVE_READDIR64_R
+        /* If readdir64_r is used, check for the overflow case of trying
+         * to fit a 64-bit integer into a 32-bit integer. */
+        if (sizeof(apr_ino_t) >= sizeof(retent->DIRENT_INODE)
+            || (apr_ino_t)retent->DIRENT_INODE == retent->DIRENT_INODE) {
+            wanted &= ~APR_FINFO_INODE;
+        } else {
+            /* Prevent the fallback code below from filling in the
+             * inode if the stat call fails. */
+            retent->DIRENT_INODE = 0;
+        }
     }
-#endif
+#endif /* HAVE_READDIR64_R */
+#endif /* DIRENT_INODE */
 
     wanted &= ~APR_FINFO_NAME;
 

Modified: apr/apr/trunk/file_io/unix/filestat.c
URL: http://svn.apache.org/viewcvs/apr/apr/trunk/file_io/unix/filestat.c?rev=265032&r1=265031&r2=265032&view=diff
==============================================================================
--- apr/apr/trunk/file_io/unix/filestat.c (original)
+++ apr/apr/trunk/file_io/unix/filestat.c Wed Aug 31 05:32:14 2005
@@ -77,9 +77,18 @@
     finfo->user = info->st_uid;
     finfo->group = info->st_gid;
     finfo->size = info->st_size;
-    finfo->inode = info->st_ino;
     finfo->device = info->st_dev;
     finfo->nlink = info->st_nlink;
+
+    /* Check for overflow if storing a 64-bit st_ino in a 32-bit
+     * apr_ino_t for LFS builds: */
+    if (sizeof(apr_ino_t) >= sizeof(info->st_ino)
+        || (apr_ino_t)info->st_ino == info->st_ino) {
+        finfo->inode = info->st_ino;
+    } else {
+        finfo->valid &= ~APR_FINFO_INODE;
+    }
+
     apr_time_ansi_put(&finfo->atime, info->st_atime);
     apr_time_ansi_put(&finfo->mtime, info->st_mtime);
     apr_time_ansi_put(&finfo->ctime, info->st_ctime);

Modified: apr/apr/trunk/include/arch/unix/apr_arch_file_io.h
URL: http://svn.apache.org/viewcvs/apr/apr/trunk/include/arch/unix/apr_arch_file_io.h?rev=265032&r1=265031&r2=265032&view=diff
==============================================================================
--- apr/apr/trunk/include/arch/unix/apr_arch_file_io.h (original)
+++ apr/apr/trunk/include/arch/unix/apr_arch_file_io.h Wed Aug 31 05:32:14 2005
@@ -125,7 +125,11 @@
     apr_pool_t *pool;
     char *dirname;
     DIR *dirstruct;
+#ifdef HAVE_READDIR64_R
+    struct dirent64 *entry;
+#else
     struct dirent *entry;
+#endif
 };
 
 apr_status_t apr_unix_file_cleanup(void *);