rpms/apr/FC-4 apr-0.9.6-flushbufs.patch, NONE, 1.1 apr-0.9.6-readdir64.patch, NONE, 1.1 apr-0.9.6-uidgid.patch, NONE, 1.1 .cvsignore, 1.6, 1.7 apr.spec, 1.24, 1.25

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Mon Sep 5 15:30:49 UTC 2005


Author: jorton

Update of /cvs/dist/rpms/apr/FC-4
In directory cvs.devel.redhat.com:/tmp/cvs-serv15117

Modified Files:
	.cvsignore apr.spec 
Added Files:
	apr-0.9.6-flushbufs.patch apr-0.9.6-readdir64.patch 
	apr-0.9.6-uidgid.patch 
Log Message:
* Mon Sep  5 2005 Joe Orton <jorton at redhat.com> 0.9.6-3.2
- add from 0.9.x branch:
 * fix for apr_{uid,gid}_* error handling (r239592)
 * fix for apr_file_ write flushing (r267192)
- add backport for use of readdir64_r (r265032, r265681, r265684)


apr-0.9.6-flushbufs.patch:
 file_io/unix/readwrite.c |   12 ++++++--
 test/testfile.c          |   70 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+), 2 deletions(-)

--- NEW FILE apr-0.9.6-flushbufs.patch ---
Author: jorton
Date: Fri Sep  2 05:22:45 2005
New Revision: 267192

URL: http://svn.apache.org/viewcvs?rev=267192&view=rev
Log:
Merge r234013, r239221 from trunk:

* file_io/unix/readwrite.c (apr_file_write): Catch apr_file_flush()
failure for buffered files.
(apr_file_read): Handle the apr_file_flush() return value when
flushing buffered writes.

* test/testfile.c (test_fail_write_flush, test_fail_read_flush): Add
test cases.

Submitted by: Erik Huelsmann <ehuels gmail.com>, jorton

Modified:
    apr/apr/branches/0.9.x/CHANGES
    apr/apr/branches/0.9.x/file_io/unix/readwrite.c
    apr/apr/branches/0.9.x/test/testfile.c

