summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjerenkrantz <jerenkrantz@13f79535-47bb-0310-9956-ffa450edef68>2004-11-17 01:07:02 +0000
committerjerenkrantz <jerenkrantz@13f79535-47bb-0310-9956-ffa450edef68>2004-11-17 01:07:02 +0000
commit6c396ff5c726ad3ccba9f8454d1d41ab65513945 (patch)
tree9fe875f78a137b87968ce8d5bcf5b554f2608fab
parent9ffc3ba97e22859b387d44eaf5d48e559c6e8874 (diff)
downloadlibapr-6c396ff5c726ad3ccba9f8454d1d41ab65513945.tar.gz
Merge in changes from trunk to 1.0.x.
Changes have been reviewed to be binary compatible with 1.0.0 by Justin to the best of his sleep-deprived ability. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/branches/1.0.x@76072 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--.cvsignore4
-rw-r--r--CHANGES34
-rw-r--r--Makefile.in2
-rw-r--r--STATUS7
-rw-r--r--atomic/netware/apr_atomic.c3
-rw-r--r--atomic/unix/apr_atomic.c6
-rw-r--r--atomic/win32/apr_atomic.c8
-rw-r--r--build/apr_hints.m43
-rw-r--r--build/jlibtool.c194
-rw-r--r--configure.in4
-rw-r--r--file_io/netware/mktemp.c2
-rw-r--r--file_io/os2/filesys.c13
-rw-r--r--file_io/unix/readwrite.c66
-rw-r--r--file_io/win32/dir.c4
-rw-r--r--file_io/win32/filedup.c14
-rw-r--r--file_io/win32/open.c6
-rw-r--r--file_io/win32/readwrite.c51
-rw-r--r--include/apr.hw2
-rw-r--r--include/apr_network_io.h19
-rw-r--r--include/apr_shm.h1
-rw-r--r--include/apr_version.h7
-rw-r--r--include/arch/apr_private_common.h5
-rw-r--r--include/arch/netware/apr_private.h5
-rw-r--r--include/arch/win32/apr_arch_threadproc.h2
-rw-r--r--include/arch/win32/apr_private.h3
-rw-r--r--memory/unix/apr_pools.c24
-rw-r--r--misc/unix/charset.c2
-rw-r--r--misc/unix/errorcodes.c8
-rw-r--r--network_io/win32/sendrecv.c86
-rw-r--r--poll/unix/poll.c4
-rw-r--r--random/unix/apr_random.c4
-rw-r--r--shmem/unix/shm.c14
-rw-r--r--tables/apr_hash.c12
-rw-r--r--test/Makefile.in3
-rw-r--r--test/Makefile.win6
-rw-r--r--test/testrand2.c59
-rw-r--r--test/teststr.c6
-rw-r--r--threadproc/beos/.cvsignore1
-rw-r--r--threadproc/win32/proc.c40
-rw-r--r--threadproc/win32/thread.c39
40 files changed, 596 insertions, 177 deletions
diff --git a/.cvsignore b/.cvsignore
index 4b17e2735..13ef1e0e2 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -6,6 +6,7 @@ config.status
configure
libtool
apr-config
+apr-*-config
apr-config.out
LibD
LibR
@@ -38,4 +39,5 @@ build-outputs.mk
*.bbg
*.da
coverage
-apr.pc
+apr*.pc
+apr.spec
diff --git a/CHANGES b/CHANGES
index 04a92d3ff..cd7bf0573 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,37 @@
+Changes for APR 1.0.1
+
+ *) Fix HUP return codes in pollset when using KQueue.
+ [Paul Querna]
+
+ *) Prevent unbounded memory use during repeated operations on a hash table.
+ [Julian Foad <julianfoad btopenworld.com>
+
+ *) Moved repository to SVN
+ [Hackathon]
+
+ *) jlibtool: Ignore '-export-symbols-regexp' option.
+ [Justin Erenkrantz]
+
+ *) fix apr_file_dup and apr_file_dup2 win32 implementations
+ to create a mutex [Steve Hay <steve.hay uk.radan.com>]
+
+ *) Makes the threads to behave like on posix. If the thread is created
+ without APR_DETACH expect that the thread_join will be called, so don't
+ close the handle in advance, if the thread has already finished.
+ [Mladen Turk]
+
+ *) The apr/test/Makefile.win is missing a target to build a
+ readchild.exe that test is depending on but is never built.
+ [Mladen Turk]
+
+ *) Improve apr_file_gets() performance on buffered files. [Justin Erenkrantz]
+
+ *) Win32: Fix bug in apr_socket_sendfile that interferred with
+ Win32 LSPs. PR 23982 [Jan Bilek, Bill Stoddard]
+
+ *) Win32: Fix bug tracking the file pointer on a file opened for
+ overlapped/APR_XTHREAD io. [Bill Stoddard]
+
Changes with APR 1.0
*) Only install apr-$MAJOR-config and add appropriate detection code to
diff --git a/Makefile.in b/Makefile.in
index 4397c96fc..0c29cba8a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -76,7 +76,7 @@ install: $(TARGET_LIB) apr-config.out build/apr_rules.out
for f in libtool shlibtool; do \
if test -f $${f}; then $(INSTALL) -m 755 $${f} $(DESTDIR)$(installbuilddir); fi; \
done
- $(INSTALL) -m 755 build/mkdir.sh $(DESTDIR)$(installbuilddir)
+ $(INSTALL) -m 755 $(top_srcdir)/build/mkdir.sh $(DESTDIR)$(installbuilddir)
for f in make_exports.awk make_var_export.awk; do \
$(INSTALL_DATA) $(top_srcdir)/build/$${f} $(DESTDIR)$(installbuilddir); \
done
diff --git a/STATUS b/STATUS
index 1dd148758..533d51d46 100644
--- a/STATUS
+++ b/STATUS
@@ -1,5 +1,5 @@
APACHE PORTABLE RUNTIME (APR) LIBRARY STATUS: -*-text-*-
-Last modified at [$Date: 2004/06/30 11:29:48 $]
+Last modified at [$Date$]
Releases:
@@ -23,10 +23,7 @@ Bundled with httpd
2.0a1 : released March 10, 2000
-RELEASE 0.9 SHOWSTOPPERS:
-
-
-RELEASE 1.0 SHOWSTOPPERS:
+RELEASE 1.0.1 SHOWSTOPPERS:
CURRENT VOTES:
diff --git a/atomic/netware/apr_atomic.c b/atomic/netware/apr_atomic.c
index 17ffe14d5..069b1bd16 100644
--- a/atomic/netware/apr_atomic.c
+++ b/atomic/netware/apr_atomic.c
@@ -60,8 +60,7 @@ APR_DECLARE(apr_uint32_t) apr_atomic_xchg32(volatile apr_uint32_t *mem, apr_uint
APR_DECLARE(int) apr_atomic_dec32(volatile apr_uint32_t *mem)
{
- atomic_dec((unsigned long *)mem);
- return *mem;
+ return (atomic_xchgadd((unsigned long *)mem, 0xFFFFFFFF) - 1);
}
APR_DECLARE(void *) apr_atomic_casptr(volatile void **mem, void *with, const void *cmp)
diff --git a/atomic/unix/apr_atomic.c b/atomic/unix/apr_atomic.c
index 5827ba091..bf457c1ea 100644
--- a/atomic/unix/apr_atomic.c
+++ b/atomic/unix/apr_atomic.c
@@ -21,6 +21,12 @@
#include <stdlib.h>
+#if defined(__GNUC__) && defined(__STRICT_ANSI__) && !defined(USE_GENERIC_ATOMICS)
+/* force use of generic atomics if building e.g. with -std=c89, which
+ * doesn't allow inline asm */
+#define USE_GENERIC_ATOMICS
+#endif
+
#if (defined(__i386__) || defined(__x86_64__)) \
&& defined(__GNUC__) && !defined(USE_GENERIC_ATOMICS)
diff --git a/atomic/win32/apr_atomic.c b/atomic/win32/apr_atomic.c
index d83d60c89..b42a2028e 100644
--- a/atomic/win32/apr_atomic.c
+++ b/atomic/win32/apr_atomic.c
@@ -40,7 +40,11 @@ typedef WINBASEAPI void * (WINAPI * apr_atomic_win32_ptr_ptr_ptr_fn)
APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint32_t val)
{
+#if (defined(_M_IA64) || defined(_M_AMD64))
+ return InterlockedExchangeAdd(mem, val);
+#else
return ((apr_atomic_win32_ptr_val_fn)InterlockedExchangeAdd)(mem, val);
+#endif
}
/* Of course we want the 2's compliment of the unsigned value, val */
@@ -48,7 +52,11 @@ APR_DECLARE(apr_uint32_t) apr_atomic_add32(volatile apr_uint32_t *mem, apr_uint3
APR_DECLARE(void) apr_atomic_sub32(volatile apr_uint32_t *mem, apr_uint32_t val)
{
+#if (defined(_M_IA64) || defined(_M_AMD64))
+ InterlockedExchangeAdd(mem, -val);
+#else
((apr_atomic_win32_ptr_val_fn)InterlockedExchangeAdd)(mem, -val);
+#endif
}
APR_DECLARE(apr_uint32_t) apr_atomic_inc32(volatile apr_uint32_t *mem)
diff --git a/build/apr_hints.m4 b/build/apr_hints.m4
index 5aa03c952..edd5f9770 100644
--- a/build/apr_hints.m4
+++ b/build/apr_hints.m4
@@ -131,6 +131,9 @@ dnl # Not a problem in 10.20. Otherwise, who knows?
;;
*-openbsd*)
APR_ADDTO(CPPFLAGS, [-D_POSIX_THREADS])
+ # binding to an ephemeral port fails on OpenBSD so override
+ # the test for O_NONBLOCK inheritance across accept().
+ APR_SETIFNULL(ac_cv_o_nonblock_inherited, [yes])
;;
*-netbsd*)
APR_ADDTO(CPPFLAGS, [-DNETBSD])
diff --git a/build/jlibtool.c b/build/jlibtool.c
index 6b1c35d69..5f38b6db6 100644
--- a/build/jlibtool.c
+++ b/build/jlibtool.c
@@ -66,7 +66,8 @@
# define DYNAMIC_LINK_OPTS "-flat_namespace -undefined suppress"
# define dynamic_link_version_func darwin_dynamic_link_function
# define DYNAMIC_INSTALL_NAME "-install_name"
-//-install_name /Users/jerenk/apache-2.0-cvs/lib/libapr.0.dylib -compatibility_version 1 -current_version 1.0
+/*-install_name /Users/jerenk/apache-2.0-cvs/lib/libapr.0.dylib -compatibility_version 1 -current_version 1.0 */
+# define LD_LIBRARY_PATH "DYLD_LIBRARY_PATH"
#endif
#if defined(__linux__) || defined(__FreeBSD__)
@@ -80,8 +81,13 @@
# define RANLIB "ranlib"
# define PIC_FLAG "-fPIC"
# define RPATH "-rpath"
-# define DYNAMIC_LINK_OPTS "-shared"
+# define SHARED_OPTS "-shared"
+# define MODULE_OPTS "-shared"
+# define DYNAMIC_LINK_OPTS "-export-dynamic"
# define LINKER_FLAG_PREFIX "-Wl,"
+# define ADD_MINUS_L
+# define LD_RUN_PATH "LD_RUN_PATH"
+# define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
#endif
#if defined(_OSD_POSIX)
@@ -92,11 +98,30 @@
# define OBJECT_EXT "o"
# define LIBRARIAN "ar"
# define LIBRARIAN_OPTS "cr"
-# define DYNAMIC_LINK_OPTS "-G"
+# define SHARED_OPTS "-G"
+# define MODULE_OPTS "-G"
# define LINKER_FLAG_PREFIX "-Wl,"
# define NEED_SNPRINTF
#endif
+#if defined(sinix) && defined(mips) && defined(__SNI_TARG_UNIX)
+# define SHELL_CMD "/usr/bin/sh"
+# define DYNAMIC_LIB_EXT "so"
+# define MODULE_LIB_EXT "so"
+# define STATIC_LIB_EXT "a"
+# define OBJECT_EXT "o"
+# define LIBRARIAN "ar"
+# define LIBRARIAN_OPTS "cr"
+# define RPATH "-Brpath"
+# define SHARED_OPTS "-G"
+# define MODULE_OPTS "-G"
+# define DYNAMIC_LINK_OPTS "-Wl,-Blargedynsym"
+# define LINKER_FLAG_PREFIX "-Wl,"
+# define NEED_SNPRINTF
+# define LD_RUN_PATH "LD_RUN_PATH"
+# define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
+#endif
+
#ifndef SHELL_CMD
#error Unsupported platform: Please add defines for SHELL_CMD etc. for your platform.
#endif
@@ -140,6 +165,14 @@ enum pic_mode_e {
pic_AVOID,
};
+enum lib_type {
+ type_UNKNOWN,
+ type_DYNAMIC_LIB,
+ type_STATIC_LIB,
+ type_MODULE_LIB,
+ type_OBJECT,
+};
+
typedef struct {
const char **vals;
int num;
@@ -383,6 +416,23 @@ int run_command(command_t *cmd_data, count_chars *cc)
return external_spawn(cmd_data, spawn_args[0], (const char**)spawn_args);
}
+/*
+ * print configuration
+ * shlibpath_var is used in configure.
+ */
+void print_config()
+{
+#ifdef LD_RUN_PATH
+ printf("runpath_var=%s\n", LD_RUN_PATH);
+#endif
+#ifdef LD_LIBRARY_PATH
+ printf("shlibpath_var=%s\n", LD_LIBRARY_PATH);
+#endif
+#ifdef SHELL_CMD
+ printf("SHELL=\"%s\"\n", SHELL_CMD);
+#endif
+}
+
int parse_long_opt(char *arg, command_t *cmd_data)
{
char *equal_pos = strchr(arg, '=');
@@ -427,6 +477,8 @@ int parse_long_opt(char *arg, command_t *cmd_data)
printf("Version " VERSION "\n");
} else if (strcmp(var, "help") == 0) {
printf("Sorry. No help available.\n");
+ } else if (strcmp(var, "config") == 0) {
+ print_config();
} else {
return 0;
}
@@ -651,7 +703,7 @@ char *check_object_exists(command_t *cmd, const char *arg, int arglen)
}
if (!cmd->options.silent) {
- printf("Checking: %s\n", newarg);
+ printf("Checking (obj): %s\n", newarg);
}
rv = stat(newarg, &sb);
}
@@ -672,7 +724,7 @@ char *check_object_exists(command_t *cmd, const char *arg, int arglen)
* 1 - .libs suffix
*/
char *check_library_exists(command_t *cmd, const char *arg, int pathlen,
- int libdircheck)
+ int libdircheck, enum lib_type *libtype)
{
char *newarg, *ext;
int pass, rv, newpathlen;
@@ -699,24 +751,29 @@ char *check_library_exists(command_t *cmd, const char *arg, int pathlen,
case 0:
if (cmd->options.pic_mode != pic_AVOID || cmd->options.shared) {
strcpy(ext, DYNAMIC_LIB_EXT);
+ *libtype = type_DYNAMIC_LIB;
break;
}
pass = 1;
case 1:
strcpy(ext, STATIC_LIB_EXT);
+ *libtype = type_STATIC_LIB;
break;
case 2:
strcpy(ext, MODULE_LIB_EXT);
+ *libtype = type_MODULE_LIB;
break;
case 3:
strcpy(ext, OBJECT_EXT);
+ *libtype = type_OBJECT;
break;
default:
+ *libtype = type_UNKNOWN;
break;
}
if (!cmd->options.silent) {
- printf("Checking: %s\n", newarg);
+ printf("Checking (lib): %s\n", newarg);
}
rv = stat(newarg, &sb);
}
@@ -729,6 +786,72 @@ char *check_library_exists(command_t *cmd, const char *arg, int pathlen,
return NULL;
}
+/* Read the final install location and add it to runtime library search path. */
+#ifdef RPATH
+void add_rpath(count_chars *cc, const char *arg)
+{
+ FILE *f;
+ char path[256];
+ char *tmp;
+ int size=0;
+
+ f = fopen(arg,"r");
+ if (f == NULL) {
+ return;
+ }
+ fgets(path,sizeof(path), f);
+ fclose(f);
+ if (path[strlen(path)-1] == '\n') {
+ path[strlen(path)-1] = '\0';
+ }
+ /* Check that we have an absolut path.
+ * Otherwise the file could be a GNU libtool file.
+ */
+ if (path[0] != '/') {
+ return;
+ }
+#ifdef LINKER_FLAG_PREFIX
+ size = strlen(LINKER_FLAG_PREFIX);
+#endif
+ size = size + strlen(path) + strlen(RPATH) + 2;
+ tmp = malloc(size);
+ if (tmp == NULL) {
+ return;
+ }
+#ifdef LINKER_FLAG_PREFIX
+ strcpy(tmp, LINKER_FLAG_PREFIX);
+ strcat(tmp, RPATH);
+#else
+ strcpy(tmp, RPATH);
+#endif
+ strcat(tmp, "=");
+ strcat(tmp, path);
+
+ push_count_chars(cc, tmp);
+}
+#endif
+
+/* use -L -llibname to allow to use installed libraries */
+void add_minus_l(count_chars *cc, const char *arg)
+{
+ char *name = strrchr(arg, '/');
+ char *file = strrchr(arg, '.');
+ char *lib = strstr(name, "lib");
+
+ if (name !=NULL && file != NULL && lib == name+1) {
+ *name = '\0';
+ *file = '\0';
+ file = name;
+ file = file+4;
+ push_count_chars(cc, "-L ");
+ push_count_chars(cc, arg);
+ push_count_chars(cc, "-l");
+ push_count_chars(cc, file);
+ } else {
+ push_count_chars(cc, arg);
+ }
+}
+
void add_linker_flag_prefix(count_chars *cc, const char *arg)
{
#ifndef LINKER_FLAG_PREFIX
@@ -747,6 +870,7 @@ int parse_input_file_name(char *arg, command_t *cmd_data)
char *ext = strrchr(arg, '.');
char *name = strrchr(arg, '/');
int pathlen;
+ enum lib_type libtype;
char *newarg;
if (!ext) {
@@ -788,22 +912,34 @@ int parse_input_file_name(char *arg, command_t *cmd_data)
switch (cmd_data->mode) {
case mLink:
/* Try the .libs dir first! */
- newarg = check_library_exists(cmd_data, arg, pathlen, 1);
+ newarg = check_library_exists(cmd_data, arg, pathlen, 1, &libtype);
if (!newarg) {
/* Try the normal dir next. */
- newarg = check_library_exists(cmd_data, arg, pathlen, 0);
+ newarg = check_library_exists(cmd_data, arg, pathlen, 0, &libtype);
if (!newarg) {
printf("Can not find suitable library for %s\n", arg);
exit(1);
}
}
- if (cmd_data->mode != mLink) {
- push_count_chars(cmd_data->arglist, newarg);
+ /* It is not ok to just add the file: a library may added with:
+ 1 - -L path library_name. (For *.so in Linux).
+ 2 - library_name.
+ */
+#ifdef ADD_MINUS_L
+ if (libtype == type_DYNAMIC_LIB) {
+ add_minus_l(cmd_data->shared_opts.dependencies, newarg);
+ } else {
+ push_count_chars(cmd_data->shared_opts.dependencies, newarg);
}
- else {
- push_count_chars(cmd_data->shared_opts.dependencies, newarg);
+#else
+ push_count_chars(cmd_data->shared_opts.dependencies, newarg);
+#endif
+#ifdef RPATH
+ if (libtype == type_DYNAMIC_LIB) {
+ add_rpath(cmd_data->shared_opts.dependencies, arg);
}
+#endif
break;
case mInstall:
/* If we've already recorded a library to install, we're most
@@ -959,7 +1095,7 @@ void parse_args(int argc, char *argv[], command_t *cmd_data)
char *arg;
int argused;
- for (a=1; a < argc; a++) {
+ for (a = 1; a < argc; a++) {
arg = argv[a];
argused = 1;
@@ -985,6 +1121,10 @@ void parse_args(int argc, char *argv[], command_t *cmd_data)
/* Store for later deciphering */
cmd_data->version_info = argv[++a];
argused = 1;
+ } else if (strcmp(arg+1, "export-symbols-regex") == 0) {
+ /* Skip the argument. */
+ ++a;
+ argused = 1;
}
}
} else {
@@ -1349,9 +1489,6 @@ int run_mode(command_t *cmd_data)
lib_args[2] = NULL;
external_spawn(cmd_data, RANLIB, lib_args);
#endif
- if (!cmd_data->options.dry_run) {
- //link(
- }
}
if (cmd_data->output == otDynamicLibraryOnly ||
@@ -1446,6 +1583,27 @@ int ensure_fake_uptodate(command_t *cmd_data)
touch_args[2] = NULL;
return external_spawn(cmd_data, "touch", touch_args);
}
+#ifdef RPATH
+/* Store the install path in the *.la file */
+int add_for_runtime(command_t *cmd_data)
+{
+ if (cmd_data->mode == mInstall) {
+ return 0;
+ }
+ if (cmd_data->output == otDynamicLibraryOnly ||
+ cmd_data->output == otLibrary) {
+ FILE *f=fopen(cmd_data->fake_output_name,"w");
+ if (f == NULL) {
+ return -1;
+ }
+ fprintf(f,"%s\n", cmd_data->install_path);
+ fclose(f);
+ return(0);
+ } else {
+ return(ensure_fake_uptodate(cmd_data));
+ }
+}
+#endif
int main(int argc, char *argv[])
{
@@ -1488,7 +1646,11 @@ int main(int argc, char *argv[])
rc = run_mode(&cmd_data);
if (!rc) {
+#ifdef RPATH
+ add_for_runtime(&cmd_data);
+#else
ensure_fake_uptodate(&cmd_data);
+#endif
}
cleanup_tmp_dirs(&cmd_data);
diff --git a/configure.in b/configure.in
index 0722a3a68..227972a97 100644
--- a/configure.in
+++ b/configure.in
@@ -155,6 +155,10 @@ case $host in
LIBTOOL="$apr_builddir/libtool"
LIBTOOL_SRC="$apr_srcdir/build/jlibtool.c"
$CC $CFLAGS $CPPFLAGS -o $LIBTOOL $LIBTOOL_SRC
+ eval `$apr_builddir/libtool --config | grep "^shlibpath_var=[[A-Z_]]*$"`
+ if test "x$shlibpath_var" = "x"; then
+ shlibpath_var=REPLACE_WITH_YOUR_SHLIBPATH_VAR
+ fi
else
dnl libtoolize requires that the following not be indented
AC_PROG_LIBTOOL
diff --git a/file_io/netware/mktemp.c b/file_io/netware/mktemp.c
index 884a8c40b..58e89386b 100644
--- a/file_io/netware/mktemp.c
+++ b/file_io/netware/mktemp.c
@@ -27,7 +27,7 @@ APR_DECLARE(apr_status_t) apr_file_mktemp(apr_file_t **fp, char *template, apr_i
apr_status_t rv;
flags = (!flags) ? APR_CREATE | APR_READ | APR_WRITE |
- APR_DELONCLOSE : flags;
+ APR_DELONCLOSE : flags & ~APR_EXCL;
fd = mkstemp(template);
if (fd == -1) {
diff --git a/file_io/os2/filesys.c b/file_io/os2/filesys.c
index b323e488d..ef597b38e 100644
--- a/file_io/os2/filesys.c
+++ b/file_io/os2/filesys.c
@@ -94,12 +94,13 @@ apr_status_t filepath_drive_get(char **rootpath, char drive,
apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p)
{
- char path[APR_PATH_MAX];
-
- strcpy(path, root);
- if (path[1] == ':')
- path[0] = apr_toupper(path[0]);
- *rootpath = apr_pstrdup(p, path);
+ if (root[0] && apr_islower(root[0]) && root[1] == ':') {
+ *rootpath = apr_pstrdup(p, root);
+ (*rootpath)[0] = apr_toupper((*rootpath)[0]);
+ }
+ else {
+ *rootpath = root;
+ }
return APR_SUCCESS;
}
diff --git a/file_io/unix/readwrite.c b/file_io/unix/readwrite.c
index 1e6a6e665..98a11421d 100644
--- a/file_io/unix/readwrite.c
+++ b/file_io/unix/readwrite.c
@@ -24,9 +24,6 @@
#define USE_WAIT_FOR_IO
#endif
-/* problems:
- * 1) ungetchar not used for buffered files
- */
APR_DECLARE(apr_status_t) apr_file_read(apr_file_t *thefile, void *buf, apr_size_t *nbytes)
{
apr_ssize_t rv;
@@ -311,18 +308,65 @@ APR_DECLARE(apr_status_t) apr_file_gets(char *str, int len, apr_file_t *thefile)
return APR_SUCCESS;
}
- while (str < final) { /* leave room for trailing '\0' */
- nbytes = 1;
- rv = apr_file_read(thefile, str, &nbytes);
- if (rv != APR_SUCCESS) {
- break;
+ /* If we have an underlying buffer, we can be *much* more efficient
+ * and skip over the apr_file_read calls.
+ */
+ if (thefile->buffered) {
+
+#if APR_HAS_THREADS
+ if (thefile->thlock) {
+ apr_thread_mutex_lock(thefile->thlock);
+ }
+#endif
+
+ if (thefile->direction == 1) {
+ apr_file_flush(thefile);
+ thefile->direction = 0;
+ thefile->bufpos = 0;
+ thefile->dataRead = 0;
}
- if (*str == '\n') {
+
+ while (str < final) { /* leave room for trailing '\0' */
+ /* Force ungetc leftover to call apr_file_read. */
+ if (thefile->bufpos < thefile->dataRead &&
+ thefile->ungetchar == -1) {
+ *str = thefile->buffer[thefile->bufpos++];
+ }
+ else {
+ nbytes = 1;
+ rv = apr_file_read(thefile, str, &nbytes);
+ if (rv != APR_SUCCESS) {
+ break;
+ }
+ }
+ if (*str == '\n') {
+ ++str;
+ break;
+ }
+ ++str;
+ }
+
+#if APR_HAS_THREADS
+ if (thefile->thlock) {
+ apr_thread_mutex_unlock(thefile->thlock);
+ }
+#endif
+ }
+ else {
+ while (str < final) { /* leave room for trailing '\0' */
+ nbytes = 1;
+ rv = apr_file_read(thefile, str, &nbytes);
+ if (rv != APR_SUCCESS) {
+ break;
+ }
+ if (*str == '\n') {
+ ++str;
+ break;
+ }
++str;
- break;
}
- ++str;
}
+
/* We must store a terminating '\0' if we've stored any chars. We can
* get away with storing it if we hit an error first.
*/
diff --git a/file_io/win32/dir.c b/file_io/win32/dir.c
index ab2d08047..19fe15e8c 100644
--- a/file_io/win32/dir.c
+++ b/file_io/win32/dir.c
@@ -49,7 +49,7 @@ APR_DECLARE(apr_status_t) apr_dir_open(apr_dir_t **new, const char *dirname,
{
apr_status_t rv;
- int len = strlen(dirname);
+ apr_size_t len = strlen(dirname);
(*new) = apr_pcalloc(pool, sizeof(apr_dir_t));
/* Leave room here to add and pop the '*' wildcard for FindFirstFile
* and double-null terminate so we have one character to change.
@@ -243,7 +243,7 @@ APR_DECLARE(apr_status_t) apr_dir_read(apr_finfo_t *finfo, apr_int32_t wanted,
#else
char fspec[APR_PATH_MAX];
#endif
- int dirlen = strlen(thedir->dirname);
+ apr_size_t dirlen = strlen(thedir->dirname);
if (dirlen >= sizeof(fspec))
dirlen = sizeof(fspec) - 1;
apr_cpystrn(fspec, thedir->dirname, sizeof(fspec));
diff --git a/file_io/win32/filedup.c b/file_io/win32/filedup.c
index 57c57ea02..63aa25089 100644
--- a/file_io/win32/filedup.c
+++ b/file_io/win32/filedup.c
@@ -44,6 +44,13 @@ APR_DECLARE(apr_status_t) apr_file_dup(apr_file_t **new_file,
(*new_file)->buffered = FALSE;
(*new_file)->ungetchar = old_file->ungetchar;
+#if APR_HAS_THREADS
+ if (old_file->mutex) {
+ apr_thread_mutex_create(&((*new_file)->mutex),
+ APR_THREAD_MUTEX_DEFAULT, p);
+ }
+#endif
+
apr_pool_cleanup_register((*new_file)->pool, (void *)(*new_file), file_cleanup,
apr_pool_cleanup_null);
@@ -118,6 +125,13 @@ APR_DECLARE(apr_status_t) apr_file_dup2(apr_file_t *new_file,
new_file->buffered = FALSE;
new_file->ungetchar = old_file->ungetchar;
+#if APR_HAS_THREADS
+ if (old_file->mutex) {
+ apr_thread_mutex_create(&(new_file->mutex),
+ APR_THREAD_MUTEX_DEFAULT, p);
+ }
+#endif
+
return APR_SUCCESS;
#endif /* !defined(_WIN32_WCE) */
}
diff --git a/file_io/win32/open.c b/file_io/win32/open.c
index e937801f8..1b950fc21 100644
--- a/file_io/win32/open.c
+++ b/file_io/win32/open.c
@@ -47,7 +47,7 @@ apr_status_t utf8_to_unicode_path(apr_wchar_t* retstr, apr_size_t retlen,
* Note that the \\?\ form only works for local drive paths, and
* \\?\UNC\ is needed UNC paths.
*/
- int srcremains = strlen(srcstr) + 1;
+ apr_size_t srcremains = strlen(srcstr) + 1;
apr_wchar_t *t = retstr;
apr_status_t rv;
@@ -101,7 +101,7 @@ apr_status_t unicode_to_utf8_path(char* retstr, apr_size_t retlen,
* then transform \\'s back into /'s since the \\?\ form never
* allows '/' path seperators, and APR always uses '/'s.
*/
- int srcremains = wcslen(srcstr) + 1;
+ apr_size_t srcremains = wcslen(srcstr) + 1;
apr_status_t rv;
char *t = retstr;
if (srcstr[0] == L'\\' && srcstr[1] == L'\\' &&
@@ -324,6 +324,8 @@ APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new, const char *fname,
else {
return APR_EACCES;
}
+ if (flag & APR_READCONTROL)
+ oflags |= READ_CONTROL;
}
if (flag & APR_XTHREAD) {
diff --git a/file_io/win32/readwrite.c b/file_io/win32/readwrite.c
index b8a5e4be8..7a5931387 100644
--- a/file_io/win32/readwrite.c
+++ b/file_io/win32/readwrite.c
@@ -27,9 +27,10 @@
* read_with_timeout()
* Uses async i/o to emulate unix non-blocking i/o with timeouts.
*/
-static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t len, apr_size_t *nbytes)
+static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t len_in, apr_size_t *nbytes)
{
apr_status_t rv;
+ DWORD len = (DWORD)len_in;
*nbytes = 0;
/* Handle the zero timeout non-blocking case */
@@ -68,7 +69,8 @@ static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t le
file->pOverlapped->OffsetHigh = (DWORD)(file->filePtr >> 32);
}
- rv = ReadFile(file->filehand, buf, len, nbytes, file->pOverlapped);
+ *nbytes = 0;
+ rv = ReadFile(file->filehand, buf, len, (LPDWORD)nbytes, file->pOverlapped);
if (!rv) {
rv = apr_get_os_error();
@@ -85,7 +87,7 @@ static apr_status_t read_with_timeout(apr_file_t *file, void *buf, apr_size_t le
switch (rv) {
case WAIT_OBJECT_0:
GetOverlappedResult(file->filehand, file->pOverlapped,
- nbytes, TRUE);
+ (LPDWORD)nbytes, TRUE);
rv = APR_SUCCESS;
break;
case WAIT_TIMEOUT:
@@ -286,7 +288,7 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a
thefile->pOverlapped->Offset = (DWORD)thefile->filePtr;
thefile->pOverlapped->OffsetHigh = (DWORD)(thefile->filePtr >> 32);
}
- rv = WriteFile(thefile->filehand, buf, *nbytes, &bwrote,
+ rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
thefile->pOverlapped);
if (thefile->append) {
apr_file_unlock(thefile);
@@ -294,7 +296,7 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a
}
}
else {
- rv = WriteFile(thefile->filehand, buf, *nbytes, &bwrote,
+ rv = WriteFile(thefile->filehand, buf, (DWORD)*nbytes, &bwrote,
thefile->pOverlapped);
}
if (rv) {
@@ -309,7 +311,7 @@ APR_DECLARE(apr_status_t) apr_file_write(apr_file_t *thefile, const void *buf, a
rv = WaitForSingleObject(thefile->pOverlapped->hEvent, INFINITE);
switch (rv) {
case WAIT_OBJECT_0:
- GetOverlappedResult(thefile->filehand, thefile->pOverlapped, nbytes, TRUE);
+ GetOverlappedResult(thefile->filehand, thefile->pOverlapped, (LPDWORD)nbytes, TRUE);
rv = APR_SUCCESS;
break;
case WAIT_TIMEOUT:
@@ -343,7 +345,7 @@ APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile,
{
apr_status_t rv = APR_SUCCESS;
apr_size_t i;
- DWORD bwrote = 0;
+ apr_size_t bwrote = 0;
char *buf;
*nbytes = 0;
@@ -361,7 +363,7 @@ APR_DECLARE(apr_status_t) apr_file_writev(apr_file_t *thefile,
APR_DECLARE(apr_status_t) apr_file_putc(char ch, apr_file_t *thefile)
{
- DWORD len = 1;
+ apr_size_t len = 1;
return apr_file_write(thefile, &ch, &len);
}
@@ -375,7 +377,7 @@ APR_DECLARE(apr_status_t) apr_file_ungetc(char ch, apr_file_t *thefile)
APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile)
{
apr_status_t rc;
- int bread;
+ apr_size_t bread;
bread = 1;
rc = apr_file_read(thefile, ch, &bread);
@@ -393,7 +395,7 @@ APR_DECLARE(apr_status_t) apr_file_getc(char *ch, apr_file_t *thefile)
APR_DECLARE(apr_status_t) apr_file_puts(const char *str, apr_file_t *thefile)
{
- DWORD len = strlen(str);
+ apr_size_t len = strlen(str);
return apr_file_write(thefile, str, &len);
}
@@ -431,13 +433,34 @@ APR_DECLARE(apr_status_t) apr_file_gets(char *str, int len, apr_file_t *thefile)
APR_DECLARE(apr_status_t) apr_file_flush(apr_file_t *thefile)
{
if (thefile->buffered) {
- DWORD written = 0;
+ DWORD numbytes, written = 0;
apr_status_t rc = 0;
+ char *buffer;
+ apr_size_t bytesleft;
if (thefile->direction == 1 && thefile->bufpos) {
- if (!WriteFile(thefile->filehand, thefile->buffer, thefile->bufpos, &written, NULL))
- rc = apr_get_os_error();
- thefile->filePtr += written;
+ buffer = thefile->buffer;
+ bytesleft = thefile->bufpos;
+
+ do {
+ if (bytesleft > APR_DWORD_MAX) {
+ numbytes = APR_DWORD_MAX;
+ }
+ else {
+ numbytes = (DWORD)bytesleft;
+ }
+
+ if (!WriteFile(thefile->filehand, buffer, numbytes, &written, NULL)) {
+ rc = apr_get_os_error();
+ thefile->filePtr += written;
+ break;
+ }
+
+ thefile->filePtr += written;
+ bytesleft -= written;
+ buffer += written;
+
+ } while (bytesleft > 0);
if (rc == 0)
thefile->bufpos = 0;
diff --git a/include/apr.hw b/include/apr.hw
index 53ee01137..7797ed97d 100644
--- a/include/apr.hw
+++ b/include/apr.hw
@@ -363,7 +363,7 @@ typedef int gid_t;
#endif
#ifndef WS2TCPIP_INLINE
-6:09 PM 11/16/2003#define IN6_IS_ADDR_V4MAPPED(a) \
+#define IN6_IS_ADDR_V4MAPPED(a) \
( (*(const apr_uint64_t *)(const void *)(&(a)->s6_addr[0]) == 0) \
&& (*(const apr_uint32_t *)(const void *)(&(a)->s6_addr[8]) == ntohl(0x0000ffff)))
#endif
diff --git a/include/apr_network_io.h b/include/apr_network_io.h
index b160b3f7f..0157a46b6 100644
--- a/include/apr_network_io.h
+++ b/include/apr_network_io.h
@@ -456,7 +456,8 @@ APR_DECLARE(apr_status_t) apr_socket_data_set(apr_socket_t *sock, void *data,
* @remark
* <PRE>
* This functions acts like a blocking write by default. To change
- * this behavior, use apr_socket_timeout_set().
+ * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+ * socket option.
*
* It is possible for both bytes to be sent and an error to be returned.
*
@@ -475,7 +476,8 @@ APR_DECLARE(apr_status_t) apr_socket_send(apr_socket_t *sock, const char *buf,
* @remark
* <PRE>
* This functions acts like a blocking write by default. To change
- * this behavior, use apr_socket_timeout_set().
+ * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+ * socket option.
* The number of bytes actually sent is stored in argument 3.
*
* It is possible for both bytes to be sent and an error to be returned.
@@ -526,7 +528,8 @@ APR_DECLARE(apr_status_t) apr_socket_recvfrom(apr_sockaddr_t *from,
* including headers, file, and trailers
* @param flags APR flags that are mapped to OS specific flags
* @remark This functions acts like a blocking write by default. To change
- * this behavior, use apr_socket_timeout_set().
+ * this behavior, use apr_socket_timeout_set() or the
+ * APR_SO_NONBLOCK socket option.
* The number of bytes actually sent is stored in argument 5.
*/
APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock,
@@ -547,8 +550,9 @@ APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock,
* @remark
* <PRE>
* This functions acts like a blocking read by default. To change
- * this behavior, use apr_socket_timeout_set().
- * The number of bytes actually sent is stored in argument 3.
+ * this behavior, use apr_socket_timeout_set() or the APR_SO_NONBLOCK
+ * socket option.
+ * The number of bytes actually received is stored in argument 3.
*
* It is possible for both bytes to be received and an APR_EOF or
* other error to be returned.
@@ -568,6 +572,11 @@ APR_DECLARE(apr_status_t) apr_socket_recv(apr_socket_t *sock,
* APR_SO_KEEPALIVE -- keep connections active
* APR_SO_LINGER -- lingers on close if data is present
* APR_SO_NONBLOCK -- Turns blocking on/off for socket
+ * When this option is enabled, use
+ * the APR_STATUS_IS_EAGAIN() macro to
+ * see if a send or receive function
+ * could not transfer data without
+ * blocking.
* APR_SO_REUSEADDR -- The rules used in validating addresses
* supplied to bind should allow reuse
* of local addresses.
diff --git a/include/apr_shm.h b/include/apr_shm.h
index 64dbafe1b..88d184b0e 100644
--- a/include/apr_shm.h
+++ b/include/apr_shm.h
@@ -114,6 +114,7 @@ APR_DECLARE(apr_status_t) apr_shm_detach(apr_shm_t *m);
* processes will maintain the same address mapping.
* @param m The shared memory segment from which to retrieve
* the base address.
+ * @return address, aligned by APR_ALIGN_DEFAULT.
*/
APR_DECLARE(void *) apr_shm_baseaddr_get(const apr_shm_t *m);
diff --git a/include/apr_version.h b/include/apr_version.h
index af307b48f..08d5f3a26 100644
--- a/include/apr_version.h
+++ b/include/apr_version.h
@@ -60,8 +60,13 @@ extern "C" {
#define APR_MINOR_VERSION 0
/** patch level */
-#define APR_PATCH_VERSION 0
+#define APR_PATCH_VERSION 1
+/**
+ * This symbol is defined for internal, "development" copies of APR.
+ * This symbol should be #undef'd for releases.
+ */
+#define APR_IS_DEV_VERSION
/** The formatted string of APR's version */
#define APR_VERSION_STRING \
diff --git a/include/arch/apr_private_common.h b/include/arch/apr_private_common.h
index b2a02a8e4..912813b0d 100644
--- a/include/arch/apr_private_common.h
+++ b/include/arch/apr_private_common.h
@@ -33,4 +33,9 @@ apr_status_t apr_filepath_list_merge_impl(char **liststr,
char separator,
apr_pool_t *p);
+/* temporary defines to handle 64bit compile mismatches */
+#define APR_INT_TRUNC_CAST int
+#define APR_UINT32_TRUNC_CAST apr_uint32_t
+#define APR_UINT32_MAX 0xFFFFFFFFUL
+
#endif /*APR_PRIVATE_COMMON_H*/
diff --git a/include/arch/netware/apr_private.h b/include/arch/netware/apr_private.h
index 5251cb0e2..917b6fa45 100644
--- a/include/arch/netware/apr_private.h
+++ b/include/arch/netware/apr_private.h
@@ -63,6 +63,8 @@
#define HAVE_SETENV 1
#define HAVE_UNSETENV 1
+#define HAVE_WRITEV 1
+
/* 64-bit integer conversion function */
#define APR_INT64_STRFN strtoll
@@ -172,6 +174,9 @@ void* getStatCache();
#define APR_OFF_T_STRFN strtol
#endif
+/* used to check DWORD overflow for 64bit compiles */
+#define APR_DWORD_MAX 0xFFFFFFFFUL
+
/*
* Include common private declarations.
*/
diff --git a/include/arch/win32/apr_arch_threadproc.h b/include/arch/win32/apr_arch_threadproc.h
index 6e8ac8d54..f752fd7df 100644
--- a/include/arch/win32/apr_arch_threadproc.h
+++ b/include/arch/win32/apr_arch_threadproc.h
@@ -54,6 +54,8 @@ struct apr_procattr_t {
char *currdir;
apr_int32_t cmdtype;
apr_int32_t detached;
+ apr_child_errfn_t *errfn;
+ apr_int32_t errchk;
};
struct apr_thread_once_t {
diff --git a/include/arch/win32/apr_private.h b/include/arch/win32/apr_private.h
index de23360b3..0dee29348 100644
--- a/include/arch/win32/apr_private.h
+++ b/include/arch/win32/apr_private.h
@@ -158,6 +158,9 @@ APR_DECLARE_DATA int errno;
#define APR_OFF_T_STRFN strtoi
#endif
+/* used to check for DWORD overflow in 64bit compiles */
+#define APR_DWORD_MAX 0xFFFFFFFFUL
+
/*
* Include common private declarations.
*/
diff --git a/memory/unix/apr_pools.c b/memory/unix/apr_pools.c
index 2ed524eb3..9bf8fa290 100644
--- a/memory/unix/apr_pools.c
+++ b/memory/unix/apr_pools.c
@@ -139,9 +139,10 @@ APR_DECLARE(apr_pool_t *) apr_allocator_owner_get(apr_allocator_t *allocator)
}
APR_DECLARE(void) apr_allocator_max_free_set(apr_allocator_t *allocator,
- apr_size_t size)
+ apr_size_t in_size)
{
apr_uint32_t max_free_index;
+ apr_uint32_t size = (APR_UINT32_TRUNC_CAST)in_size;
#if APR_HAS_THREADS
apr_thread_mutex_t *mutex;
@@ -168,7 +169,8 @@ static APR_INLINE
apr_memnode_t *allocator_alloc(apr_allocator_t *allocator, apr_size_t size)
{
apr_memnode_t *node, **ref;
- apr_uint32_t i, index, max_index;
+ apr_uint32_t max_index;
+ apr_size_t i, index;
/* Round up the block size to the next boundary, but always
* allocate at least a certain size (MIN_ALLOC).
@@ -181,6 +183,10 @@ apr_memnode_t *allocator_alloc(apr_allocator_t *allocator, apr_size_t size)
* dividing its size by the boundary size
*/
index = (size >> BOUNDARY_INDEX) - 1;
+
+ if (index > APR_UINT32_MAX) {
+ return NULL;
+ }
/* First see if there are any nodes in the area we know
* our node will fit into.
@@ -293,7 +299,7 @@ apr_memnode_t *allocator_alloc(apr_allocator_t *allocator, apr_size_t size)
return NULL;
node->next = NULL;
- node->index = index;
+ node->index = (APR_UINT32_TRUNC_CAST)index;
node->first_avail = (char *)node + APR_MEMNODE_T_SIZE;
node->endp = (char *)node + size;
@@ -582,7 +588,7 @@ APR_DECLARE(void *) apr_palloc(apr_pool_t *pool, apr_size_t size)
{
apr_memnode_t *active, *node;
void *mem;
- apr_uint32_t free_index;
+ apr_size_t free_index;
size = APR_ALIGN_DEFAULT(size);
active = pool->active;
@@ -620,7 +626,7 @@ APR_DECLARE(void *) apr_palloc(apr_pool_t *pool, apr_size_t size)
free_index = (APR_ALIGN(active->endp - active->first_avail + 1,
BOUNDARY_SIZE) - BOUNDARY_SIZE) >> BOUNDARY_INDEX;
- active->free_index = free_index;
+ active->free_index = (APR_UINT32_TRUNC_CAST)free_index;
node = active->next;
if (free_index >= node->free_index)
return mem;
@@ -877,7 +883,7 @@ static int psprintf_flush(apr_vformatter_buff_t *vbuff)
apr_size_t cur_len, size;
char *strp;
apr_pool_t *pool;
- apr_uint32_t free_index;
+ apr_size_t free_index;
pool = ps->pool;
active = ps->node;
@@ -907,7 +913,7 @@ static int psprintf_flush(apr_vformatter_buff_t *vbuff)
free_index = (APR_ALIGN(active->endp - active->first_avail + 1,
BOUNDARY_SIZE) - BOUNDARY_SIZE) >> BOUNDARY_INDEX;
- active->free_index = free_index;
+ active->free_index = (APR_UINT32_TRUNC_CAST)free_index;
node = active->next;
if (free_index < node->free_index) {
do {
@@ -948,7 +954,7 @@ APR_DECLARE(char *) apr_pvsprintf(apr_pool_t *pool, const char *fmt, va_list ap)
char *strp;
apr_size_t size;
apr_memnode_t *active, *node;
- apr_uint32_t free_index;
+ apr_size_t free_index;
ps.node = active = pool->active;
ps.pool = pool;
@@ -1008,7 +1014,7 @@ APR_DECLARE(char *) apr_pvsprintf(apr_pool_t *pool, const char *fmt, va_list ap)
free_index = (APR_ALIGN(active->endp - active->first_avail + 1,
BOUNDARY_SIZE) - BOUNDARY_SIZE) >> BOUNDARY_INDEX;
- active->free_index = free_index;
+ active->free_index = (APR_UINT32_TRUNC_CAST)free_index;
node = active->next;
if (free_index >= node->free_index)
diff --git a/misc/unix/charset.c b/misc/unix/charset.c
index 5e1842fac..6acb4e157 100644
--- a/misc/unix/charset.c
+++ b/misc/unix/charset.c
@@ -55,7 +55,7 @@ APR_DECLARE(const char*) apr_os_default_encoding (apr_pool_t *pool)
}
if ('A' == 0x41) {
- return "ISO8859-1"; /* not necessarily true */
+ return "ISO-8859-1"; /* not necessarily true */
}
return "unknown";
diff --git a/misc/unix/errorcodes.c b/misc/unix/errorcodes.c
index 447b8d859..5c318d530 100644
--- a/misc/unix/errorcodes.c
+++ b/misc/unix/errorcodes.c
@@ -374,7 +374,13 @@ static char *native_strerror(apr_status_t statcode, char *buf,
sprintf(err, "Native Error #%d", statcode);
return stuffbuffer(buf, bufsize, err);
#else
- return stuffbuffer(buf, bufsize, strerror(statcode));
+ const char *err = strerror(statcode);
+ if (err) {
+ return stuffbuffer(buf, bufsize, err);
+ } else {
+ return stuffbuffer(buf, bufsize,
+ "APR does not understand this error code");
+ }
#endif
}
#endif
diff --git a/network_io/win32/sendrecv.c b/network_io/win32/sendrecv.c
index d7a68cd9c..11573fdad 100644
--- a/network_io/win32/sendrecv.c
+++ b/network_io/win32/sendrecv.c
@@ -43,7 +43,7 @@ APR_DECLARE(apr_status_t) apr_socket_send(apr_socket_t *sock, const char *buf,
int lasterror;
DWORD dwBytes = 0;
- wsaData.len = *len;
+ wsaData.len = (u_long)*len;
wsaData.buf = (char*) buf;
#ifndef _WIN32_WCE
@@ -72,7 +72,7 @@ APR_DECLARE(apr_status_t) apr_socket_recv(apr_socket_t *sock, char *buf,
DWORD dwBytes = 0;
DWORD flags = 0;
- wsaData.len = *len;
+ wsaData.len = (u_long)*len;
wsaData.buf = (char*) buf;
#ifndef _WIN32_WCE
@@ -94,21 +94,49 @@ APR_DECLARE(apr_status_t) apr_socket_recv(apr_socket_t *sock, char *buf,
APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock,
const struct iovec *vec,
- apr_int32_t nvec, apr_size_t *nbytes)
+ apr_int32_t in_vec, apr_size_t *nbytes)
{
apr_status_t rc = APR_SUCCESS;
apr_ssize_t rv;
- int i;
+ apr_size_t cur_len;
+ apr_int32_t nvec = 0;
+ int i, j = 0;
DWORD dwBytes = 0;
- WSABUF *pWsaBuf = (nvec <= WSABUF_ON_STACK) ? _alloca(sizeof(WSABUF) * (nvec))
- : malloc(sizeof(WSABUF) * (nvec));
+ WSABUF *pWsaBuf;
+
+ for (i = 0; i < in_vec; i++) {
+ cur_len = vec[i].iov_len;
+ nvec++;
+ while (cur_len > APR_DWORD_MAX) {
+ nvec++;
+ cur_len -= APR_DWORD_MAX;
+ }
+ }
+ pWsaBuf = (nvec <= WSABUF_ON_STACK) ? _alloca(sizeof(WSABUF) * (nvec))
+ : malloc(sizeof(WSABUF) * (nvec));
if (!pWsaBuf)
return APR_ENOMEM;
- for (i = 0; i < nvec; i++) {
- pWsaBuf[i].buf = vec[i].iov_base;
- pWsaBuf[i].len = vec[i].iov_len;
+ for (i = 0; i < in_vec; i++) {
+ char * base = vec[i].iov_base;
+ cur_len = vec[i].iov_len;
+
+ do {
+ if (cur_len > APR_DWORD_MAX) {
+ pWsaBuf[j].buf = base;
+ pWsaBuf[j].len = APR_DWORD_MAX;
+ cur_len -= APR_DWORD_MAX;
+ base += APR_DWORD_MAX;
+ }
+ else {
+ pWsaBuf[j].buf = base;
+ pWsaBuf[j].len = (DWORD)cur_len;
+ cur_len = 0;
+ }
+ j++;
+
+ } while (cur_len > 0);
}
#ifndef _WIN32_WCE
rv = WSASend(sock->socketdes, pWsaBuf, nvec, &dwBytes, 0, NULL, NULL);
@@ -140,7 +168,7 @@ APR_DECLARE(apr_status_t) apr_socket_sendto(apr_socket_t *sock,
{
apr_ssize_t rv;
- rv = sendto(sock->socketdes, buf, (*len), flags,
+ rv = sendto(sock->socketdes, buf, (int)*len, flags,
(const struct sockaddr*)&where->sa,
where->salen);
if (rv == SOCKET_ERROR) {
@@ -160,7 +188,7 @@ APR_DECLARE(apr_status_t) apr_socket_recvfrom(apr_sockaddr_t *from,
{
apr_ssize_t rv;
- rv = recvfrom(sock->socketdes, buf, (*len), flags,
+ rv = recvfrom(sock->socketdes, buf, (int)*len, flags,
(struct sockaddr*)&from->sa, &from->salen);
if (rv == SOCKET_ERROR) {
(*len) = 0;
@@ -225,13 +253,13 @@ APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock,
apr_int32_t flags)
{
apr_status_t status = APR_SUCCESS;
- apr_ssize_t rv;
+ apr_status_t rv;
apr_off_t curoff = *offset;
DWORD dwFlags = 0;
- DWORD nbytes;
+ apr_size_t nbytes;
TRANSMIT_FILE_BUFFERS tfb, *ptfb = NULL;
int ptr = 0;
- int bytes_to_send; /* Bytes to send out of the file (not including headers) */
+ apr_size_t bytes_to_send; /* Bytes to send out of the file (not including headers) */
int disconnected = 0;
int sendv_trailers = 0;
char hdtrbuf[4096];
@@ -267,11 +295,15 @@ APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock,
/* Collapse the headers into a single buffer */
if (hdtr && hdtr->numheaders) {
+ apr_size_t head_length = tfb.HeadLength;
ptfb = &tfb;
nbytes = 0;
- rv = collapse_iovec((char **)&ptfb->Head, &ptfb->HeadLength,
+ rv = collapse_iovec((char **)&ptfb->Head, &head_length,
hdtr->headers, hdtr->numheaders,
hdtrbuf, sizeof(hdtrbuf));
+
+ tfb.HeadLength = (DWORD)head_length;
+
/* If not enough buffer, punt to sendv */
if (rv == APR_INCOMPLETE) {
rv = apr_socket_sendv(sock, hdtr->headers, hdtr->numheaders, &nbytes);
@@ -289,19 +321,25 @@ APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock,
sock->overlapped->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
}
while (bytes_to_send) {
+ DWORD xmitbytes;
+
if (bytes_to_send > MAX_SEGMENT_SIZE) {
- nbytes = MAX_SEGMENT_SIZE;
+ xmitbytes = MAX_SEGMENT_SIZE;
}
else {
/* Last call to TransmitFile() */
- nbytes = bytes_to_send;
+ xmitbytes = (DWORD)bytes_to_send;
/* Collapse the trailers into a single buffer */
if (hdtr && hdtr->numtrailers) {
+ apr_size_t tail_length = tfb.TailLength;
ptfb = &tfb;
- rv = collapse_iovec((char**) &ptfb->Tail, &ptfb->TailLength,
+ rv = collapse_iovec((char**) &ptfb->Tail, &tail_length,
hdtr->trailers, hdtr->numtrailers,
hdtrbuf + ptfb->HeadLength,
sizeof(hdtrbuf) - ptfb->HeadLength);
+
+ tfb.TailLength = (DWORD)tail_length;
+
if (rv == APR_INCOMPLETE) {
/* If not enough buffer, punt to sendv, later */
sendv_trailers = 1;
@@ -323,7 +361,7 @@ APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock,
/* XXX BoundsChecker claims dwFlags must not be zero. */
rv = TransmitFile(sock->socketdes, /* socket */
file->filehand, /* open file descriptor of the file to be sent */
- nbytes, /* number of bytes to send. 0=send all */
+ xmitbytes, /* number of bytes to send. 0=send all */
0, /* Number of bytes per send. 0=use default */
sock->overlapped, /* OVERLAPPED structure */
ptfb, /* header and trailer buffers */
@@ -341,7 +379,7 @@ APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock,
if (!disconnected) {
if (!WSAGetOverlappedResult(sock->socketdes,
sock->overlapped,
- &nbytes,
+ &xmitbytes,
FALSE,
&dwFlags)) {
status = apr_get_netos_error();
@@ -351,7 +389,7 @@ APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock,
* tracks bytes sent out of the file.
*/
else if (ptfb) {
- nbytes -= (ptfb->HeadLength + ptfb->TailLength);
+ xmitbytes -= (ptfb->HeadLength + ptfb->TailLength);
}
}
}
@@ -374,9 +412,9 @@ APR_DECLARE(apr_status_t) apr_socket_sendfile(apr_socket_t *sock,
if (status != APR_SUCCESS)
break;
- bytes_to_send -= nbytes;
- curoff += nbytes;
- *len += nbytes;
+ bytes_to_send -= xmitbytes;
+ curoff += xmitbytes;
+ *len += xmitbytes;
/* Adjust len for any headers/trailers sent */
if (ptfb) {
*len += (ptfb->HeadLength + ptfb->TailLength);
diff --git a/poll/unix/poll.c b/poll/unix/poll.c
index a04866fcd..b03b086f3 100644
--- a/poll/unix/poll.c
+++ b/poll/unix/poll.c
@@ -50,7 +50,9 @@ static apr_int16_t get_kqueue_revent(apr_int16_t event, apr_int16_t flags)
rv |= APR_POLLIN;
if (event & EVFILT_WRITE)
rv |= APR_POLLOUT;
- if (flags & EV_ERROR || flags & EV_EOF)
+ if (flags & EV_EOF)
+ rv |= APR_POLLHUP;
+ if (flags & EV_ERROR)
rv |= APR_POLLERR;
return rv;
diff --git a/random/unix/apr_random.c b/random/unix/apr_random.c
index b4daeb2f5..49af49079 100644
--- a/random/unix/apr_random.c
+++ b/random/unix/apr_random.c
@@ -111,8 +111,8 @@ APR_DECLARE(void) apr_random_init(apr_random_t *g,apr_pool_t *p,
/2)*g->pool_hash->size*2;
g->reseed_size = APR_RANDOM_DEFAULT_RESEED_SIZE;
- g->H = apr_palloc(p,H_size(g));
- g->H_waiting = apr_palloc(p,H_size(g));
+ g->H = apr_pcalloc(p,H_size(g));
+ g->H_waiting = apr_pcalloc(p,H_size(g));
g->randomness = apr_palloc(p,B_size(g));
g->random_bytes = 0;
diff --git a/shmem/unix/shm.c b/shmem/unix/shm.c
index ec6e2b41f..db0dc5e79 100644
--- a/shmem/unix/shm.c
+++ b/shmem/unix/shm.c
@@ -385,20 +385,28 @@ APR_DECLARE(apr_status_t) apr_shm_remove(const char *filename,
* exist before calling ftok(). */
shmkey = ftok(filename, 1);
if (shmkey == (key_t)-1) {
- return errno;
+ goto shm_remove_failed;
}
+ apr_file_close(file);
+
if ((shmid = shmget(shmkey, 0, SHM_R | SHM_W)) < 0) {
- return errno;
+ goto shm_remove_failed;
}
/* Indicate that the segment is to be destroyed as soon
* as all processes have detached. This also disallows any
* new attachments to the segment. */
if (shmctl(shmid, IPC_RMID, NULL) == -1) {
- return errno;
+ goto shm_remove_failed;
}
return apr_file_remove(filename, pool);
+
+shm_remove_failed:
+ status = errno;
+ /* ensure the file has been removed anyway. */
+ apr_file_remove(filename, pool);
+ return status;
#endif
/* No support for anonymous shm */
diff --git a/tables/apr_hash.c b/tables/apr_hash.c
index 8b8a7f3d1..fba4ff162 100644
--- a/tables/apr_hash.c
+++ b/tables/apr_hash.c
@@ -73,6 +73,7 @@ struct apr_hash_t {
apr_hash_index_t iterator; /* For apr_hash_first(NULL, ...) */
unsigned int count, max;
apr_hashfunc_t hash_func;
+ apr_hash_entry_t *free; /* List of recycled entries */
};
#define INITIAL_MAX 15 /* tunable == 2^n - 1 */
@@ -92,6 +93,7 @@ APR_DECLARE(apr_hash_t *) apr_hash_make(apr_pool_t *pool)
apr_hash_t *ht;
ht = apr_palloc(pool, sizeof(apr_hash_t));
ht->pool = pool;
+ ht->free = NULL;
ht->count = 0;
ht->max = INITIAL_MAX;
ht->array = alloc_array(ht, ht->max);
@@ -264,7 +266,10 @@ static apr_hash_entry_t **find_entry(apr_hash_t *ht,
return hep;
/* add a new entry for non-NULL values */
- he = apr_palloc(ht->pool, sizeof(*he));
+ if ((he = ht->free) != NULL)
+ ht->free = he->next;
+ else
+ he = apr_palloc(ht->pool, sizeof(*he));
he->next = NULL;
he->hash = hash;
he->key = key;
@@ -286,6 +291,7 @@ APR_DECLARE(apr_hash_t *) apr_hash_copy(apr_pool_t *pool,
sizeof(*ht->array) * (orig->max + 1) +
sizeof(apr_hash_entry_t) * orig->count);
ht->pool = pool;
+ ht->free = NULL;
ht->count = orig->count;
ht->max = orig->max;
ht->hash_func = orig->hash_func;
@@ -333,7 +339,10 @@ APR_DECLARE(void) apr_hash_set(apr_hash_t *ht,
if (*hep) {
if (!val) {
/* delete entry */
+ apr_hash_entry_t *old = *hep;
*hep = (*hep)->next;
+ old->next = ht->free;
+ ht->free = old;
--ht->count;
}
else {
@@ -396,6 +405,7 @@ APR_DECLARE(apr_hash_t *) apr_hash_merge(apr_pool_t *p,
res = apr_palloc(p, sizeof(apr_hash_t));
res->pool = p;
+ res->free = NULL;
res->hash_func = base->hash_func;
res->count = base->count;
res->max = (overlay->max > base->max) ? overlay->max : base->max;
diff --git a/test/Makefile.in b/test/Makefile.in
index 1c0c324d1..545536102 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -29,7 +29,8 @@ TARGETS = $(PROGRAMS)
LOCAL_LIBS=../lib@APR_LIBNAME@.la
CLEAN_TARGETS = testfile.tmp mod_test.slo proc_child@EXEEXT@ occhild@EXEEXT@ \
-readchild@EXEEXT@ tryread@EXEEXT@ sockchid@EXEEXT@
+ readchild@EXEEXT@ tryread@EXEEXT@ sockchild@EXEEXT@ \
+ globalmutexchild@EXEEXT@ lfstests/large.bin
CLEAN_SUBDIRS = internal
INCDIR=../include
diff --git a/test/Makefile.win b/test/Makefile.win
index 2772edff1..7e5644e9b 100644
--- a/test/Makefile.win
+++ b/test/Makefile.win
@@ -6,7 +6,8 @@ PROGRAMS = \
sendfile.exe \
proc_child.exe \
tryread.exe \
- occhild.exe\
+ occhild.exe \
+ readchild.exe \
sockchild.exe \
testlockperf.exe \
testshmproducer.exe \
@@ -40,6 +41,9 @@ tryread.exe: tryread.obj $(LOCAL_LIBS)
occhild.exe: occhild.obj $(LOCAL_LIBS)
$(LINK) occhild.obj $(LOCAL_LIBS) $(ALL_LIBS)
+readchild.exe: readchild.obj $(LOCAL_LIBS)
+ $(LINK) readchild.obj $(LOCAL_LIBS) $(ALL_LIBS)
+
proc_child.exe: proc_child.obj $(LOCAL_LIBS)
$(LINK) /debug /subsystem:console /machine:I386 \
proc_child.obj $(LOCAL_LIBS) $(ALL_LIBS)
diff --git a/test/testrand2.c b/test/testrand2.c
index 2d2e8a625..8d5b7b07c 100644
--- a/test/testrand2.c
+++ b/test/testrand2.c
@@ -1,55 +1,16 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
+/* Copyright 2000-2004 The Apache Software Foundation
*
- * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
- * reserved.
+ * 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
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Apache" and "Apache Software Foundation" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * nor may "Apache" appear in their name, without prior written
- * permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
+ * 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_general.h"
diff --git a/test/teststr.c b/test/teststr.c
index 2121da41a..99aa8af41 100644
--- a/test/teststr.c
+++ b/test/teststr.c
@@ -150,6 +150,7 @@ static void snprintf_underflow(abts_case *tc, void *data)
static void string_error(abts_case *tc, void *data)
{
char buf[128], *rv;
+ apr_status_t n;
buf[0] = '\0';
rv = apr_strerror(APR_ENOENT, buf, sizeof buf);
@@ -159,6 +160,11 @@ static void string_error(abts_case *tc, void *data)
rv = apr_strerror(APR_TIMEUP, buf, sizeof buf);
ABTS_PTR_EQUAL(tc, buf, rv);
ABTS_STR_EQUAL(tc, "The timeout specified has expired", buf);
+
+ /* throw some randomish numbers at it to check for robustness */
+ for (n = 1; n < 1000000; n *= 2) {
+ apr_strerror(n, buf, sizeof buf);
+ }
}
#define SIZE 180000
diff --git a/threadproc/beos/.cvsignore b/threadproc/beos/.cvsignore
index 11f54a843..f82426797 100644
--- a/threadproc/beos/.cvsignore
+++ b/threadproc/beos/.cvsignore
@@ -1,5 +1,6 @@
Makefile
apr_proc_stub
*.lo
+*.slo
.libs
.deps
diff --git a/threadproc/win32/proc.c b/threadproc/win32/proc.c
index e7c21c105..191d682d4 100644
--- a/threadproc/win32/proc.c
+++ b/threadproc/win32/proc.c
@@ -245,14 +245,14 @@ static char *apr_caret_escape_args(apr_pool_t *p, const char *str)
APR_DECLARE(apr_status_t) apr_procattr_child_errfn_set(apr_procattr_t *attr,
apr_child_errfn_t *errfn)
{
- /* won't ever be called on this platform, so don't save the function pointer */
+ attr->errfn = errfn;
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_procattr_error_check_set(apr_procattr_t *attr,
apr_int32_t chk)
{
- /* won't ever be used on this platform, so don't save the flag */
+ attr->errchk = chk;
return APR_SUCCESS;
}
@@ -311,6 +311,12 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new,
char *fullpath = NULL;
if ((rv = apr_filepath_merge(&fullpath, attr->currdir, progname,
APR_FILEPATH_NATIVE, pool)) != APR_SUCCESS) {
+ if (attr->errfn) {
+ attr->errfn(pool, rv,
+ apr_pstrcat(pool, "filepath_merge failed.",
+ " currdir: ", attr->currdir,
+ " progname: ", progname, NULL));
+ }
return rv;
}
progname = fullpath;
@@ -352,6 +358,9 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new,
if (attr->cmdtype == APR_SHELLCMD || attr->cmdtype == APR_SHELLCMD_ENV) {
char *shellcmd = getenv("COMSPEC");
if (!shellcmd) {
+ if (attr->errfn) {
+ attr->errfn(pool, APR_EINVAL, "COMSPEC envar is not set");
+ }
return APR_EINVAL;
}
if (shellcmd[0] == '"') {
@@ -388,6 +397,9 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new,
{
char *shellcmd = getenv("COMSPEC");
if (!shellcmd) {
+ if (attr->errfn) {
+ attr->errfn(pool, APR_EINVAL, "COMSPEC envar is not set");
+ }
return APR_EINVAL;
}
if (shellcmd[0] == '"') {
@@ -479,6 +491,12 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new,
if ((rv = apr_conv_utf8_to_ucs2(env[i], &in,
pNext, &iEnvBlockLen))
!= APR_SUCCESS) {
+ if (attr->errfn) {
+ attr->errfn(pool, rv,
+ apr_pstrcat(pool,
+ "utf8 to ucs2 conversion failed"
+ " on this string: ", env[i], NULL));
+ }
return rv;
}
pNext = wcschr(pNext, L'\0') + 1;
@@ -525,6 +543,12 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new,
wprg = apr_palloc(pool, nwprg * sizeof(wprg[0]));
if ((rv = apr_conv_utf8_to_ucs2(progname, &nprg, wprg, &nwprg))
!= APR_SUCCESS) {
+ if (attr->errfn) {
+ attr->errfn(pool, rv,
+ apr_pstrcat(pool,
+ "utf8 to ucs2 conversion failed"
+ " on progname: ", progname, NULL));
+ }
return rv;
}
}
@@ -535,6 +559,12 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new,
wcmd = apr_palloc(pool, nwcmd * sizeof(wcmd[0]));
if ((rv = apr_conv_utf8_to_ucs2(cmdline, &ncmd, wcmd, &nwcmd))
!= APR_SUCCESS) {
+ if (attr->errfn) {
+ attr->errfn(pool, rv,
+ apr_pstrcat(pool,
+ "utf8 to ucs2 conversion failed"
+ " on cmdline: ", cmdline, NULL));
+ }
return rv;
}
}
@@ -547,6 +577,12 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new,
if ((rv = apr_conv_utf8_to_ucs2(attr->currdir, &ncwd,
wcwd, &nwcwd))
!= APR_SUCCESS) {
+ if (attr->errfn) {
+ attr->errfn(pool, rv,
+ apr_pstrcat(pool,
+ "utf8 to ucs2 conversion failed"
+ " on currdir: ", attr->currdir, NULL));
+ }
return rv;
}
}
diff --git a/threadproc/win32/thread.c b/threadproc/win32/thread.c
index 364d23274..95132cb4b 100644
--- a/threadproc/win32/thread.c
+++ b/threadproc/win32/thread.c
@@ -85,6 +85,7 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new,
{
apr_status_t stat;
unsigned temp;
+ HANDLE handle;
(*new) = (apr_thread_t *)apr_palloc(pool, sizeof(apr_thread_t));
@@ -95,7 +96,7 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new,
(*new)->pool = pool;
(*new)->data = data;
(*new)->func = func;
-
+ (*new)->td = NULL;
stat = apr_pool_create(&(*new)->pool, pool);
if (stat != APR_SUCCESS) {
return stat;
@@ -105,14 +106,14 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new,
* same size as the calling thread.
*/
#ifndef _WIN32_WCE
- if (((*new)->td = (HANDLE)_beginthreadex(NULL,
+ if ((handle = (HANDLE)_beginthreadex(NULL,
attr && attr->stacksize > 0 ? attr->stacksize : 0,
(unsigned int (APR_THREAD_FUNC *)(void *))dummy_worker,
(*new), 0, &temp)) == 0) {
return APR_FROM_OS_ERROR(_doserrno);
}
#else
- if (((*new)->td = CreateThread(NULL,
+ if ((handle = CreateThread(NULL,
attr && attr->stacksize > 0 ? attr->stacksize : 0,
(unsigned int (APR_THREAD_FUNC *)(void *))dummy_worker,
(*new), 0, &temp)) == 0) {
@@ -120,9 +121,10 @@ APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new,
}
#endif
if (attr && attr->detach) {
- CloseHandle((*new)->td);
- (*new)->td = NULL;
+ CloseHandle(handle);
}
+ else
+ (*new)->td = handle;
return APR_SUCCESS;
}
@@ -132,10 +134,8 @@ APR_DECLARE(apr_status_t) apr_thread_exit(apr_thread_t *thd,
{
thd->exitval = retval;
apr_pool_destroy(thd->pool);
+ thd->pool = NULL;
#ifndef _WIN32_WCE
- if (thd->td) {
- CloseHandle(thd->td);
- }
_endthreadex(0);
#else
ExitThread(0);
@@ -146,15 +146,26 @@ APR_DECLARE(apr_status_t) apr_thread_exit(apr_thread_t *thd,
APR_DECLARE(apr_status_t) apr_thread_join(apr_status_t *retval,
apr_thread_t *thd)
{
- apr_status_t rv;
-
+ apr_status_t rv = APR_SUCCESS;
+
+ if (!thd->td) {
+ /* Can not join on detached threads */
+ return APR_DETACH;
+ }
rv = WaitForSingleObject(thd->td, INFINITE);
if ( rv == WAIT_OBJECT_0 || rv == WAIT_ABANDONED) {
- *retval = thd->exitval;
- return APR_SUCCESS;
+ /* If the thread_exit has been called */
+ if (!thd->pool)
+ *retval = thd->exitval;
+ else
+ rv = APR_INCOMPLETE;
}
- /* Wait failed */
- return apr_get_os_error();;
+ else
+ rv = apr_get_os_error();
+ CloseHandle(thd->td);
+ thd->td = NULL;
+
+ return rv;
}
APR_DECLARE(apr_status_t) apr_thread_detach(apr_thread_t *thd)