jorton 2004/03/27 05:11:18
Modified: . CHANGES configure.in
file_io/unix filestat.c mktemp.c open.c readwrite.c seek.c
include apr.h.in
include/arch/netware apr_arch_file_io.h
include/arch/unix apr_arch_file_io.h
mmap/unix mmap.c
network_io/unix sendrecv.c
test .cvsignore Makefile.in test_apr.h testall.c
Added: test testlfs.c
Log:
Add LFS support:
* configure.in: Check for off64_t and necessary LFS functions, define
apr_off_t as off64_t where available. Add --disable-lfs flag.
Forward-port changes from 0.9.5 to define apr_off_t as long on systems
systems with a 32-bit off_t which don't have LFS enabled.
* include/apr.h.in: Let configure define APR_HAS_LARGE_FILES.
* include/arch/netware/apr_arch_file_io.h: Redefine lseek and
ftruncate.
* include/arch/unix/apr_arch_file_io.h: Redefine stat, lstat, fstat,
lseek, ftruncate here; define struct_stat.
* file_io/unix/filestat.c: Use struct_stat.
* file_io/unix/mktemp.c: Use mkstemp64 where available.
* file_io/unix/open.c (apr_file_open): Use O_LARGEFILE by default when
LFS is enabled.
* file_io/unix/readwrite.c, file_io/unix/seek.c: Don't redefine lseek
and ftruncate here.
* mmap/unix/mmap.c (apr_mmap_create): Use mmap64 if available;
otherwise check for overflow when LFS is enabled.
* network_io/unix/sendrecv.c (apr_socket_sendfile) [Linux/HPUX]: Use
sendfile64 if available; otherwise check for overflow when LFS is
enabled. [solaris]: Use sendfilev64/sendfilevec64_t.
* test/Makefile.in, test/test_apr.h, test/testlfs.c: Add tests.
Reviewed by: Jeff Trawick
Revision Changes Path
1.455 +3 -0 apr/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr/CHANGES,v
retrieving revision 1.454
retrieving revision 1.455
diff -w -d -u -r1.454 -r1.455
--- CHANGES 25 Mar 2004 23:08:23 -0000 1.454
+++ CHANGES 27 Mar 2004 13:11:17 -0000 1.455
@@ -7,6 +7,9 @@
Changes with APR 1.0
+ *) Support "large files" by default on 32-bit Unix platforms which
+ implement the LFS standard. [Joe Orton]
+
*) Add apr_threadattr_stacksize_set() for overriding the default
stack size for threads created by apr_thread_create().
[Jeff Trawick]
1.576 +86 -22 apr/configure.in
Index: configure.in
===================================================================
RCS file: /home/cvs/apr/configure.in,v
retrieving revision 1.575
retrieving revision 1.576
diff -w -d -u -r1.575 -r1.576
--- configure.in 13 Mar 2004 01:24:42 -0000 1.575
+++ configure.in 27 Mar 2004 13:11:17 -0000 1.576
@@ -416,6 +416,55 @@
AC_SUBST(OBJECTS_PLATFORM)
+# Check whether LFS has explicitly been disabled
+AC_ARG_ENABLE(lfs,[ --disable-lfs Disable large file support on
32-bit platforms],
+[apr_lfs_choice=$enableval], [apr_lfs_choice=yes])
+
+if test "$apr_lfs_choice" = "yes"; then
+ # Check whether the transitional LFS API is sufficient
+ AC_CACHE_CHECK([whether to enable -D_LARGEFILE64_SOURCE],
[apr_cv_use_lfs64], [
+ apr_save_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE"
+ AC_TRY_RUN([
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+void main(void)
+{
+ int fd, ret = 0;
+ struct stat64 st;
+ off64_t off = 4242;
+
+ if (sizeof(off64_t) != 8 || sizeof(off_t) != 4)
+ exit(1);
+ if ((fd = open("conftest.lfs", O_LARGEFILE|O_CREAT|O_WRONLY)) < 0)
+ exit(2);
+ if (ftruncate64(fd, off) != 0)
+ ret = 3;
+ else if (fstat64(fd, &st) != 0 || st.st_size != off)
+ ret = 4;
+ else if (lseek64(fd, off, SEEK_SET) != off)
+ ret = 5;
+ else if (close(fd) != 0)
+ ret = 6;
+ else if (lstat64("conftest.lfs", &st) != 0 || st.st_size != off)
+ ret = 7;
+ else if (stat64("conftest.lfs", &st) != 0 || st.st_size != off)
+ ret = 8;
+ unlink("conftest.lfs");
+
+ exit(ret);
+}], [apr_cv_use_lfs64=yes], [apr_cv_use_lfs64=no], [apr_cv_use_lfs64=no])
+ CPPFLAGS=$apr_save_CPPFLAGS])
+ if test "$apr_cv_use_lfs64" = "yes"; then
+ APR_ADDTO(CPPFLAGS, [-D_LARGEFILE64_SOURCE])
+ fi
+fi
+
AC_ARG_ENABLE(nonportable-atomics,
[ --enable-nonportable-atomics Use optimized atomic code which may produce
nonportable binaries],
[if test $enableval = yes; then
@@ -1104,11 +1153,6 @@
stdint=0
fi
-if test "$ac_cv_type_off_t" = "yes"; then
- off_t_value="off_t"
-else
- off_t_value="apr_int32_t"
-fi
if test "$ac_cv_type_size_t" = "yes"; then
size_t_value="size_t"
else
@@ -1147,15 +1191,45 @@
APR_CHECK_SIZEOF_EXTENDED([#include <sys/types.h>], off_t, 8)
-if test "$ac_cv_sizeof_off_t" = "$ac_cv_sizeof_int"; then
- off_t_fmt='#define APR_OFF_T_FMT "d"'
-elif test "$ac_cv_sizeof_off_t" = "$ac_cv_sizeof_long"; then
+if test "${ac_cv_sizeof_off_t}${apr_cv_use_lfs64}" = "4yes"; then
+ # Enable LFS
+ aprlfs=1
+ AC_CHECK_FUNCS([mmap64 sendfile64 sendfilev64 mkstemp64])
+else
+ aprlfs=0
+fi
+
+AC_MSG_CHECKING([which type to use for apr_off_t])
+if test "${ac_cv_sizeof_off_t}${apr_cv_use_lfs64}" = "4yes"; then
+ # LFS is go!
+ off_t_fmt='#define APR_OFF_T_FMT APR_INT64_T_FMT'
+ off_t_value='off64_t'
+elif test "${ac_cv_sizeof_off_t}x${ac_cv_sizeof_long}" = "4x4"; then
+ # Special case: off_t may change size with _FILE_OFFSET_BITS
+ # on 32-bit systems with LFS support. To avoid compatibility
+ # with other software which may export _FILE_OFFSET_BITS,
+ # hard-code apr_off_t to long.
+ off_t_value=long
+ off_t_fmt='#define APR_OFF_T_FMT "ld"'
+elif test "$ac_cv_type_off_t" = "yes"; then
+ off_t_value=off_t
+ # off_t is more commonly a long than an int; prefer that case
+ # where int and long are the same size.
+ if test "$ac_cv_sizeof_off_t" = "$ac_cv_sizeof_long"; then
off_t_fmt='#define APR_OFF_T_FMT "ld"'
+ elif test "$ac_cv_sizeof_off_t" = "$ac_cv_sizeof_int"; then
+ off_t_fmt='#define APR_OFF_T_FMT "d"'
elif test "$ac_cv_sizeof_off_t" = "$ac_cv_sizeof_long_long"; then
off_t_fmt='#define APR_OFF_T_FMT APR_INT64_T_FMT'
else
- off_t_fmt='#error Can not determine the proper size for off_t'
+ AC_ERROR([could not determine the size of off_t])
+ fi
+else
+ # Fallback on int
+ off_t_value=apr_int32_t
+ off_t_fmt=d
fi
+AC_MSG_RESULT($off_t_value)
APR_CHECK_SIZEOF_EXTENDED([#include <sys/types.h>], pid_t, 8)
@@ -1188,7 +1262,6 @@
size_t_fmt='#define APR_SIZE_T_FMT "ld"'
;;
*-os2*)
- off_t_fmt='#define APR_OFF_T_FMT "ld"'
size_t_fmt='#define APR_SIZE_T_FMT "lu"'
;;
*-solaris*)
@@ -1208,16 +1281,6 @@
;;
esac
-# Override format string for off_t more carefully: only use hard-coded
-# choice if using a 32-bit off_t on platforms which support LFS.
-if test "$ac_cv_sizeof_off_t" = "4"; then
- case $host in
- *linux*|*-solaris*|*aix[[45]]*)
- off_t_fmt='#define APR_OFF_T_FMT "ld"'
- ;;
- esac
-fi
-
AC_SUBST(voidp_size)
AC_SUBST(short_value)
AC_SUBST(int_value)
@@ -1238,6 +1301,7 @@
AC_SUBST(uint64_literal)
AC_SUBST(stdint)
AC_SUBST(bigendian)
+AC_SUBST(aprlfs)
dnl ----------------------------- Checking for string functions
AC_CHECK_FUNCS(strnicmp, have_strnicmp="1", have_strnicmp="0")
1.72 +3 -3 apr/file_io/unix/filestat.c
Index: filestat.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/filestat.c,v
retrieving revision 1.71
retrieving revision 1.72
diff -w -d -u -r1.71 -r1.72
--- filestat.c 13 Feb 2004 09:38:25 -0000 1.71
+++ filestat.c 27 Mar 2004 13:11:17 -0000 1.72
@@ -66,7 +66,7 @@
return type;
}
-static void fill_out_finfo(apr_finfo_t *finfo, struct stat *info,
+static void fill_out_finfo(apr_finfo_t *finfo, struct_stat *info,
apr_int32_t wanted)
{
finfo->valid = APR_FINFO_MIN | APR_FINFO_IDENT | APR_FINFO_NLINK
@@ -94,7 +94,7 @@
apr_int32_t wanted,
apr_file_t *thefile)
{
- struct stat info;
+ struct_stat info;
if (thefile->buffered) {
apr_status_t rv = apr_file_flush(thefile);
@@ -227,7 +227,7 @@
const char *fname,
apr_int32_t wanted, apr_pool_t *pool)
{
- struct stat info;
+ struct_stat info;
int srv;
if (wanted & APR_FINFO_LINK)
1.30 +5 -0 apr/file_io/unix/mktemp.c
Index: mktemp.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/mktemp.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -w -d -u -r1.29 -r1.30
--- mktemp.c 13 Feb 2004 09:38:25 -0000 1.29
+++ mktemp.c 27 Mar 2004 13:11:17 -0000 1.30
@@ -182,7 +182,12 @@
return gettemp(template, fp, flags, p);
#else
+#ifdef HAVE_MKSTEMP64
+ fd = mkstemp64(template);
+#else
fd = mkstemp(template);
+#endif
+
if (fd == -1) {
return errno;
}
1.116 +4 -0 apr/file_io/unix/open.c
Index: open.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/open.c,v
retrieving revision 1.115
retrieving revision 1.116
diff -w -d -u -r1.115 -r1.116
--- open.c 13 Feb 2004 09:38:26 -0000 1.115
+++ open.c 27 Mar 2004 13:11:17 -0000 1.116
@@ -99,6 +99,10 @@
}
#endif
+#if APR_HAS_LARGE_FILES && defined(_LARGEFILE64_SOURCE)
+ oflags |= O_LARGEFILE;
+#endif
+
#if APR_HAS_THREADS
if ((flag & APR_BUFFERED) && (flag & APR_XTHREAD)) {
rv = apr_thread_mutex_create(&thlock,
1.89 +0 -4 apr/file_io/unix/readwrite.c
Index: readwrite.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/readwrite.c,v
retrieving revision 1.88
retrieving revision 1.89
diff -w -d -u -r1.88 -r1.89
--- readwrite.c 13 Feb 2004 09:38:26 -0000 1.88
+++ readwrite.c 27 Mar 2004 13:11:17 -0000 1.89
@@ -164,11 +164,7 @@
*/
apr_int64_t offset = thefile->filePtr - thefile->dataRead +
thefile->bufpos;
if (offset != thefile->filePtr)
-#if defined(NETWARE) && APR_HAS_LARGE_FILES
- lseek64(thefile->filedes, offset, SEEK_SET);
-#else
lseek(thefile->filedes, offset, SEEK_SET);
-#endif
thefile->bufpos = thefile->dataRead = 0;
thefile->direction = 1;
}
1.34 +0 -13 apr/file_io/unix/seek.c
Index: seek.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/seek.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -w -d -u -r1.33 -r1.34
--- seek.c 13 Feb 2004 09:38:26 -0000 1.33
+++ seek.c 27 Mar 2004 13:11:17 -0000 1.34
@@ -31,11 +31,7 @@
rc = 0;
}
else {
-#if defined(NETWARE) && APR_HAS_LARGE_FILES
- rc = lseek64(thefile->filedes, pos, SEEK_SET);
-#else
rc = lseek(thefile->filedes, pos, SEEK_SET);
-#endif
if (rc != -1 ) {
thefile->bufpos = thefile->dataRead = 0;
@@ -81,12 +77,7 @@
return rc;
}
else {
-
-#if defined(NETWARE) && APR_HAS_LARGE_FILES
- rv = lseek64(thefile->filedes, *offset, where);
-#else
rv = lseek(thefile->filedes, *offset, where);
-#endif
if (rv == -1) {
*offset = -1;
return errno;
@@ -100,11 +91,7 @@
apr_status_t apr_file_trunc(apr_file_t *fp, apr_off_t offset)
{
-#if defined(NETWARE) && APR_HAS_LARGE_FILES
- if (ftruncate64(fp->filedes, offset) == -1) {
-#else
if (ftruncate(fp->filedes, offset) == -1) {
-#endif
return errno;
}
return setptr(fp, offset);
1.135 +1 -1 apr/include/apr.h.in
Index: apr.h.in
===================================================================
RCS file: /home/cvs/apr/include/apr.h.in,v
retrieving revision 1.134
retrieving revision 1.135
diff -w -d -u -r1.134 -r1.135
--- apr.h.in 28 Feb 2004 18:31:41 -0000 1.134
+++ apr.h.in 27 Mar 2004 13:11:17 -0000 1.135
@@ -218,7 +218,7 @@
#define APR_HAS_UNICODE_FS 0
#define APR_HAS_PROC_INVOKED 0
#define APR_HAS_USER 1
-#define APR_HAS_LARGE_FILES 0
+#define APR_HAS_LARGE_FILES @aprlfs@
#define APR_HAS_XTHREAD_FILES 0
#define APR_HAS_OS_UUID 0
1.6 +7 -0 apr/include/arch/netware/apr_arch_file_io.h
Index: apr_arch_file_io.h
===================================================================
RCS file: /home/cvs/apr/include/arch/netware/apr_arch_file_io.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -w -d -u -r1.5 -r1.6
--- apr_arch_file_io.h 13 Feb 2004 09:38:29 -0000 1.5
+++ apr_arch_file_io.h 27 Mar 2004 13:11:17 -0000 1.6
@@ -70,6 +70,13 @@
#define APR_FILE_BUFSIZE 4096
+#if APR_HAS_LARGE_FILES
+#define lseek(f,o,w) lseek64(f,o,w)
+#define ftruncate(f,l) ftruncate64(f,l)
+#endif
+
+typedef struct stat struct_stat;
+
struct apr_file_t {
apr_pool_t *pool;
int filedes;
1.7 +11 -0 apr/include/arch/unix/apr_arch_file_io.h
Index: apr_arch_file_io.h
===================================================================
RCS file: /home/cvs/apr/include/arch/unix/apr_arch_file_io.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -w -d -u -r1.6 -r1.7
--- apr_arch_file_io.h 13 Feb 2004 09:38:30 -0000 1.6
+++ apr_arch_file_io.h 27 Mar 2004 13:11:18 -0000 1.7
@@ -109,6 +109,17 @@
#endif
};
+#if APR_HAS_LARGE_FILES && defined(_LARGEFILE64_SOURCE)
+#define stat(f,b) stat64(f,b)
+#define lstat(f,b) lstat64(f,b)
+#define fstat(f,b) fstat64(f,b)
+#define lseek(f,o,w) lseek64(f,o,w)
+#define ftruncate(f,l) ftruncate64(f,l)
+typedef struct stat64 struct_stat;
+#else
+typedef struct stat struct_stat;
+#endif
+
struct apr_dir_t {
apr_pool_t *pool;
char *dirname;
1.53 +8 -0 apr/mmap/unix/mmap.c
Index: mmap.c
===================================================================
RCS file: /home/cvs/apr/mmap/unix/mmap.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -w -d -u -r1.52 -r1.53
--- mmap.c 13 Feb 2004 09:38:33 -0000 1.52
+++ mmap.c 27 Mar 2004 13:11:18 -0000 1.53
@@ -83,6 +83,14 @@
apr_int32_t native_flags = 0;
#endif
+#if APR_HAS_LARGE_FILES && defined(HAVE_MMAP64)
+#define mmap mmap64
+#elif APR_HAS_LARGE_FILES && SIZEOF_OFF_T == 4
+ /* LFS but no mmap64: check for overflow */
+ if ((apr_int64_t)offset + size > INT_MAX)
+ return APR_EINVAL;
+#endif
+
if (size == 0)
return APR_EINVAL;
1.104 +47 -5 apr/network_io/unix/sendrecv.c
Index: sendrecv.c
===================================================================
RCS file: /home/cvs/apr/network_io/unix/sendrecv.c,v
retrieving revision 1.103
retrieving revision 1.104
diff -w -d -u -r1.103 -r1.104
--- sendrecv.c 13 Feb 2004 09:38:33 -0000 1.103
+++ sendrecv.c 27 Mar 2004 13:11:18 -0000 1.104
@@ -243,10 +243,28 @@
apr_hdtr_t *hdtr, apr_off_t *offset,
apr_size_t *len, apr_int32_t flags)
{
- off_t off = *offset;
int rv, nbytes = 0, total_hdrbytes, i;
apr_status_t arv;
+#if APR_HAS_LARGE_FILES && defined(HAVE_SENDFILE64)
+ apr_off_t off = *offset;
+#define sendfile sendfile64
+
+#elif APR_HAS_LARGE_FILES && SIZEOF_OFF_T == 4
+ /* 64-bit apr_off_t but no sendfile64(): fail if trying to send
+ * past the 2Gb limit. */
+ off_t off;
+
+ if ((apr_int64_t)*offset + *len > INT_MAX) {
+ return EINVAL;
+ }
+
+ off = *offset;
+
+#else
+ off_t off = *offset;
+#endif
+
if (!hdtr) {
hdtr = &no_hdtr;
}
@@ -562,6 +580,24 @@
struct iovec hdtrarray[2];
char *headerbuf, *trailerbuf;
+#if APR_HAS_LARGE_FILES && defined(HAVE_SENDFILE64)
+ /* later HP-UXes have a sendfile64() */
+#define sendfile sendfile64
+ apr_off_t off = *offset;
+
+#elif APR_HAS_LARGE_FILES && SIZEOF_OFF_T == 4
+ /* HP-UX 11.00 doesn't have a sendfile64(): fail if trying to send
+ * past the 2Gb limit */
+ off_t off;
+
+ if ((apr_int64_t)*offset + *len > INT_MAX) {
+ return EINVAL;
+ }
+ off = *offset;
+#else
+ apr_off_t off = *offset;
+#endif
+
if (!hdtr) {
hdtr = &no_hdtr;
}
@@ -627,7 +663,7 @@
if (nbytes) { /* any bytes to send from the file? */
rc = sendfile(sock->socketdes, /* socket */
file->filedes, /* file descriptor to send */
- *offset, /* where in the file to
start */
+ off, /* where in the file to
start */
nbytes, /* number of bytes to send
from file */
hdtrarray, /* Headers/footers */
flags); /* undefined, set to 0 */
@@ -650,7 +686,7 @@
if (nbytes) {
rc = sendfile(sock->socketdes, /* socket */
file->filedes, /* file descriptor to
send */
- *offset, /* where in the file
to start */
+ off, /* where in the file
to start */
nbytes, /* number of bytes to
send from file */
hdtrarray, /* Headers/footers */
flags); /* undefined, set to 0
*/
@@ -838,6 +874,12 @@
* 111298-01, 108529-09, 109473-06, 109235-04, 108996-02, 111296-01,
109026-04,
* 108992-13
*/
+
+#if APR_HAS_LARGE_FILES && defined(HAVE_SENDFILEV64)
+#define sendfilevec_t sendfilevec64_t
+#define sendfilev sendfilev64
+#endif
+
apr_status_t apr_socket_sendfile(apr_socket_t *sock, apr_file_t *file,
apr_hdtr_t *hdtr, apr_off_t *offset,
apr_size_t *len, apr_int32_t flags)
@@ -865,7 +907,7 @@
for (i = 0; i < hdtr->numheaders; i++, curvec++) {
sfv[curvec].sfv_fd = SFV_FD_SELF;
sfv[curvec].sfv_flag = 0;
- sfv[curvec].sfv_off = (off_t)hdtr->headers[i].iov_base;
+ sfv[curvec].sfv_off = (apr_off_t)hdtr->headers[i].iov_base;
sfv[curvec].sfv_len = hdtr->headers[i].iov_len;
requested_len += sfv[curvec].sfv_len;
}
@@ -889,7 +931,7 @@
for (i = 0; i < hdtr->numtrailers; i++, curvec++) {
sfv[curvec].sfv_fd = SFV_FD_SELF;
sfv[curvec].sfv_flag = 0;
- sfv[curvec].sfv_off = (off_t)hdtr->trailers[i].iov_base;
+ sfv[curvec].sfv_off = (apr_off_t)hdtr->trailers[i].iov_base;
sfv[curvec].sfv_len = hdtr->trailers[i].iov_len;
requested_len += sfv[curvec].sfv_len;
}
1.52 +1 -1 apr/test/.cvsignore
Index: .cvsignore
===================================================================
RCS file: /home/cvs/apr/test/.cvsignore,v
retrieving revision 1.51
retrieving revision 1.52
diff -w -d -u -r1.51 -r1.52
--- .cvsignore 18 Mar 2004 17:41:08 -0000 1.51
+++ .cvsignore 27 Mar 2004 13:11:18 -0000 1.52
@@ -42,4 +42,4 @@
testmutexscope
testshmconsumer
testshmproducer
-
+lfstests
1.158 +1 -1 apr/test/Makefile.in
Index: Makefile.in
===================================================================
RCS file: /home/cvs/apr/test/Makefile.in,v
retrieving revision 1.157
retrieving revision 1.158
diff -w -d -u -r1.157 -r1.158
--- Makefile.in 22 Mar 2004 20:56:29 -0000 1.157
+++ Makefile.in 27 Mar 2004 13:11:18 -0000 1.158
@@ -102,7 +102,7 @@
testhash.lo testargs.lo testnames.lo testuser.lo testpath.lo \
testenv.lo testprocmutex.lo testrand2.lo testfnmatch.lo \
testatomic.lo testflock.lo testshm.lo testsock.lo testglobalmutex.lo
\
- teststrnatcmp.lo testfilecopy.lo testtemp.lo
+ teststrnatcmp.lo testfilecopy.lo testtemp.lo testlfs.lo
testall: $(TESTS) mod_test.la libmod_test.la [EMAIL PROTECTED]@ \
[EMAIL PROTECTED]@ CuTest.lo [EMAIL PROTECTED]@ \
1.56 +1 -0 apr/test/test_apr.h
Index: test_apr.h
===================================================================
RCS file: /home/cvs/apr/test/test_apr.h,v
retrieving revision 1.55
retrieving revision 1.56
diff -w -d -u -r1.55 -r1.56
--- test_apr.h 18 Mar 2004 17:46:02 -0000 1.55
+++ test_apr.h 27 Mar 2004 13:11:18 -0000 1.56
@@ -52,6 +52,7 @@
CuSuite *testhash(void);
CuSuite *testipsub(void);
CuSuite *testlock(void);
+CuSuite *testlfs(void);
CuSuite *testmmap(void);
CuSuite *testnames(void);
CuSuite *testoc(void);
1.60 +1 -0 apr/test/testall.c
Index: testall.c
===================================================================
RCS file: /home/cvs/apr/test/testall.c,v
retrieving revision 1.59
retrieving revision 1.60
diff -w -d -u -r1.59 -r1.60
--- testall.c 18 Mar 2004 17:46:02 -0000 1.59
+++ testall.c 27 Mar 2004 13:11:18 -0000 1.60
@@ -54,6 +54,7 @@
{"testglobalmutex", testglobalmutex},
{"testhash", testhash},
{"testipsub", testipsub},
+ {"testlfs", testlfs},
{"testlock", testlock},
{"testmmap", testmmap},
{"testnames", testnames},
1.1 apr/test/testlfs.c
Index: testlfs.c
===================================================================
/* Copyright 2004 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "apr_file_io.h"
#include "apr_file_info.h"
#include "apr_errno.h"
#include "apr_general.h"
#include "apr_poll.h"
#include "apr_strings.h"
#include "apr_lib.h"
#include "apr_mmap.h"
#include "test_apr.h"
/* Only enable these tests by default on platforms which support sparse
* files... just Unixes? */
#if APR_HAS_LARGE_FILES && !defined(WIN32) && !defined(OS2) &&
!defined(NETWARE)
#define USE_LFS_TESTS
/* Tests which create an 8Gb sparse file and then check it can be used
* as normal. */
static apr_off_t eightGb = APR_INT64_C(2) << 32;
static int madefile = 0;
#define PRECOND if (!madefile) CuNotImpl(tc, NULL)
#define TESTDIR "lfstests"
#define TESTFILE "large.bin"
#define TESTFN "lfstests/large.bin"
static void test_open(CuTest *tc)
{
apr_file_t *f;
apr_status_t rv;
rv = apr_dir_make(TESTDIR, APR_OS_DEFAULT, p);
if (rv && !APR_STATUS_IS_EEXIST(rv)) {
apr_assert_success(tc, "make test directory", rv);
}
apr_assert_success(tc, "open file",
apr_file_open(&f, TESTFN,
APR_CREATE | APR_WRITE | APR_TRUNCATE,
APR_OS_DEFAULT, p));
rv = apr_file_trunc(f, eightGb);
apr_assert_success(tc, "close large file", apr_file_close(f));
/* 8Gb may pass rlimits or filesystem limits */
#ifdef EFBIG
if (rv == EFBIG) {
CuNotImpl(tc, "Creation of large file (limited by rlimit or fs?)");
} else
#endif
{
apr_assert_success(tc, "truncate file to 8gb", rv);
}
madefile = 1;
}
static void test_reopen(CuTest *tc)
{
apr_file_t *fh;
apr_finfo_t finfo;
PRECOND;
apr_assert_success(tc, "re-open 8Gb file",
apr_file_open(&fh, TESTFN, APR_READ, APR_OS_DEFAULT,
p));
apr_assert_success(tc, "file_info_get failed",
apr_file_info_get(&finfo, APR_FINFO_NORM, fh));
CuAssert(tc, "file_info_get gave incorrect size",
finfo.size == eightGb);
apr_assert_success(tc, "re-close large file", apr_file_close(fh));
}
static void test_stat(CuTest *tc)
{
apr_finfo_t finfo;
PRECOND;
apr_assert_success(tc, "stat large file",
apr_stat(&finfo, TESTFN, APR_FINFO_NORM, p));
CuAssert(tc, "stat gave incorrect size", finfo.size == eightGb);
}
static void test_readdir(CuTest *tc)
{
apr_dir_t *dh;
apr_status_t rv;
PRECOND;
apr_assert_success(tc, "open test directory",
apr_dir_open(&dh, TESTDIR, p));
do {
apr_finfo_t finfo;
rv = apr_dir_read(&finfo, APR_FINFO_NORM, dh);
if (rv == APR_SUCCESS && strcmp(finfo.name, TESTFILE) == 0) {
CuAssert(tc, "apr_dir_read gave incorrect size for large file",
finfo.size == eightGb);
}
} while (rv == APR_SUCCESS);
if (!APR_STATUS_IS_ENOENT(rv)) {
apr_assert_success(tc, "apr_dir_read failed", rv);
}
apr_assert_success(tc, "close test directory",
apr_dir_close(dh));
}
#define TESTSTR "Hello, world."
static void test_append(CuTest *tc)
{
apr_file_t *fh;
apr_finfo_t finfo;
PRECOND;
apr_assert_success(tc, "open 8Gb file for append",
apr_file_open(&fh, TESTFN, APR_WRITE | APR_APPEND,
APR_OS_DEFAULT, p));
apr_assert_success(tc, "append to 8Gb file",
apr_file_write_full(fh, TESTSTR, strlen(TESTSTR),
NULL));
apr_assert_success(tc, "file_info_get failed",
apr_file_info_get(&finfo, APR_FINFO_NORM, fh));
CuAssert(tc, "file_info_get gave incorrect size",
finfo.size == eightGb + strlen(TESTSTR));
apr_assert_success(tc, "close 8Gb file", apr_file_close(fh));
}
static void test_seek(CuTest *tc)
{
apr_file_t *fh;
apr_off_t pos;
PRECOND;
apr_assert_success(tc, "open 8Gb file for writing",
apr_file_open(&fh, TESTFN, APR_WRITE,
APR_OS_DEFAULT, p));
pos = eightGb;
apr_assert_success(tc, "seek to 8Gb", apr_file_seek(fh, APR_SET, &pos));
CuAssert(tc, "seek gave 8Gb offset", pos == eightGb);
pos = 0;
apr_assert_success(tc, "relative seek to 0", apr_file_seek(fh, APR_CUR,
&pos));
CuAssert(tc, "relative seek gave 8Gb offset", pos == eightGb);
apr_file_close(fh);
}
static void test_write(CuTest *tc)
{
apr_file_t *fh;
apr_off_t pos = eightGb - 4;
PRECOND;
apr_assert_success(tc, "re-open 8Gb file",
apr_file_open(&fh, TESTFN, APR_WRITE, APR_OS_DEFAULT,
p));
apr_assert_success(tc, "seek to 8Gb - 4",
apr_file_seek(fh, APR_SET, &pos));
CuAssert(tc, "seek gave 8Gb-4 offset", pos == eightGb - 4);
apr_assert_success(tc, "write magic string to 8Gb-4",
apr_file_write_full(fh, "FISH", 4, NULL));
apr_assert_success(tc, "close 8Gb file", apr_file_close(fh));
}
#if APR_HAS_MMAP
static void test_mmap(CuTest *tc)
{
apr_mmap_t *map;
apr_file_t *fh;
apr_size_t len = 16384; /* hopefully a multiple of the page size */
apr_off_t off = eightGb - len;
void *ptr;
PRECOND;
apr_assert_success(tc, "open 8gb file for mmap",
apr_file_open(&fh, TESTFN, APR_READ, APR_OS_DEFAULT,
p));
apr_assert_success(tc, "mmap 8Gb file",
apr_mmap_create(&map, fh, off, len, APR_MMAP_READ, p));
apr_assert_success(tc, "close file", apr_file_close(fh));
CuAssert(tc, "mapped a 16K block", map->size == len);
apr_assert_success(tc, "get pointer into mmaped region",
apr_mmap_offset(&ptr, map, len - 4));
CuAssert(tc, "pointer was not NULL", ptr != NULL);
CuAssert(tc, "found the magic string", memcmp(ptr, "FISH", 4) == 0);
apr_assert_success(tc, "delete mmap handle", apr_mmap_delete(map));
}
#endif /* APR_HAS_MMAP */
static void test_format(CuTest *tc)
{
apr_off_t off;
PRECOND;
off = apr_atoi64(apr_off_t_toa(p, eightGb));
CuAssert(tc, "apr_atoi64 parsed apr_off_t_toa result incorrectly",
off == eightGb);
}
#else
static void test_nolfs(CuTest *tc)
{
CuNotImpl(tc, "Large Files not supported");
}
#endif
CuSuite *testlfs(void)
{
CuSuite *suite = CuSuiteNew("Large File Support");
#ifdef USE_LFS_TESTS
SUITE_ADD_TEST(suite, test_open);
SUITE_ADD_TEST(suite, test_reopen);
SUITE_ADD_TEST(suite, test_stat);
SUITE_ADD_TEST(suite, test_readdir);
SUITE_ADD_TEST(suite, test_append);
SUITE_ADD_TEST(suite, test_seek);
SUITE_ADD_TEST(suite, test_write);
#if APR_HAS_MMAP
SUITE_ADD_TEST(suite, test_mmap);
#endif
SUITE_ADD_TEST(suite, test_format);
#else
SUITE_ADD_TEST(suite, test_nolfs)
#endif
return suite;
}