--- apr-0.9.6/file_io/unix/readwrite.c.flushbufs
+++ apr-0.9.6/file_io/unix/readwrite.c
@@ -50,7 +50,15 @@
 #endif
 
         if (thefile->direction == 1) {
-            apr_file_flush(thefile);
+            rv = apr_file_flush(thefile);
+            if (rv) {
+#if APR_HAS_THREADS
+                if (thefile->thlock) {
+                    apr_thread_mutex_unlock(thefile->thlock);
+                }
+#endif
+                return rv;
+            }
             thefile->bufpos = 0;
             thefile->direction = 0;
             thefile->dataRead = 0;
@@ -173,7 +181,7 @@
         rv = 0;
         while (rv == 0 && size > 0) {
             if (thefile->bufpos == APR_FILE_BUFSIZE)   /* write buffer is full*/
-                apr_file_flush(thefile);
+                rv = apr_file_flush(thefile);
 
             blocksize = size > APR_FILE_BUFSIZE - thefile->bufpos ? 
                         APR_FILE_BUFSIZE - thefile->bufpos : size;
--- apr-0.9.6/test/testfile.c.flushbufs
+++ apr-0.9.6/test/testfile.c
@@ -528,6 +528,74 @@
     CuAssertIntEquals(tc, APR_SUCCESS, rv);
 }
 
+static void test_fail_write_flush(CuTest *tc)
+{
+    apr_file_t *f;
+    const char *fname = "data/testflush.dat";
+    apr_status_t rv;
+    char buf[APR_BUFFERSIZE];
+    int n;
+
+    apr_file_remove(fname, p);
+
+    apr_assert_success(tc, "open test file",
+                       apr_file_open(&f, fname,
+                                     APR_CREATE|APR_READ|APR_BUFFERED,
+                                     APR_UREAD|APR_UWRITE, p));
+
+    memset(buf, 'A', sizeof buf);
+
+    /* Try three writes.  One of these should fail when it exceeds the
+     * internal buffer and actually tries to write to the file, which
+     * was opened read-only and hence should be unwritable. */
+    for (n = 0, rv = APR_SUCCESS; n < 4 && rv == APR_SUCCESS; n++) {
+        apr_size_t bytes = sizeof buf;
+        rv = apr_file_write(f, buf, &bytes);
+    }
+
+    CuAssert(tc, "failed to write to read-only buffered fd",
+             rv != APR_SUCCESS);
+
+    apr_file_close(f);
+    apr_file_remove(fname, p);
+}
+
+static void test_fail_read_flush(CuTest *tc)
+{
+    apr_file_t *f;
+    const char *fname = "data/testflush.dat";
+    apr_status_t rv;
+    char buf[2];
+
+    apr_file_remove(fname, p);
+
+    apr_assert_success(tc, "open test file",
+                       apr_file_open(&f, fname,
+                                     APR_CREATE|APR_READ|APR_BUFFERED,
+                                     APR_UREAD|APR_UWRITE, p));
+
+    /* this write should be buffered. */
+    apr_assert_success(tc, "buffered write should succeed",
+                       apr_file_puts("hello", f));
+
+    /* Now, trying a read should fail since the write must be flushed,
+     * and should fail with something other than EOF since the file is
+     * opened read-only. */
+    rv = apr_file_read_full(f, buf, 2, NULL);
+
+    CuAssert(tc, "read should flush buffered write and fail",
+             rv != APR_SUCCESS && rv != APR_EOF);
+
+    /* Likewise for gets */
+    rv = apr_file_gets(buf, 2, f);
+
+    CuAssert(tc, "gets should flush buffered write and fail",
+             rv != APR_SUCCESS && rv != APR_EOF);
+
+    apr_file_close(f);
+    apr_file_remove(fname, p);
+}
+
 CuSuite *testfile(void)
 {
     CuSuite *suite = CuSuiteNew("File I/O");
@@ -553,6 +621,8 @@
     SUITE_ADD_TEST(suite, test_bigread);
     SUITE_ADD_TEST(suite, test_mod_neg);
     SUITE_ADD_TEST(suite, test_truncate);
+    SUITE_ADD_TEST(suite, test_fail_write_flush);
+    SUITE_ADD_TEST(suite, test_fail_read_flush);
 
     return suite;
 }

apr-0.9.6-readdir64.patch:
 configure.in                         |    4 ++
 file_io/unix/dir.c                   |   56 +++++++++++++++++++++++++++--------
 file_io/unix/filestat.c              |   11 ++++++
 include/arch/unix/apr_arch_file_io.h |    4 ++
 4 files changed, 62 insertions(+), 13 deletions(-)

--- NEW FILE apr-0.9.6-readdir64.patch ---
--- apr-0.9.6/file_io/unix/dir.c.readdir64
+++ apr-0.9.6/file_io/unix/dir.c
@@ -77,24 +77,24 @@
      * 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);
+    DIR *dir = opendir(dirname);
+
+    if (!dir) {
+        return errno;
+    }
 
     (*new) = (apr_dir_t *)apr_palloc(pool, sizeof(apr_dir_t));
 
     (*new)->pool = pool;
     (*new)->dirname = apr_pstrdup(pool, dirname);
-    (*new)->dirstruct = opendir(dirname);
+    (*new)->dirstruct = dir;
     (*new)->entry = apr_pcalloc(pool, dirent_size);
 
-    if ((*new)->dirstruct == NULL) {
-        return errno;
-    }    
-    else {
-        apr_pool_cleanup_register((*new)->pool, (void *)(*new), dir_cleanup,
-	                          apr_pool_cleanup_null);
-        return APR_SUCCESS;
-    }
+    apr_pool_cleanup_register((*new)->pool, *new, dir_cleanup,
+                              apr_pool_cleanup_null);
+    return APR_SUCCESS;
 }
 
 apr_status_t apr_dir_close(apr_dir_t *thedir)
@@ -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,22 @@
 #endif
 #ifdef DIRENT_INODE
     if (thedir->entry->DIRENT_INODE && thedir->entry->DIRENT_INODE != -1) {
+#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;
+        }
+#else
         wanted &= ~APR_FINFO_INODE;
+#endif /* HAVE_READDIR64_R */
     }
-#endif
+#endif /* DIRENT_INODE */
 
     wanted &= ~APR_FINFO_NAME;
 
--- apr-0.9.6/file_io/unix/filestat.c.readdir64
+++ apr-0.9.6/file_io/unix/filestat.c
@@ -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);
--- apr-0.9.6/include/arch/unix/apr_arch_file_io.h.readdir64
+++ apr-0.9.6/include/arch/unix/apr_arch_file_io.h
@@ -108,7 +108,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 *);
--- apr-0.9.6/configure.in.readdir64
+++ apr-0.9.6/configure.in
@@ -1310,6 +1310,10 @@
 AC_CHECK_FUNCS(memchr, have_memchr="1", have_memchr="0")
 AC_CHECK_FUNCS($int64_strfn, have_int64_strfn="1", have_int64_strfn="0")
 
+if test "$ac_cv_sizeof_long" = "4"; then
+   AC_CHECK_FUNCS([readdir64_r])
+fi
+
 dnl ----------------------------- We have a fallback position
 if test "$have_int64_strfn" = "0" && test "$int64_strfn" = "strtoll"; then
     int64_strfn="strtoq"

apr-0.9.6-uidgid.patch:
 test/testuser.c       |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 user/unix/groupinfo.c |   30 ++++++++++++++++++++++++------
 user/unix/userinfo.c  |   44 ++++++++++++++++++++++++++++++++------------
 3 files changed, 102 insertions(+), 18 deletions(-)

--- NEW FILE apr-0.9.6-uidgid.patch ---
Author: jorton
Date: Wed Aug 24 02:56:04 2005
New Revision: 239592

URL: http://svn.apache.org/viewcvs?rev=239592&view=rev
Log:
Merge r219635, r219667, r239390, r239574 from trunk:

* user/unix/userinfo.c (getpwnam_safe, apr_uid_name_get): Fix error
handling; always use the getpwnam_r return value as the error code,
and ignore errno, since POSIX does not require that getpwnam_r sets
errno.

* user/unix/groupinfo.c (apr_gid_name_get, apr_gid_get): Fix error
handling as above; and check for the NULL -> "no entry" cases here
too.

* test/testuser.c (fail_userinfo): Add test cases for error handling
(only one of them actually trips on the bugs in the old code with
glibc).

* user/unix/userinfo.c (getpwnam_safe, apr_uid_name_get): Fix error
handling for platforms which do not set errno on non-threadsafe
get{pw,gr}* failures; always return APR_ENOENT for that case.

* user/unix/groupinfo.c (apr_gid_name_get, apr_gid_get): Likewise.

PR: 34053
Submitted by: pquerna, jorton

Modified:
    apr/apr/branches/0.9.x/CHANGES
    apr/apr/branches/0.9.x/test/testuser.c
    apr/apr/branches/0.9.x/user/unix/groupinfo.c
    apr/apr/branches/0.9.x/user/unix/userinfo.c

--- apr-0.9.6/test/testuser.c.uidgid
+++ apr-0.9.6/test/testuser.c
@@ -93,6 +93,51 @@
     apr_assert_success(tc, "apr_gid_compare failed",
                        apr_gid_compare(gid, retreived_gid));
 }
+
+static void fail_userinfo(CuTest *tc)
+{
+    apr_uid_t uid;
+    apr_gid_t gid;
+    apr_status_t rv;
+    char *tmp;
+
+    errno = 0;
+    gid = uid = 9999999;
+    tmp = NULL;
+    rv = apr_uid_name_get(&tmp, uid, p);
+    CuAssert(tc, "apr_uid_name_get should fail or "
+                "return a user name",
+                rv != APR_SUCCESS || tmp != NULL);
+
+    errno = 0;
+    tmp = NULL;
+    rv = apr_gid_name_get(&tmp, gid, p);
+    CuAssert(tc, "apr_gid_name_get should fail or "
+             "return a group name",
+             rv != APR_SUCCESS || tmp != NULL);
+    
+    gid = 424242;
+    errno = 0;
+    rv = apr_gid_get(&gid, "I_AM_NOT_A_GROUP", p);
+    CuAssert(tc, "apr_gid_get should fail or "
+             "set a group number",
+             rv != APR_SUCCESS || gid == 424242);
+
+    gid = uid = 424242;
+    errno = 0;
+    rv = apr_uid_get(&uid, &gid, "I_AM_NOT_A_USER", p);
+    CuAssert(tc, "apr_gid_get should fail or "
+             "set a user and group number",
+             rv != APR_SUCCESS || uid == 424242 || gid == 4242442);
+
+    errno = 0;
+    tmp = NULL;
+    rv = apr_uid_homepath_get(&tmp, "I_AM_NOT_A_USER", p);
+    CuAssert(tc, "apr_uid_homepath_get should fail or "
+             "set a path name",
+             rv != APR_SUCCESS || tmp != NULL);
+}
+
 #else
 static void users_not_impl(CuTest *tc)
 {
@@ -110,6 +155,7 @@
     SUITE_ADD_TEST(suite, uid_current);
     SUITE_ADD_TEST(suite, username);
     SUITE_ADD_TEST(suite, groupname);
+    SUITE_ADD_TEST(suite, fail_userinfo);
 #endif
 
     return suite;
--- apr-0.9.6/user/unix/groupinfo.c.uidgid
+++ apr-0.9.6/user/unix/groupinfo.c
@@ -37,13 +37,22 @@
 #if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRGID_R)
     struct group grp;
     char grbuf[512];
+    apr_status_t rv;
 
-    if (getgrgid_r(groupid, &grp, grbuf, sizeof(grbuf), &gr)) {
+    /* See comment in getpwnam_safe on error handling. */
+    rv = getgrgid_r(groupid, &grp, grbuf, sizeof(grbuf), &gr);
+    if (rv) {
+        return rv;
+    }
+    if (gr == NULL) {
+        return APR_ENOENT;
+    }
 #else
+    errno = 0;
     if ((gr = getgrgid(groupid)) == NULL) {
-#endif
-        return errno;
+        return errno ? errno : APR_ENOENT;
     }
+#endif
     *groupname = apr_pstrdup(p, gr->gr_name);
 #endif
     return APR_SUCCESS;
@@ -58,13 +67,22 @@
 #if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETGRNAM_R)
     struct group grp;
     char grbuf[512];
+    apr_status_t rv;
 
-    if (getgrnam_r(groupname, &grp, grbuf, sizeof(grbuf), &gr)) {
+    /* See comment in getpwnam_safe on error handling. */
+    rv = getgrnam_r(groupname, &grp, grbuf, sizeof(grbuf), &gr);
+    if (rv) {
+        return rv;
+    }
+    if (gr == NULL) {
+        return APR_ENOENT;
+    }
 #else
+    errno = 0;
     if ((gr = getgrnam(groupname)) == NULL) {
-#endif
-        return errno;
+        return errno ? errno : APR_ENOENT;
     }
+#endif
     *groupid = gr->gr_gid;
 #endif
     return APR_SUCCESS;
--- apr-0.9.6/user/unix/userinfo.c.uidgid
+++ apr-0.9.6/user/unix/userinfo.c
@@ -38,21 +38,31 @@
 {
     struct passwd *pwptr;
 #if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWNAM_R)
-    /* IRIX getpwnam_r() returns 0 and sets pwptr to NULL on failure */
-    if (!getpwnam_r(username, pw, pwbuf, PWBUF_SIZE, &pwptr) && pwptr) {
-        /* nothing extra to do on success */
+    apr_status_t rv;
+
+    /* POSIX defines getpwnam_r() et al to return the error number
+     * rather than set errno, and requires pwptr to be set to NULL if
+     * the entry is not found, imply that "not found" is not an error
+     * condition; some implementations do return 0 with pwptr set to
+     * NULL. */
+    rv = getpwnam_r(username, pw, pwbuf, PWBUF_SIZE, &pwptr);
+    if (rv) {
+        return rv;
+    }
+    if (pwptr == NULL) {
+        return APR_ENOENT;
+    }
 #else
+    /* Some platforms (e.g. FreeBSD 4.x) do not set errno on NULL "not
+     * found" return values for the non-threadsafe function either. */
+    errno = 0;
     if ((pwptr = getpwnam(username)) != NULL) {
         memcpy(pw, pwptr, sizeof *pw);
-#endif
     }
     else {
-        if (errno == 0) {
-            /* this can happen with getpwnam() on FreeBSD 4.3 */
-            return APR_EGENERAL;
-        }
-        return errno;
+        return errno ? errno : APR_ENOENT;
     }
+#endif
     return APR_SUCCESS;
 }
 
@@ -114,13 +124,23 @@
 #if APR_HAS_THREADS && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_GETPWUID_R)
     struct passwd pwd;
     char pwbuf[PWBUF_SIZE];
+    apr_status_t rv;
+
+    rv = getpwuid_r(userid, &pwd, pwbuf, sizeof(pwbuf), &pw);
+    if (rv) {
+        return rv;
+    }
+
+    if (pw == NULL) {
+        return APR_ENOENT;
+    }
 
-    if (getpwuid_r(userid, &pwd, pwbuf, sizeof(pwbuf), &pw)) {
 #else
+    errno = 0;
     if ((pw = getpwuid(userid)) == NULL) {
-#endif
-        return errno;
+        return errno ? errno : APR_ENOENT;
     }
+#endif
     *username = apr_pstrdup(p, pw->pw_name);
     return APR_SUCCESS;
 }


Index: .cvsignore
===================================================================
RCS file: /cvs/dist/rpms/apr/FC-4/.cvsignore,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- .cvsignore	26 Jul 2005 08:21:34 -0000	1.6
+++ .cvsignore	5 Sep 2005 15:30:35 -0000	1.7
@@ -1,3 +1,5 @@
 apr-0.9.6.tar.gz
 apr-0.9.6
 i386
+*.rpm
+clog


Index: apr.spec
===================================================================
RCS file: /cvs/dist/rpms/apr/FC-4/apr.spec,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- apr.spec	26 Jul 2005 08:21:34 -0000	1.24
+++ apr.spec	5 Sep 2005 15:30:35 -0000	1.25
@@ -3,7 +3,7 @@
 Summary: Apache Portable Runtime library
 Name: apr
 Version: 0.9.6
-Release: 3.1
+Release: 3.2
 License: Apache Software License
 Group: System Environment/Libraries
 URL: http://apr.apache.org/
@@ -15,6 +15,9 @@
 Patch18: apr-0.9.4-stacksize.patch
 Patch21: apr-0.9.4-lp64psem.patch
 Patch22: apr-0.9.4-attrerror.patch
+Patch23: apr-0.9.6-readdir64.patch
+Patch24: apr-0.9.6-uidgid.patch
+Patch25: apr-0.9.6-flushbufs.patch
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
 BuildPrereq: autoconf, libtool, doxygen
 Conflicts: subversion < 0.20.1-2
@@ -47,6 +50,9 @@
 %patch18 -p1 -b .stacksize
 %patch21 -p1 -b .lp64psem
 %patch22 -p1 -b .attrerror
+%patch23 -p1 -b .readdir64
+%patch24 -p1 -b .uidgid
+%patch25 -p1 -b .flushbufs
 
 %build
 # regenerate configure script etc.
@@ -119,6 +125,12 @@
 %{_includedir}/apr-%{aprver}/*.h
 
 %changelog
+* Mon Sep  5 2005 Joe Orton <jorton at redhat.com> 0.9.6-3.2
+- add from 0.9.x branch:
+ * fix for apr_{uid,gid}_* error handling (r239592)
+ * fix for apr_file_ write flushing (r267192)
+- add backport for use of readdir64_r (r265032, r265681, r265684)
+
 * Tue Jul 26 2005 Joe Orton <jorton at redhat.com> 0.9.6-3.1
 - rebuild for new gcc
 




More information about the fedora-cvs-commits mailing list