Files
haikuports/dev-libs/apr/apr-1.0.1.diff
2008-07-30 16:49:08 +00:00

2870 lines
91 KiB
Diff
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
configure:
CFLAGS="-I/boot/home/develop/flock_server/src/headers -I/boot/home/config/include" CPPFLAGS="-I/boot/home/develop/flock_server/src/headers -I/boot/home/config/include" LDFLAGS="-L/boot/home/config/lib -lflock -liconv -no-undefined" ./configure --prefix=/boot/home/config --with-libtool
diff -urN apr-1.0.1.orig/build/apr_hints.m4 apr-1.0.1/build/apr_hints.m4
--- apr-1.0.1.orig/build/apr_hints.m4 2004-11-17 02:07:02.000000000 +0100
+++ apr-1.0.1/build/apr_hints.m4 2004-12-17 15:19:10.000000000 +0100
@@ -351,7 +351,6 @@
*beos*)
APR_ADDTO(CPPFLAGS, [-DBEOS])
PLATOSVERS=`uname -r`
- APR_SETIFNULL(apr_process_lock_is_global, [yes])
case $PLATOSVERS in
5.0.4)
APR_ADDTO(LDFLAGS, [-L/boot/beos/system/lib])
@@ -362,6 +361,9 @@
APR_ADDTO(LDFLAGS, [-L/boot/beos/system/lib])
APR_ADDTO(LIBS, [-lbind -lsocket])
;;
+ *)
+ APR_ADDTO(LDFLAGS,-lnet)
+ ;;
esac
APR_ADDTO(CPPFLAGS, [-DSIGPROCMASK_SETS_THREAD_MASK -DAP_AUTH_DBM_USE_APR])
;;
diff -urN apr-1.0.1.orig/configure.in apr-1.0.1/configure.in
--- apr-1.0.1.orig/configure.in 2004-11-17 02:07:02.000000000 +0100
+++ apr-1.0.1/configure.in 2004-12-17 15:19:10.000000000 +0100
@@ -221,7 +221,7 @@
dnl otherwise.
case $host in
- *os390)
+ *os390 | *beos)
if test "$ac_test_CFLAGS" != set; then
APR_REMOVEFROM(CFLAGS,-g)
fi
@@ -232,6 +232,10 @@
[APR_ADDTO(CFLAGS,-g)
if test "$GCC" = "yes"; then
APR_ADDTO(CFLAGS,-Wall)
+ if test "$host" = "i586-pc-beos"; then
+ APR_REMOVEFROM(CFLAGS, -O2)
+ APR_ADDTO(CFLAGS, -O0)
+ fi
elif test "$AIX_XLC" = "yes"; then
APR_ADDTO(CFLAGS,-qfullpath)
fi
@@ -384,10 +388,9 @@
APR_CHECK_DEFINE(BONE_VERSION, sys/socket.h)
eolstr="\\n"
osver=`uname -r`
- proc_mutex_is_global=1
OBJECTS_PLATFORM='$(OBJECTS_beos)'
case $osver in
- 5.0.4)
+ 5.0.4 | 5.1)
file_as_socket="1"
;;
*)
@@ -715,6 +718,7 @@
haveshmgetanon="0"
havemmapzero="0"
havemmapanon="0"
+havebeosarea="0"
APR_BEGIN_DECISION([anonymous shared memory allocation method])
APR_IFALLYES(header:sys/ipc.h header:sys/shm.h header:sys/file.h dnl
func:shmget func:shmat func:shmdt func:shmctl,
@@ -732,7 +736,7 @@
[haveos2shm="1"
APR_DECIDE(USE_SHMEM_OS2_ANON, [OS/2 DosAllocSharedMem()])])
APR_IFALLYES(header:kernel/OS.h func:create_area,
- [havebeosshm="1"
+ [havebeosarea="1"
APR_DECIDE(USE_SHMEM_BEOS_ANON,
[BeOS areas])])
case $host in
@@ -779,7 +783,6 @@
havemmaptmp="0"
havemmapshm="0"
haveshmget="0"
-havebeosarea="0"
haveos2shm="0"
APR_BEGIN_DECISION([namebased memory allocation method])
APR_IFALLYES(header:sys/mman.h func:mmap func:munmap,
@@ -796,7 +799,7 @@
[haveshmget="1"
APR_DECIDE(USE_SHMEM_SHMGET, [SysV IPC shmget()])])
APR_IFALLYES(header:kernel/OS.h func:create_area,
- [havebeosshm="1"
+ [havebeosarea="1"
APR_DECIDE(USE_SHMEM_BEOS, [BeOS areas])])
APR_IFALLYES(header:os2.h,
[haveos2shm="1"
@@ -1315,9 +1318,10 @@
size_t_fmt='#define APR_SIZE_T_FMT "ld"'
;;
*beos*)
- ssize_t_fmt='#define APR_SSIZE_T_FMT "ld"'
- size_t_fmt='#define APR_SIZE_T_FMT "ld"'
- ;;
+ pid_t_fmt='#define APR_PID_T_FMT "ld"'
+ ssize_t_fmt='#define APR_SSIZE_T_FMT "ld"'
+ size_t_fmt='#define APR_SIZE_T_FMT "ld"'
+ ;;
*apple-darwin*)
ssize_t_fmt='#define APR_SSIZE_T_FMT "d"'
size_t_fmt='#define APR_SIZE_T_FMT "lu"'
@@ -1399,6 +1403,10 @@
# Original HP-UX:
AC_CHECK_LIB(dld, shl_load, [dsotype=shl; APR_ADDTO(LIBS,-ldld)])
fi
+ if test "$dsotype" = "any"; then
+ # BeOS:
+ AC_CHECK_LIB(root, load_image, [dsotype=other])
+ fi
# Normal POSIX:
if test "$dsotype" = "any"; then
AC_CHECK_FUNC(dlopen, [dsotype=dlfcn])
@@ -1414,10 +1422,6 @@
[dsotype=any
echo "Weird: dlopen() was found but dlsym() was not found!"])])
fi
- if test "$dsotype" = "any"; then
- # BeOS:
- AC_CHECK_LIB(root, load_image, [dsotype=other])
- fi
# Everything else:
if test "$dsotype" = "any"; then
case $host in
@@ -1597,6 +1601,17 @@
fi
fi
+# BeOS has no built-in flock(), but there is a third-party flock_server package
+# that adds basic (if not compliant) support. It defines flock() in flock.h.
+case $host in
+ *beos)
+ unset ac_cv_define_LOCK_EX
+ APR_CHECK_DEFINE(LOCK_EX, flock.h)
+ APR_IFALLYES(func:flock define:LOCK_EX, [
+ APR_ADDTO(CFLAGS, -Dclose=flock_close -Ddup2=flock_dup2)])
+ ;;
+esac
+
# See which lock mechanisms we can support on this system.
APR_IFALLYES(header:semaphore.h func:sem_open func:sem_close dnl
func:sem_unlink func:sem_post func:sem_wait,
@@ -1610,7 +1625,16 @@
func:pthread_mutexattr_setpshared dnl
file:/dev/zero,
hasprocpthreadser="1", hasprocpthreadser="0")
-APR_IFALLYES(header:OS.h func:create_sem, hasbeossem="1", hasbeossem="0")
+APR_IFALLYES(header:OS.h func:create_sem, hasbeossemser="1", hasbeossemser="0")
+
+# BeOS defines F_SETLK, but that doesn't mean, that it really works.
+case $host in
+ *beos*)
+ hasfcntlser="0"
+ ;;
+ *)
+ ;;
+esac
# See which lock mechanism we'll select by default on this system.
# The last APR_DECIDE to execute sets the default.
@@ -1642,6 +1666,7 @@
posixser="0"
procpthreadser="0"
fcntlser="0"
+beossemser="0"
case $ac_decision in
USE_FLOCK_SERIALIZE )
flockser="1"
@@ -1659,7 +1684,7 @@
procpthreadser="1"
;;
USE_BEOSSEM )
- beossem="1"
+ beossemser="1"
;;
esac
@@ -1668,12 +1693,14 @@
AC_SUBST(hasposixser)
AC_SUBST(hasfcntlser)
AC_SUBST(hasprocpthreadser)
+AC_SUBST(hasbeossemser)
AC_SUBST(flockser)
AC_SUBST(sysvser)
AC_SUBST(posixser)
AC_SUBST(fcntlser)
AC_SUBST(procpthreadser)
AC_SUBST(pthreadser)
+AC_SUBST(beossemser)
AC_MSG_CHECKING(if all interprocess locks affect threads)
if test "x$apr_process_lock_is_global" = "xyes"; then
@@ -1983,6 +2010,9 @@
if test -d $srcdir/test; then
MAKEFILES="$MAKEFILES test/Makefile test/internal/Makefile"
fi
+if test -d $srcdir/threadproc/beos; then
+ MAKEFILES="$MAKEFILES threadproc/beos/Makefile"
+fi
#
# BSD/OS (BSDi) needs to use a different include syntax in the Makefiles
diff -urN apr-1.0.1.orig/dso/beos/dso.c apr-1.0.1/dso/beos/dso.c
--- apr-1.0.1.orig/dso/beos/dso.c 2004-03-09 15:40:41.000000000 +0100
+++ apr-1.0.1/dso/beos/dso.c 2004-12-17 15:19:10.000000000 +0100
@@ -22,7 +22,7 @@
{
apr_dso_handle_t *dso = thedso;
- if (dso->handle > 0 && unload_add_on(dso->handle) < B_NO_ERROR)
+ if (dso->handle >= 0 && unload_add_on(dso->handle) < B_NO_ERROR)
return APR_EINIT;
dso->handle = -1;
@@ -32,19 +32,16 @@
APR_DECLARE(apr_status_t) apr_dso_load(apr_dso_handle_t **res_handle,
const char *path, apr_pool_t *pool)
{
- image_id newid = -1;
+ apr_dso_handle_t *handle = apr_pcalloc(pool, sizeof(apr_dso_handle_t));
+ *res_handle = handle;
- *res_handle = apr_pcalloc(pool, sizeof(*res_handle));
-
- if((newid = load_add_on(path)) < B_NO_ERROR) {
- (*res_handle)->errormsg = strerror(newid);
+ handle->handle = load_add_on(path);
+ if (handle->handle < B_NO_ERROR)
return APR_EDSOOPEN;
- }
-
- (*res_handle)->pool = pool;
- (*res_handle)->handle = newid;
- apr_pool_cleanup_register(pool, *res_handle, dso_cleanup, apr_pool_cleanup_null);
+ handle->pool = pool;
+
+ apr_pool_cleanup_register(pool, handle, dso_cleanup, apr_pool_cleanup_null);
return APR_SUCCESS;
}
@@ -62,10 +59,9 @@
if (symname == NULL)
return APR_ESYMNOTFOUND;
- err = get_image_symbol(handle->handle, symname, B_SYMBOL_TYPE_ANY,
- ressym);
+ err = get_image_symbol(handle->handle, symname, B_SYMBOL_TYPE_ANY, ressym);
- if(err != B_OK)
+ if (err != B_OK)
return APR_ESYMNOTFOUND;
return APR_SUCCESS;
diff -urN apr-1.0.1.orig/file_io/unix/flock.c apr-1.0.1/file_io/unix/flock.c
--- apr-1.0.1.orig/file_io/unix/flock.c 2004-02-13 10:38:38.000000000 +0100
+++ apr-1.0.1/file_io/unix/flock.c 2004-12-17 15:19:10.000000000 +0100
@@ -22,11 +22,15 @@
#include <sys/file.h>
#endif
+#if defined(BEOS) && APR_HAS_FLOCK_SERIALIZE
+#include <flock.h>
+#endif
+
APR_DECLARE(apr_status_t) apr_file_lock(apr_file_t *thefile, int type)
{
int rc;
-#if defined(HAVE_FCNTL_H)
+#if APR_HAS_FCNTL_SERIALIZE
{
struct flock l = { 0 };
int fc;
@@ -56,7 +60,7 @@
return errno;
}
}
-#elif defined(HAVE_SYS_FILE_H)
+#elif APR_HAS_FLOCK_SERIALIZE
{
int ltype;
@@ -85,7 +89,7 @@
{
int rc;
-#if defined(HAVE_FCNTL_H)
+#if APR_HAS_FCNTL_SERIALIZE
{
struct flock l = { 0 };
@@ -102,7 +106,7 @@
if (rc == -1)
return errno;
}
-#elif defined(HAVE_SYS_FILE_H)
+#elif APR_HAS_FLOCK_SERIALIZE
{
/* keep trying if flock() gets interrupted (by a signal) */
while ((rc = flock(thefile->filedes, LOCK_UN)) < 0 && errno == EINTR)
diff -urN apr-1.0.1.orig/file_io/unix/pipe.c apr-1.0.1/file_io/unix/pipe.c
--- apr-1.0.1.orig/file_io/unix/pipe.c 2004-02-13 10:38:38.000000000 +0100
+++ apr-1.0.1/file_io/unix/pipe.c 2004-12-17 15:19:11.000000000 +0100
@@ -42,7 +42,7 @@
fd_flags &= ~O_NONBLOCK;
# elif defined(O_NDELAY)
fd_flags &= ~O_NDELAY;
-# elif defined(FNDELAY)
+# elif defined(O_FNDELAY)
fd_flags &= ~O_FNDELAY;
# else
/* XXXX: this breaks things, but an alternative isn't obvious...*/
@@ -77,7 +77,7 @@
fd_flags |= O_NONBLOCK;
# elif defined(O_NDELAY)
fd_flags |= O_NDELAY;
-# elif defined(FNDELAY)
+# elif defined(O_FNDELAY)
fd_flags |= O_FNDELAY;
# else
/* XXXX: this breaks things, but an alternative isn't obvious...*/
diff -urN apr-1.0.1.orig/include/apr.h.in apr-1.0.1/include/apr.h.in
--- apr-1.0.1.orig/include/apr.h.in 2004-06-05 13:52:43.000000000 +0200
+++ apr-1.0.1/include/apr.h.in 2004-12-17 15:19:10.000000000 +0100
@@ -172,12 +172,14 @@
#define APR_USE_FCNTL_SERIALIZE @fcntlser@
#define APR_USE_PROC_PTHREAD_SERIALIZE @procpthreadser@
#define APR_USE_PTHREAD_SERIALIZE @pthreadser@
+#define APR_USE_BEOS_SEM_SERIALIZE @beossemser@
#define APR_HAS_FLOCK_SERIALIZE @hasflockser@
#define APR_HAS_SYSVSEM_SERIALIZE @hassysvser@
#define APR_HAS_POSIXSEM_SERIALIZE @hasposixser@
#define APR_HAS_FCNTL_SERIALIZE @hasfcntlser@
#define APR_HAS_PROC_PTHREAD_SERIALIZE @hasprocpthreadser@
+#define APR_HAS_BEOS_SEM_SERIALIZE @hasbeossemser@
#define APR_PROCESS_LOCK_IS_GLOBAL @proclockglobal@
diff -urN apr-1.0.1.orig/include/apr_portable.h apr-1.0.1/include/apr_portable.h
--- apr-1.0.1.orig/include/apr_portable.h 2004-02-13 10:38:38.000000000 +0100
+++ apr-1.0.1/include/apr_portable.h 2004-12-17 15:19:10.000000000 +0100
@@ -87,9 +87,24 @@
#include <kernel/OS.h>
#include <kernel/image.h>
+/** Basic OS process mutex structure. */
struct apr_os_proc_mutex_t {
- sem_id sem;
- int32 ben;
+#if APR_HAS_SYSVSEM_SERIALIZE || APR_HAS_FCNTL_SERIALIZE || APR_HAS_FLOCK_SERIALIZE
+ /** Value used for SYS V Semaphore, FCNTL and FLOCK serialization */
+ int crossproc;
+#endif
+#if APR_HAS_PROC_PTHREAD_SERIALIZE
+ /** Value used for PTHREAD serialization */
+ pthread_mutex_t *pthread_interproc;
+#endif
+#if APR_HAS_THREADS
+ /* If no threads, no need for thread locks */
+#if APR_USE_PTHREAD_SERIALIZE
+ /** This value is currently unused within APR and Apache */
+ pthread_mutex_t *intraproc;
+#endif
+ sem_id beos_sem;
+#endif
};
typedef int apr_os_file_t;
@@ -98,7 +113,7 @@
typedef struct apr_os_proc_mutex_t apr_os_proc_mutex_t;
typedef thread_id apr_os_thread_t;
typedef thread_id apr_os_proc_t;
-typedef int apr_os_threadkey_t;
+typedef int32 apr_os_threadkey_t;
typedef struct timeval apr_os_imp_time_t;
typedef struct tm apr_os_exp_time_t;
typedef image_id apr_os_dso_handle_t;
--- apr-1.0.1.orig/include/arch/beos/apr_arch_proc_mutex.h 2004-02-13 10:38:38.000000000 +0100
+++ apr-1.0.1/include/arch/beos/apr_arch_proc_mutex.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,35 +0,0 @@
-/* Copyright 2000-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.
- */
-
-#ifndef PROC_MUTEX_H
-#define PROC_MUTEX_H
-
-#include "apr_pools.h"
-#include "apr_proc_mutex.h"
-#include "apr_file_io.h"
-#include "apr_general.h"
-#include "apr_lib.h"
-#include "apr_portable.h"
-
-struct apr_proc_mutex_t {
- apr_pool_t *pool;
-
- /* Our lock :) */
- sem_id Lock;
- int32 LockCount;
-};
-
-#endif /* PROC_MUTEX_H */
-
diff -urN apr-1.0.1.orig/include/arch/beos/apr_arch_shm.h apr-1.0.1/include/arch/beos/apr_arch_shm.h
--- apr-1.0.1.orig/include/arch/beos/apr_arch_shm.h 1970-01-01 01:00:00.000000000 +0100
+++ apr-1.0.1/include/arch/beos/apr_arch_shm.h 2004-12-17 15:19:11.000000000 +0100
@@ -0,0 +1,35 @@
+/* Copyright 2000-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.
+ */
+
+#ifndef SHM_H
+#define SHM_H
+
+#include <kernel/OS.h>
+#include "apr_pools.h"
+#include "apr_general.h"
+#include "apr_lib.h"
+#include "apr_portable.h"
+
+typedef struct beos_area_handle beos_area_handle;
+
+struct apr_shm_t {
+ apr_pool_t *pool;
+ beos_area_handle *handle;
+};
+
+apr_status_t apr_beos_setup_shmem();
+apr_status_t apr_beos_shmem_child_init();
+
+#endif /* SHM_H */
diff -urN apr-1.0.1.orig/include/arch/beos/apr_arch_thread_mutex.h apr-1.0.1/include/arch/beos/apr_arch_thread_mutex.h
--- apr-1.0.1.orig/include/arch/beos/apr_arch_thread_mutex.h 2004-02-13 10:38:38.000000000 +0100
+++ apr-1.0.1/include/arch/beos/apr_arch_thread_mutex.h 2004-12-17 15:19:11.000000000 +0100
@@ -37,5 +37,8 @@
int owner_ref;
};
+apr_status_t apr_beos_thread_mutex_init(apr_thread_mutex_t *mutex,
+ unsigned int flags, apr_pool_t *pool);
+
#endif /* THREAD_MUTEX_H */
diff -urN apr-1.0.1.orig/include/arch/beos/apr_arch_threadproc.h apr-1.0.1/include/arch/beos/apr_arch_threadproc.h
--- apr-1.0.1.orig/include/arch/beos/apr_arch_threadproc.h 2004-02-13 10:38:38.000000000 +0100
+++ apr-1.0.1/include/arch/beos/apr_arch_threadproc.h 2004-12-17 15:19:11.000000000 +0100
@@ -44,6 +44,7 @@
void *data;
apr_thread_start_t func;
apr_status_t exitval;
+ vint32 join_count;
};
struct apr_threadattr_t {
@@ -55,21 +56,8 @@
struct apr_threadkey_t {
apr_pool_t *pool;
- int32 key;
-};
-
-struct beos_private_data {
- const void ** data;
- int count;
- volatile thread_id td;
-};
-
-struct beos_key {
- int assigned;
- int count;
- sem_id lock;
- int32 ben_lock;
- void (* destructor) (void *);
+ int32 key;
+ void (*destructor)(void *);
};
struct apr_procattr_t {
@@ -87,7 +75,6 @@
struct apr_thread_once_t {
sem_id sem;
- int hit;
};
#endif /* ! THREAD_PROC_H */
diff -urN apr-1.0.1.orig/include/arch/unix/apr_arch_proc_mutex.h apr-1.0.1/include/arch/unix/apr_arch_proc_mutex.h
--- apr-1.0.1.orig/include/arch/unix/apr_arch_proc_mutex.h 2004-06-14 10:53:31.000000000 +0200
+++ apr-1.0.1/include/arch/unix/apr_arch_proc_mutex.h 2004-12-17 15:19:10.000000000 +0100
@@ -104,6 +104,9 @@
#if APR_HAS_PROC_PTHREAD_SERIALIZE
pthread_mutex_t *pthread_interproc;
#endif
+#if APR_HAS_BEOS_SEM_SERIALIZE
+ sem_id beos_sem;
+#endif
};
void apr_proc_mutex_unix_setup_lock(void);
diff -urN apr-1.0.1.orig/locks/beos/locks_common.c apr-1.0.1/locks/beos/locks_common.c
--- apr-1.0.1.orig/locks/beos/locks_common.c 1970-01-01 01:00:00.000000000 +0100
+++ apr-1.0.1/locks/beos/locks_common.c 2004-12-17 15:19:11.000000000 +0100
@@ -0,0 +1,5 @@
+/* Include "apr_arch_thread_mutex.h" first, so that "apr_arch_global_mutex.h"
+ * won't include the wrong one (the UNIX version).
+ */
+#include "apr_arch_thread_mutex.h"
+#include "../unix/global_mutex.c"
diff -urN apr-1.0.1.orig/locks/beos/proc_mutex.c apr-1.0.1/locks/beos/proc_mutex.c
--- apr-1.0.1.orig/locks/beos/proc_mutex.c 2004-03-09 15:39:45.000000000 +0100
+++ apr-1.0.1/locks/beos/proc_mutex.c 2004-12-17 15:19:11.000000000 +0100
@@ -13,157 +13,68 @@
* limitations under the License.
*/
-/*Read/Write locking implementation based on the MultiLock code from
- * Stephen Beaulieu <hippo@be.com>
- */
-
#include "apr_arch_proc_mutex.h"
#include "apr_strings.h"
#include "apr_portable.h"
+#if APR_HAS_FLOCK_SERIALIZE
+#include <flock.h>
+#endif
-static apr_status_t _proc_mutex_cleanup(void * data)
-{
- apr_proc_mutex_t *lock = (apr_proc_mutex_t*)data;
- if (lock->LockCount != 0) {
- /* we're still locked... */
- while (atomic_add(&lock->LockCount , -1) > 1){
- /* OK we had more than one person waiting on the lock so
- * the sem is also locked. Release it until we have no more
- * locks left.
- */
- release_sem (lock->Lock);
- }
- }
- delete_sem(lock->Lock);
- return APR_SUCCESS;
-}
-
-APR_DECLARE(apr_status_t) apr_proc_mutex_create(apr_proc_mutex_t **mutex,
- const char *fname,
- apr_lockmech_e mech,
- apr_pool_t *pool)
-{
- apr_proc_mutex_t *new;
- apr_status_t stat = APR_SUCCESS;
-
- if (mech != APR_LOCK_DEFAULT) {
- return APR_ENOTIMPL;
- }
-
- new = (apr_proc_mutex_t *)apr_pcalloc(pool, sizeof(apr_proc_mutex_t));
- if (new == NULL){
- return APR_ENOMEM;
- }
-
- if ((stat = create_sem(0, "APR_Lock")) < B_NO_ERROR) {
- _proc_mutex_cleanup(new);
- return stat;
- }
- new->LockCount = 0;
- new->Lock = stat;
- new->pool = pool;
-
- apr_pool_cleanup_register(new->pool, (void *)new, _proc_mutex_cleanup,
- apr_pool_cleanup_null);
-
- (*mutex) = new;
- return APR_SUCCESS;
-}
+#include <OS.h>
-APR_DECLARE(apr_status_t) apr_proc_mutex_child_init(apr_proc_mutex_t **mutex,
- const char *fname,
- apr_pool_t *pool)
+static apr_status_t proc_mutex_beos_sem_cleanup(void *mutex_)
{
- return APR_SUCCESS;
-}
+ apr_proc_mutex_t *mutex = mutex_;
-APR_DECLARE(apr_status_t) apr_proc_mutex_lock(apr_proc_mutex_t *mutex)
-{
- int32 stat;
-
- if (atomic_add(&mutex->LockCount, 1) > 0) {
- if ((stat = acquire_sem(mutex->Lock)) < B_NO_ERROR) {
- atomic_add(&mutex->LockCount, -1);
- return stat;
- }
- }
- return APR_SUCCESS;
-}
-
-APR_DECLARE(apr_status_t) apr_proc_mutex_trylock(apr_proc_mutex_t *mutex)
-{
- return APR_ENOTIMPL;
-}
+ return delete_sem(mutex->beos_sem);
+}
-APR_DECLARE(apr_status_t) apr_proc_mutex_unlock(apr_proc_mutex_t *mutex)
+static apr_status_t proc_mutex_beos_sem_create(apr_proc_mutex_t *new_mutex,
+ const char *fname)
{
- int32 stat;
-
- if (atomic_add(&mutex->LockCount, -1) > 1) {
- if ((stat = release_sem(mutex->Lock)) < B_NO_ERROR) {
- atomic_add(&mutex->LockCount, 1);
- return stat;
- }
- }
- return APR_SUCCESS;
-}
+ new_mutex->beos_sem = create_sem(1, "APR_ProcMutex");
+ if (new_mutex->beos_sem < B_NO_ERROR)
+ return new_mutex->beos_sem;
-APR_DECLARE(apr_status_t) apr_proc_mutex_destroy(apr_proc_mutex_t *mutex)
-{
- apr_status_t stat;
- if ((stat = _proc_mutex_cleanup(mutex)) == APR_SUCCESS) {
- apr_pool_cleanup_kill(mutex->pool, mutex, _proc_mutex_cleanup);
- return APR_SUCCESS;
- }
- return stat;
-}
+ apr_pool_cleanup_register(new_mutex->pool, (void *)new_mutex,
+ apr_proc_mutex_cleanup,
+ apr_pool_cleanup_null);
-APR_DECLARE(apr_status_t) apr_proc_mutex_cleanup(void *mutex)
-{
- return _proc_mutex_cleanup(mutex);
+ return APR_SUCCESS;
}
-
-APR_DECLARE(const char *) apr_proc_mutex_lockfile(apr_proc_mutex_t *mutex)
+static apr_status_t proc_mutex_beos_sem_acquire(apr_proc_mutex_t *mutex)
{
- return NULL;
+ return acquire_sem(mutex->beos_sem);
}
-APR_DECLARE(const char *) apr_proc_mutex_name(apr_proc_mutex_t *mutex)
+static apr_status_t proc_mutex_beos_sem_tryacquire(apr_proc_mutex_t *mutex)
{
- return "beossem";
+ return acquire_sem_etc(mutex->beos_sem, 0, B_RELATIVE_TIMEOUT, 0);
}
-APR_DECLARE(const char *) apr_proc_mutex_defname(void)
+static apr_status_t proc_mutex_beos_sem_release(apr_proc_mutex_t *mutex)
{
- return "beossem";
+ return release_sem(mutex->beos_sem);
}
-APR_POOL_IMPLEMENT_ACCESSOR(proc_mutex)
-
-/* Implement OS-specific accessors defined in apr_portable.h */
-
-APR_DECLARE(apr_status_t) apr_os_proc_mutex_get(apr_os_proc_mutex_t *ospmutex,
- apr_proc_mutex_t *pmutex)
+static apr_status_t proc_mutex_beos_sem_child_init(apr_proc_mutex_t **mutex,
+ apr_pool_t *cont,
+ const char *fname)
{
- ospmutex->sem = pmutex->Lock;
- ospmutex->ben = pmutex->LockCount;
return APR_SUCCESS;
}
-APR_DECLARE(apr_status_t) apr_os_proc_mutex_put(apr_proc_mutex_t **pmutex,
- apr_os_proc_mutex_t *ospmutex,
- apr_pool_t *pool)
-{
- if (pool == NULL) {
- return APR_ENOPOOL;
- }
- if ((*pmutex) == NULL) {
- (*pmutex) = (apr_proc_mutex_t *)apr_pcalloc(pool, sizeof(apr_proc_mutex_t));
- (*pmutex)->pool = pool;
- }
- (*pmutex)->Lock = ospmutex->sem;
- (*pmutex)->LockCount = ospmutex->ben;
- return APR_SUCCESS;
-}
+static const apr_proc_mutex_unix_lock_methods_t mutex_beos_sem_methods =
+{
+ APR_PROCESS_LOCK_MECH_IS_GLOBAL,
+ proc_mutex_beos_sem_create,
+ proc_mutex_beos_sem_acquire,
+ proc_mutex_beos_sem_tryacquire,
+ proc_mutex_beos_sem_release,
+ proc_mutex_beos_sem_cleanup,
+ proc_mutex_beos_sem_child_init,
+ "beossem"
+};
+#include "../unix/proc_mutex.c"
diff -urN apr-1.0.1.orig/locks/beos/thread_cond.c apr-1.0.1/locks/beos/thread_cond.c
--- apr-1.0.1.orig/locks/beos/thread_cond.c 2004-02-26 18:03:26.000000000 +0100
+++ apr-1.0.1/locks/beos/thread_cond.c 2004-12-17 15:19:11.000000000 +0100
@@ -20,7 +20,6 @@
static apr_status_t thread_cond_cleanup(void *data)
{
- struct waiter *w;
apr_thread_cond_t *cond = (apr_thread_cond_t *)data;
acquire_sem(cond->lock);
diff -urN apr-1.0.1.orig/locks/beos/thread_mutex.c apr-1.0.1/locks/beos/thread_mutex.c
--- apr-1.0.1.orig/locks/beos/thread_mutex.c 2004-02-26 18:03:26.000000000 +0100
+++ apr-1.0.1/locks/beos/thread_mutex.c 2004-12-17 15:19:11.000000000 +0100
@@ -26,18 +26,37 @@
apr_thread_mutex_t *lock = (apr_thread_mutex_t*)data;
if (lock->LockCount != 0) {
/* we're still locked... */
- while (atomic_add(&lock->LockCount , -1) > 1){
- /* OK we had more than one person waiting on the lock so
- * the sem is also locked. Release it until we have no more
- * locks left.
- */
+ while (atomic_add(&lock->LockCount , -1) > 1){
+ /* OK we had more than one person waiting on the lock so
+ * the sem is also locked. Release it until we have no more
+ * locks left.
+ */
release_sem (lock->Lock);
- }
+ }
}
delete_sem(lock->Lock);
return APR_SUCCESS;
}
+/* pool may be NULL. */
+apr_status_t apr_beos_thread_mutex_init(apr_thread_mutex_t *mutex,
+ unsigned int flags, apr_pool_t *pool)
+{
+ mutex->Lock = create_sem(0, "APR_Lock");
+ if (mutex->Lock < 0)
+ return mutex->Lock;
+
+ mutex->LockCount = 0;
+ mutex->pool = pool;
+
+ /* Optimal default is APR_THREAD_MUTEX_UNNESTED,
+ * no additional checks required for either flag.
+ */
+ mutex->nested = flags & APR_THREAD_MUTEX_NESTED;
+
+ return APR_SUCCESS;
+}
+
APR_DECLARE(apr_status_t) apr_thread_mutex_create(apr_thread_mutex_t **mutex,
unsigned int flags,
apr_pool_t *pool)
@@ -49,19 +68,10 @@
if (new_m == NULL){
return APR_ENOMEM;
}
-
- if ((stat = create_sem(0, "APR_Lock")) < B_NO_ERROR) {
- _thread_mutex_cleanup(new_m);
- return stat;
- }
- new_m->LockCount = 0;
- new_m->Lock = stat;
- new_m->pool = pool;
- /* Optimal default is APR_THREAD_MUTEX_UNNESTED,
- * no additional checks required for either flag.
- */
- new_m->nested = flags & APR_THREAD_MUTEX_NESTED;
+ stat = apr_beos_thread_mutex_init(new_m, flags, pool);
+ if (stat != APR_SUCCESS)
+ return stat;
apr_pool_cleanup_register(new_m->pool, (void *)new_m, _thread_mutex_cleanup,
apr_pool_cleanup_null);
@@ -90,13 +100,13 @@
return APR_SUCCESS;
}
- if (atomic_add(&mutex->LockCount, 1) > 0) {
- if ((stat = acquire_sem(mutex->Lock)) < B_NO_ERROR) {
+ if (atomic_add(&mutex->LockCount, 1) > 0) {
+ if ((stat = acquire_sem(mutex->Lock)) < B_NO_ERROR) {
/* Oh dear, acquire_sem failed!! */
- atomic_add(&mutex->LockCount, -1);
- return stat;
- }
- }
+ atomic_add(&mutex->LockCount, -1);
+ return stat;
+ }
+ }
mutex->owner = me;
mutex->owner_ref = 1;
@@ -119,7 +129,7 @@
return APR_SUCCESS;
}
- if (atomic_add(&mutex->LockCount, -1) > 1) {
+ if (atomic_add(&mutex->LockCount, -1) > 1) {
if ((stat = release_sem(mutex->Lock)) < B_NO_ERROR) {
atomic_add(&mutex->LockCount, 1);
return stat;
diff -urN apr-1.0.1.orig/locks/unix/proc_mutex.c apr-1.0.1/locks/unix/proc_mutex.c
--- apr-1.0.1.orig/locks/unix/proc_mutex.c 2004-06-15 10:21:22.000000000 +0200
+++ apr-1.0.1/locks/unix/proc_mutex.c 2004-12-17 15:19:11.000000000 +0100
@@ -717,6 +717,8 @@
new_mutex->inter_meth = &mutex_proc_pthread_methods;
#elif APR_USE_POSIXSEM_SERIALIZE
new_mutex->inter_meth = &mutex_posixsem_methods;
+#elif APR_USE_BEOS_SEM_SERIALIZE
+ new_mutex->inter_meth = &mutex_beos_sem_methods;
#else
return APR_ENOTIMPL;
#endif
@@ -837,6 +839,9 @@
#if APR_HAS_PROC_PTHREAD_SERIALIZE
ospmutex->pthread_interproc = pmutex->pthread_interproc;
#endif
+#if APR_HAS_BEOS_SEM_SERIALIZE
+ ospmutex->beos_sem = pmutex->beos_sem;
+#endif
return APR_SUCCESS;
}
@@ -858,6 +863,9 @@
#if APR_HAS_PROC_PTHREAD_SERIALIZE
(*pmutex)->pthread_interproc = ospmutex->pthread_interproc;
#endif
+#if APR_HAS_BEOS_SEM_SERIALIZE
+ (*pmutex)->beos_sem = ospmutex->beos_sem;
+#endif
return APR_SUCCESS;
}
diff -urN apr-1.0.1.orig/misc/unix/start.c apr-1.0.1/misc/unix/start.c
--- apr-1.0.1.orig/misc/unix/start.c 2004-02-13 10:38:38.000000000 +0100
+++ apr-1.0.1/misc/unix/start.c 2004-12-17 15:19:11.000000000 +0100
@@ -22,6 +22,10 @@
#include "apr_arch_proc_mutex.h" /* for apr_proc_mutex_unix_setup_lock() */
#include "apr_arch_internal_time.h"
+#ifdef BEOS
+#include "apr_arch_shm.h" /* for apr_beos_setup_shmem() */
+#endif
+
APR_DECLARE(apr_status_t) apr_app_initialize(int *argc,
const char * const * *argv,
@@ -51,6 +55,10 @@
apr_unix_setup_time();
#endif
+#ifdef BEOS
+ apr_beos_setup_shmem();
+#endif
+
if ((status = apr_pool_initialize()) != APR_SUCCESS)
return status;
--- apr-1.0.1.orig/network_io/beos/sendrecv.c 2004-02-13 10:38:38.000000000 +0100
+++ apr-1.0.1/network_io/beos/sendrecv.c 2004-12-17 15:25:26.000000000 +0100
@@ -17,9 +17,14 @@
#if BEOS_BONE /* BONE uses the unix code - woohoo */
#include "../unix/sendrecv.c"
#else
+#include <OS.h>
+
#include "apr_arch_networkio.h"
#include "apr_time.h"
+#define SEND_WAIT APR_USEC_PER_SEC / 100
+#define RECEIVE_WAIT APR_USEC_PER_SEC / 100
+
static apr_status_t wait_for_io_or_timeout(apr_socket_t *sock, int for_read)
{
struct timeval tv, *tvptr;
@@ -37,6 +42,8 @@
tv.tv_usec = sock->timeout % APR_USEC_PER_SEC;
tvptr = &tv;
}
+ /* This probably only works for read_for. At least according to the
+ * documentation only the read set argument is actually supported. */
srv = select(sock->socketdes + 1,
for_read ? &fdset : NULL,
for_read ? NULL : &fdset,
@@ -54,38 +61,46 @@
return APR_SUCCESS;
}
-#define SEND_WAIT APR_USEC_PER_SEC / 10
+apr_status_t apr_wait_for_io_or_timeout(apr_file_t *f, apr_socket_t *s,
+ int for_read)
+{
+ /* BeOS net_server select() supports sockets only */
+ if (!f)
+ return APR_ENOTIMPL;
+
+ return wait_for_io_or_timeout(s, for_read);
+}
APR_DECLARE(apr_status_t) apr_socket_send(apr_socket_t *sock, const char *buf,
apr_size_t *len)
{
apr_ssize_t rv;
-
+
do {
rv = send(sock->socketdes, buf, (*len), 0);
} while (rv == -1 && errno == EINTR);
if (rv == -1 && errno == EWOULDBLOCK && sock->timeout > 0) {
- apr_int32_t snooze_val = SEND_WAIT;
- apr_int32_t zzz = 0;
-
- do {
- rv = send(sock->socketdes, buf, (*len), 0);
- if (rv == -1 && errno == EWOULDBLOCK){
- apr_sleep (snooze_val);
- zzz += snooze_val;
- snooze_val += SEND_WAIT;
- /* have we passed our timeout value */
- if (zzz > (sock->timeout * APR_USEC_PER_SEC))
- break;
- }
- } while (rv == -1 && (errno == EINTR || errno == EWOULDBLOCK));
+ bigtime_t now = system_time();
+ bigtime_t endTime = now + sock->timeout;
+ while (now < endTime) {
+ snooze(RECEIVE_WAIT);
+
+ do {
+ rv = send(sock->socketdes, buf, (*len), 0);
+ } while (rv == -1 && errno == EINTR);
+
+ if (rv >= 0 || (rv < 0 && errno != EWOULDBLOCK))
+ break;
+
+ now = system_time();
+ };
}
if (rv == -1) {
*len = 0;
- return errno;
+ return (errno == EWOULDBLOCK ? APR_TIMEUP : errno);
}
- (*len) = rv;
+ *len = rv;
return APR_SUCCESS;
}
@@ -100,22 +115,30 @@
} while (rv == -1 && errno == EINTR);
if (rv == -1 && errno == EWOULDBLOCK && sock->timeout > 0) {
- apr_status_t arv = wait_for_io_or_timeout(sock, 1);
- if (arv != APR_SUCCESS) {
- *len = 0;
- return arv;
- }
- else {
+ /* bonefish: I don't know why, but in some cases select() seems to
+ * return success, even if there's nothing to read yet. Maybe if the
+ * connection is not yet established? The tests exposed this problem.
+ * Long story short, we have to poll here, too. */
+ bigtime_t now = system_time();
+ bigtime_t endTime = now + sock->timeout;
+ while (now < endTime) {
+ snooze(RECEIVE_WAIT);
+
do {
rv = recv(sock->socketdes, buf, (*len), 0);
} while (rv == -1 && errno == EINTR);
- }
+
+ if (rv >= 0 || (rv < 0 && errno != EWOULDBLOCK))
+ break;
+
+ now = system_time();
+ };
}
if (rv == -1) {
(*len) = 0;
- return errno;
+ return (errno == EWOULDBLOCK ? APR_TIMEUP : errno);
}
- (*len) = rv;
+ *len = rv;
if (rv == 0)
return APR_EOF;
return APR_SUCCESS;
@@ -144,23 +167,28 @@
where->salen);
} while (rv == -1 && errno == EINTR);
- if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)
- && sock->timeout != 0) {
- apr_status_t arv = wait_for_io_or_timeout(sock, 0);
- if (arv != APR_SUCCESS) {
- *len = 0;
- return arv;
- } else {
+
+ if (rv == -1 && errno == EWOULDBLOCK && sock->timeout > 0) {
+ bigtime_t now = system_time();
+ bigtime_t endTime = now + sock->timeout;
+ while (now < endTime) {
+ snooze(RECEIVE_WAIT);
+
do {
rv = sendto(sock->socketdes, buf, (*len), flags,
(const struct sockaddr*)&where->sa,
where->salen);
} while (rv == -1 && errno == EINTR);
- }
+
+ if (rv >= 0 || (rv < 0 && errno != EWOULDBLOCK))
+ break;
+
+ now = system_time();
+ };
}
if (rv == -1) {
*len = 0;
- return errno;
+ return (errno == EWOULDBLOCK ? APR_TIMEUP : errno);
}
*len = rv;
return APR_SUCCESS;
@@ -173,38 +201,38 @@
{
apr_ssize_t rv;
- if (from == NULL){
- return APR_ENOMEM;
- /* Not sure if this is correct. Maybe we should just allocate
- the memory??
- */
- }
-
do {
rv = recvfrom(sock->socketdes, buf, (*len), flags,
(struct sockaddr*)&from->sa, &from->salen);
} while (rv == -1 && errno == EINTR);
- if (rv == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
- sock->timeout != 0) {
- apr_status_t arv = wait_for_io_or_timeout(sock, 1);
- if (arv != APR_SUCCESS) {
- *len = 0;
- return arv;
- } else {
+ if (rv == -1 && errno == EWOULDBLOCK && sock->timeout > 0) {
+ /* bonefish: I don't know why, but in some cases select() seems to
+ * return success, even if there's nothing to read yet. Maybe if the
+ * connection is not yet established? The tests exposed this problem.
+ * Long story short, we have to poll here, too. */
+ bigtime_t now = system_time();
+ bigtime_t endTime = now + sock->timeout;
+ while (now < endTime) {
+ snooze(RECEIVE_WAIT);
+
do {
rv = recvfrom(sock->socketdes, buf, (*len), flags,
(struct sockaddr*)&from->sa, &from->salen);
- } while (rv == -1 && errno == EINTR);
- }
+ } while (rv == -1 && errno == EINTR);
+
+ if (rv >= 0 || (rv < 0 && errno != EWOULDBLOCK))
+ break;
+
+ now = system_time();
+ };
}
if (rv == -1) {
(*len) = 0;
- return errno;
+ return (errno == EWOULDBLOCK ? APR_TIMEUP : errno);
}
-
- (*len) = rv;
- if (rv == 0)
+ *len = rv;
+ if (rv == 0 && sock->type == SOCK_STREAM)
return APR_EOF;
return APR_SUCCESS;
diff -urN apr-1.0.1.orig/network_io/unix/sockaddr.c apr-1.0.1/network_io/unix/sockaddr.c
--- apr-1.0.1.orig/network_io/unix/sockaddr.c 2004-07-13 11:15:50.000000000 +0200
+++ apr-1.0.1/network_io/unix/sockaddr.c 2004-12-17 15:19:11.000000000 +0100
@@ -543,7 +543,7 @@
if ((masked = flags & (APR_IPV4_ADDR_OK | APR_IPV6_ADDR_OK))) {
if (!hostname ||
- family != AF_UNSPEC ||
+ family != APR_UNSPEC ||
masked == (APR_IPV4_ADDR_OK | APR_IPV6_ADDR_OK)) {
return APR_EINVAL;
}
diff -urN apr-1.0.1.orig/network_io/unix/sockets.c apr-1.0.1/network_io/unix/sockets.c
--- apr-1.0.1.orig/network_io/unix/sockets.c 2004-03-10 21:58:34.000000000 +0100
+++ apr-1.0.1/network_io/unix/sockets.c 2004-12-17 15:19:11.000000000 +0100
@@ -20,9 +20,10 @@
#include "apr_portable.h"
#include "apr_arch_inherit.h"
-#if defined(BEOS) && !defined(BEOS_BONE)
+#ifdef BEOS_R5
+#undef close
#define close closesocket
-#endif
+#endif /* BEOS_R5 */
static char generic_inaddr_any[16] = {0}; /* big enough for IPv4 or IPv6 */
@@ -92,7 +93,28 @@
alloc_socket(new, cont);
+#ifndef BEOS_R5
(*new)->socketdes = socket(family, type, protocol);
+#else
+ /* For any reason BeOS R5 has an unconventional protocol numbering,
+ * so we need to translate here. */
+ switch (protocol) {
+ case 0:
+ (*new)->socketdes = socket(family, type, 0);
+ break;
+ case APR_PROTO_TCP:
+ (*new)->socketdes = socket(family, type, IPPROTO_TCP);
+ break;
+ case APR_PROTO_UDP:
+ (*new)->socketdes = socket(family, type, IPPROTO_UDP);
+ break;
+ case APR_PROTO_SCTP:
+ default:
+ errno = EPROTONOSUPPORT;
+ (*new)->socketdes = -1;
+ break;
+ }
+#endif /* BEOS_R5 */
#if APR_HAVE_IPV6
if ((*new)->socketdes < 0 && ofamily == APR_UNSPEC) {
diff -urN apr-1.0.1.orig/network_io/unix/sockopt.c apr-1.0.1/network_io/unix/sockopt.c
--- apr-1.0.1.orig/network_io/unix/sockopt.c 2004-04-03 19:15:52.000000000 +0200
+++ apr-1.0.1/network_io/unix/sockopt.c 2004-12-17 15:19:11.000000000 +0100
@@ -323,6 +323,7 @@
apr_status_t apr_socket_atmark(apr_socket_t *sock, int *atmark)
{
+#ifndef BEOS_R5
int oobmark;
if (ioctl(sock->socketdes, SIOCATMARK, (void*) &oobmark) < 0)
@@ -331,6 +332,9 @@
*atmark = (oobmark != 0);
return APR_SUCCESS;
+#else
+ return APR_ENOTIMPL;
+#endif
}
diff -urN apr-1.0.1.orig/shmem/beos/shm.c apr-1.0.1/shmem/beos/shm.c
--- apr-1.0.1.orig/shmem/beos/shm.c 2004-06-29 18:38:16.000000000 +0200
+++ apr-1.0.1/shmem/beos/shm.c 2004-12-17 15:19:11.000000000 +0100
@@ -13,25 +13,147 @@
* limitations under the License.
*/
-#include "apr_general.h"
-#include "apr_shm.h"
+#include "apr_arch_shm.h"
+#include "apr_arch_thread_mutex.h"
#include "apr_errno.h"
#include "apr_lib.h"
+#include "apr_general.h"
+#include "apr_portable.h"
+#include "apr_ring.h"
+#include "apr_shm.h"
#include "apr_strings.h"
+
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
-#include <kernel/OS.h>
-#include "apr_portable.h"
+#include <unistd.h>
+
+#include <OS.h>
+
+static struct apr_thread_mutex_t area_handles_lock;
-struct apr_shm_t {
- apr_pool_t *pool;
- void *memblock;
- void *ptr;
- apr_size_t reqsize;
- apr_size_t avail;
- area_id aid;
+APR_RING_HEAD(area_handle_list, beos_area_handle);
+static struct area_handle_list area_handles;
+
+struct beos_area_handle {
+ APR_RING_ENTRY(beos_area_handle) link;
+ area_id id; /* area id */
+ char *name; /* area name */
+ void *address; /* base address */
+ apr_size_t size; /* requested size */
+ char *filename; /* name of the file, associated with the area */
+ int fd; /* FD of the file, associated with the area */
+ int use_count; /* how often attached in this process */
};
+typedef struct shmem_file_info {
+ apr_size_t size; /* requested size of the shmem */
+ char name[B_OS_NAME_LENGTH]; /* area name */
+} shmem_file_info;
+
+#define LOCK_AREA_HANDLES() apr_thread_mutex_lock(&area_handles_lock)
+#define UNLOCK_AREA_HANDLES() apr_thread_mutex_unlock(\
+ &area_handles_lock)
+#define INIT_AREA_HANDLE_LINK(handle) APR_RING_ELEM_INIT(handle, link)
+#define FIRST_AREA_HANDLE() APR_RING_FIRST(&area_handles)
+#define NEXT_AREA_HANDLE(handle) APR_RING_NEXT(handle, link)
+#define AREA_HANDLES_END() APR_RING_SENTINEL(&area_handles, \
+ beos_area_handle, link)
+#define ADD_AREA_HANDLE(handle) APR_RING_INSERT_TAIL(&area_handles, \
+ handle, \
+ beos_area_handle, \
+ link)
+#define REMOVE_AREA_HANDLE(handle) APR_RING_REMOVE(handle, link)
+
+/* Initializes the area handle list and the semaphore that protects it. Invoked
+ by apr_initialize(). */
+apr_status_t apr_beos_setup_shmem()
+{
+ APR_RING_INIT(&area_handles, beos_area_handle, link);
+ return apr_beos_thread_mutex_init(&area_handles_lock, 0, NULL);
+}
+
+/* Called directly after fork() in the child process. Sets up the semaphore
+ that protects the area handle list in a child process and repairs the shared
+ memory areas. The problem is that BeOS fork() clones all areas copy on write,
+ which requires us to re-clone the parent's areas. */
+apr_status_t apr_beos_shmem_child_init()
+{
+ apr_status_t error;
+ beos_area_handle *handle;
+
+ /* re-init the lock */
+ error = apr_beos_thread_mutex_init(&area_handles_lock, 0, NULL);
+ if (error != B_OK)
+ return error;
+
+ /* now iterate through the area handle list and clone all areas */
+ for (handle = FIRST_AREA_HANDLE();
+ handle != AREA_HANDLES_END();
+ handle = NEXT_AREA_HANDLE(handle)) {
+ /* delete the clone area and clone the original one */
+ delete_area(area_for(handle->address));
+ handle->id = clone_area(handle->name, &(handle->address),
+ B_EXACT_ADDRESS, B_READ_AREA | B_WRITE_AREA,
+ handle->id);
+ if (handle->id < 0)
+ return handle->id;
+ }
+
+ return APR_SUCCESS;
+}
+
+/* Creates a new area handle from a given valid area_info. */
+static beos_area_handle *create_area_handle(area_id id, const char *name,
+ void *address, apr_size_t size,
+ const char *filename, int fd,
+ int useCount)
+{
+ beos_area_handle *handle
+ = (beos_area_handle*)malloc(sizeof(beos_area_handle));
+ if (!handle)
+ return NULL;
+
+ INIT_AREA_HANDLE_LINK(handle);
+ handle->id = id;
+ handle->name = strdup(name);
+ handle->address = address;
+ handle->size = size;
+ handle->filename = (filename ? strdup(filename) : NULL);
+ handle->fd = fd;
+ handle->use_count = useCount;
+
+ if (!handle->name || (filename && !handle->filename)) {
+ free(handle->name);
+ free(handle->filename);
+ free(handle);
+ return NULL;
+ }
+
+ return handle;
+}
+
+static apr_status_t shm_cleanup(void *_m)
+{
+ apr_shm_t *m = (apr_shm_t*)_m;
+
+ LOCK_AREA_HANDLES();
+
+ if (m->handle && --m->handle->use_count == 0) {
+ REMOVE_AREA_HANDLE(m->handle);
+ delete_area(m->handle->id);
+ if (m->handle->fd >= 0)
+ close(m->handle->fd);
+ free(m->handle->name);
+ free(m->handle);
+ }
+ m->handle = NULL;
+
+ UNLOCK_AREA_HANDLES();
+
+ return APR_SUCCESS;
+}
+
APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m,
apr_size_t reqsize,
const char *filename,
@@ -40,53 +162,102 @@
apr_size_t pagesize;
area_id newid;
char *addr;
- char shname[B_OS_NAME_LENGTH];
+ shmem_file_info fileInfo;
+ char *shname = fileInfo.name;
+ int fd = -1;
+ int num = 0;
+ status_t error = B_OK;
+ beos_area_handle *handle = NULL;
(*m) = (apr_shm_t *)apr_pcalloc(p, sizeof(apr_shm_t));
/* we MUST allocate in pages, so calculate how big an area we need... */
pagesize = ((reqsize + B_PAGE_SIZE - 1) / B_PAGE_SIZE) * B_PAGE_SIZE;
-
- if (!filename) {
- int num = 0;
- snprintf(shname, B_OS_NAME_LENGTH, "apr_shmem_%ld", find_thread(NULL));
- while (find_area(shname) >= 0)
- snprintf(shname, B_OS_NAME_LENGTH, "apr_shmem_%ld_%d",
- find_thread(NULL), num++);
- }
- newid = create_area(filename ? filename : shname,
- (void*)&addr, B_ANY_ADDRESS,
- pagesize, B_LAZY_LOCK, B_READ_AREA|B_WRITE_AREA);
- if (newid < 0)
- return errno;
+
+ /* create a unique name for the area */
+ snprintf(shname, B_OS_NAME_LENGTH, "apr_shmem_%ld", find_thread(NULL));
+ while (find_area(shname) >= 0)
+ snprintf(shname, B_OS_NAME_LENGTH, "apr_shmem_%ld_%d",
+ find_thread(NULL), num++);
+
+ LOCK_AREA_HANDLES();
+
+ /* if a file name was given, create the file */
+ if (filename) {
+ fd = open(filename, O_RDWR |O_CREAT | O_TRUNC | O_EXCL,
+ S_IRUSR | S_IWUSR, S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
+ if (fd < 0)
+ return errno;
+ }
+
+ /* write the shmem info to the file */
+ if (fd >= 0) {
+ int len = (shname + strlen(shname)) - (char*)&fileInfo;
+ fileInfo.size = reqsize;
+ if (write(fd, &fileInfo, len) < 0)
+ error = errno;
+ }
+
+ /* allocate the area */
+ if (error == B_OK) {
+ newid = create_area(shname, (void*)&addr, B_ANY_ADDRESS,
+ pagesize, B_LAZY_LOCK, B_READ_AREA | B_WRITE_AREA);
+ if (newid < 0)
+ error = newid;
+ }
+
+ /* allocate an area handle */
+ if (error == B_OK) {
+ handle = create_area_handle(newid, shname, addr, reqsize, filename, fd,
+ 1);
+ /* add it to the list */
+ if (handle)
+ ADD_AREA_HANDLE(handle);
+ else
+ error = APR_ENOMEM;
+ }
+
+ UNLOCK_AREA_HANDLES();
+
+ /* cleanup on error */
+ if (error != B_OK) {
+ if (newid >= 0)
+ delete_area(newid);
+ if (filename)
+ unlink(filename);
+ close(fd);
+ return error;
+ }
(*m)->pool = p;
- (*m)->aid = newid;
- (*m)->memblock = addr;
- (*m)->ptr = (void*)addr;
- (*m)->avail = pagesize; /* record how big an area we actually created... */
- (*m)->reqsize = reqsize;
+ (*m)->handle = handle;
+
+ apr_pool_cleanup_register(p, *m, shm_cleanup, apr_pool_cleanup_null);
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_shm_destroy(apr_shm_t *m)
{
- delete_area(m->aid);
- m->avail = 0;
- m->memblock = NULL;
- return APR_SUCCESS;
+ LOCK_AREA_HANDLES();
+
+ if (m->handle && m->handle->filename) {
+ unlink(m->handle->filename);
+ free(m->handle->filename);
+ m->handle->filename = NULL;
+ }
+
+ UNLOCK_AREA_HANDLES();
+
+ return apr_pool_cleanup_run(m->pool, m, shm_cleanup);
}
APR_DECLARE(apr_status_t) apr_shm_remove(const char *filename,
apr_pool_t *pool)
{
- area_id deleteme = find_area(filename);
-
- if (deleteme == B_NAME_NOT_FOUND)
- return APR_EINVAL;
+ if (unlink(filename) < 0)
+ return errno;
- delete_area(deleteme);
return APR_SUCCESS;
}
@@ -94,58 +265,132 @@
const char *filename,
apr_pool_t *pool)
{
- area_info ai;
- thread_info ti;
- apr_shm_t *new_m;
- area_id deleteme = find_area(filename);
-
- if (deleteme == B_NAME_NOT_FOUND)
+ int fd = -1;
+ shmem_file_info fileInfo;
+ char *areaName = fileInfo.name;
+ int fileInfoLen;
+ int nameLen = 0;
+ beos_area_handle *handle = NULL;
+ area_id id = -1;
+ status_t error = B_OK;
+
+ /* open the file */
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
return APR_EINVAL;
- new_m = (apr_shm_t*)apr_palloc(pool, sizeof(apr_shm_t*));
- if (new_m == NULL)
- return APR_ENOMEM;
- new_m->pool = pool;
-
- get_area_info(deleteme, &ai);
- get_thread_info(find_thread(NULL), &ti);
-
- if (ti.team != ai.team) {
- area_id narea;
-
- narea = clone_area(ai.name, &(ai.address), B_CLONE_ADDRESS,
- B_READ_AREA|B_WRITE_AREA, ai.area);
-
- if (narea < B_OK)
- return narea;
-
- get_area_info(narea, &ai);
- new_m->aid = narea;
- new_m->memblock = ai.address;
- new_m->ptr = (void*)ai.address;
- new_m->avail = ai.size;
- new_m->reqsize = ai.size;
+ /* read the file info */
+ fileInfoLen = read(fd, &fileInfo, sizeof(shmem_file_info) - 1);
+ if (fileInfoLen > 0) {
+ nameLen = (char*)&fileInfo + fileInfoLen - areaName;
+ if (nameLen > 0) {
+ areaName[nameLen] = '\0';
+ nameLen = strlen(areaName);
+ }
+ }
+ if (nameLen <= 0)
+ error = APR_EINVAL;
+
+ LOCK_AREA_HANDLES();
+
+ /* check, if we already know the area */
+ if (error == B_OK) {
+ beos_area_handle *itHandle;
+ for (itHandle = FIRST_AREA_HANDLE();
+ itHandle != AREA_HANDLES_END();
+ itHandle = NEXT_AREA_HANDLE(itHandle)) {
+ if (strcmp(itHandle->name, areaName) == 0) {
+ /* OK, found */
+ handle = itHandle;
+ close(fd);
+ fd = -1;
+ break;
+ }
+ }
+ }
+
+ /* if we don't know the area yet, get it */
+ if (error == B_OK && !handle) {
+ id = find_area(areaName);
+ if (id < 0)
+ error = APR_EINVAL;
+ }
+
+ /* if we have no error till now, then there definitely exists an area */
+ if (error == B_OK) {
+ /* allocate memory for the new shared memory handle */
+ *m = (apr_shm_t*)apr_palloc(pool, sizeof(apr_shm_t*));
+ if (!*m)
+ error = APR_ENOMEM;
}
- (*m) = new_m;
+ /* if we don't know the area yet, we clone it */
+ if (error == B_OK && !handle) {
+ area_info areaInfo;
+ error = get_area_info(id, &areaInfo);
+ if (error == B_OK && areaInfo.size < fileInfo.size) {
+ /* something's fishy: the actual area size is less than the
+ * shmem region it is supposed to contain */
+ error = APR_EINVAL;
+ }
+ if (error == B_OK) {
+ void *address;
+ id = clone_area(areaInfo.name, &address, B_ANY_ADDRESS,
+ B_READ_AREA | B_WRITE_AREA, areaInfo.area);
+ if (id >= 0) {
+ /* create the area */
+ handle = create_area_handle(id, areaName, address,
+ fileInfo.size, filename, fd, 0);
+ /* The size we supply here is actually not the real size
+ * of the shared memory region, but is rounded up to a
+ * page size multiple. We could store the real size in
+ * the file. */
- return APR_SUCCESS;
+ /* add it to the list */
+ if (handle) {
+ ADD_AREA_HANDLE(handle);
+ }
+ else {
+ delete_area(id);
+ error = APR_ENOMEM;
+ }
+ }
+ else
+ error = id;
+ }
+ }
+
+ /* now we should have a handle -- nothing can go wrong anymore */
+ if (error == B_OK) {
+ (*m)->pool = pool;
+ (*m)->handle = handle;
+ (*m)->handle->use_count++;
+ apr_pool_cleanup_register(pool, *m, shm_cleanup, apr_pool_cleanup_null);
+ }
+
+ UNLOCK_AREA_HANDLES();
+
+ /* cleanup on error */
+ if (error != B_OK) {
+ close(fd);
+ }
+
+ return error;
}
APR_DECLARE(apr_status_t) apr_shm_detach(apr_shm_t *m)
{
- delete_area(m->aid);
- return APR_SUCCESS;
+ return apr_pool_cleanup_run(m->pool, m, shm_cleanup);
}
APR_DECLARE(void *) apr_shm_baseaddr_get(const apr_shm_t *m)
{
- return m->memblock;
+ return (m->handle ? m->handle->address : NULL);
}
APR_DECLARE(apr_size_t) apr_shm_size_get(const apr_shm_t *m)
{
- return m->reqsize;
+ return (m->handle ? m->handle->size : 0);
}
APR_POOL_IMPLEMENT_ACCESSOR(shm)
diff -urN apr-1.0.1.orig/test/Makefile.in apr-1.0.1/test/Makefile.in
--- apr-1.0.1.orig/test/Makefile.in 2004-11-17 02:07:02.000000000 +0100
+++ apr-1.0.1/test/Makefile.in 2004-12-17 15:19:11.000000000 +0100
@@ -72,7 +72,7 @@
$(LIBTOOL) $(LTFLAGS) --mode=compile $(COMPILE) -prefer-pic -c $(srcdir)/mod_test.c && touch $@
mod_test.la: mod_test.slo $(LOCAL_LIBS)
- $(LIBTOOL) $(LTFLAGS) --mode=link $(COMPILE) -rpath `pwd` -avoid-version -module mod_test.lo $(LT_LDFLAGS) $(ALL_LDFLAGS) -o $@
+ $(LIBTOOL) $(LTFLAGS) --mode=link $(COMPILE) -rpath `pwd` -avoid-version -module mod_test.lo $(LT_LDFLAGS) $(ALL_LDFLAGS) -o $@ $(LOCAL_LIBS) $(ALL_LIBS)
libmod_test.la: mod_test.slo $(LOCAL_LIBS)
$(LIBTOOL) $(LTFLAGS) --mode=link $(COMPILE) -rpath `pwd` -avoid-version mod_test.lo $(LT_LDFLAGS) $(ALL_LDFLAGS) -o $@ $(LOCAL_LIBS) $(ALL_LIBS)
diff -urN apr-1.0.1.orig/test/testdso.c apr-1.0.1/test/testdso.c
--- apr-1.0.1.orig/test/testdso.c 2004-05-14 16:43:22.000000000 +0200
+++ apr-1.0.1/test/testdso.c 2004-12-17 15:19:11.000000000 +0100
@@ -77,9 +77,11 @@
ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
ABTS_PTR_NOTNULL(tc, func1);
- function = (void (*)(char *))func1;
- (*function)(teststr);
- ABTS_STR_EQUAL(tc, "Hello - I'm a DSO!\n", teststr);
+ if (status == APR_SUCCESS) {
+ function = (void (*)(char *))func1;
+ (*function)(teststr);
+ ABTS_STR_EQUAL(tc, "Hello - I'm a DSO!\n", teststr);
+ }
apr_dso_unload(h);
}
@@ -100,9 +102,11 @@
ABTS_ASSERT(tc, apr_dso_error(h, errstr, 256), APR_SUCCESS == status);
ABTS_PTR_NOTNULL(tc, func1);
- function = (int (*)(int))func1;
- status = (*function)(5);
- ABTS_INT_EQUAL(tc, 5, status);
+ if (status == APR_SUCCESS) {
+ function = (int (*)(int))func1;
+ status = (*function)(5);
+ ABTS_INT_EQUAL(tc, 5, status);
+ }
apr_dso_unload(h);
}
diff -urN apr-1.0.1.orig/test/testpipe.c apr-1.0.1/test/testpipe.c
--- apr-1.0.1.orig/test/testpipe.c 2004-05-14 16:43:22.000000000 +0200
+++ apr-1.0.1/test/testpipe.c 2004-12-17 15:19:11.000000000 +0100
@@ -23,6 +23,11 @@
#include "apr_thread_proc.h"
#include "apr_strings.h"
+/* BeOS doesn't offer non-blocking pipes */
+#if defined(BEOS)
+# define BLOCKING_PIPE_ONLY
+#endif
+
static apr_file_t *readp = NULL;
static apr_file_t *writep = NULL;
@@ -60,6 +65,10 @@
ABTS_PTR_NOTNULL(tc, readp);
ABTS_PTR_NOTNULL(tc, writep);
+#ifdef BLOCKING_PIPE_ONLY
+ (void)timeout;
+ ABTS_NOT_IMPL(tc, "no non-blocking pipe support");
+#else
rv = apr_file_pipe_timeout_get(readp, &timeout);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
ABTS_INT_EQUAL(tc, -1, timeout);
@@ -70,6 +79,7 @@
rv = apr_file_pipe_timeout_get(readp, &timeout);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
ABTS_INT_EQUAL(tc, apr_time_from_sec(1), timeout);
+#endif
}
static void read_write(abts_case *tc, void *data)
@@ -86,12 +96,16 @@
ABTS_PTR_NOTNULL(tc, readp);
ABTS_PTR_NOTNULL(tc, writep);
+#ifdef BLOCKING_PIPE_ONLY
+ ABTS_NOT_IMPL(tc, "no non-blocking pipe support");
+#else
rv = apr_file_pipe_timeout_set(readp, apr_time_from_sec(1));
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
rv = apr_file_read(readp, buf, &nbytes);
ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
ABTS_INT_EQUAL(tc, 0, nbytes);
+#endif
}
static void read_write_notimeout(abts_case *tc, void *data)
@@ -122,6 +136,9 @@
static void test_pipe_writefull(abts_case *tc, void *data)
{
+#ifdef BLOCKING_PIPE_ONLY
+ ABTS_NOT_IMPL(tc, "no non-blocking pipe support");
+#else
int iterations = 1000;
int i;
int bytes_per_iteration = 8000;
@@ -177,6 +194,7 @@
apr_proc_wait(&proc, NULL, &why, APR_WAIT) == APR_CHILD_DONE);
ABTS_ASSERT(tc, "child terminated normally", why == APR_PROC_EXIT);
+#endif
}
abts_suite *testpipe(abts_suite *suite)
diff -urN apr-1.0.1.orig/test/testpoll.c apr-1.0.1/test/testpoll.c
--- apr-1.0.1.orig/test/testpoll.c 2004-07-06 05:38:06.000000000 +0200
+++ apr-1.0.1/test/testpoll.c 2004-12-17 15:19:11.000000000 +0100
@@ -21,6 +21,11 @@
#include "apr_network_io.h"
#include "apr_poll.h"
+/* non-BONE BeOS select() only supports the read set */
+#if defined(BEOS) && !defined(HAVE_BONE_VERSION)
+# define NO_POLLOUT_SUPPORT 1
+#endif
+
#define SMALL_NUM_SOCKETS 3
/* We can't use 64 here, because some platforms *ahem* Solaris *ahem* have
* a default limit of 64 open file descriptors per process. If we use
@@ -425,6 +430,9 @@
static void pollset_remove(abts_case *tc, void *data)
{
+#ifdef NO_POLLOUT_SUPPORT
+ ABTS_NOT_IMPL(tc, "no APR_POLLOUT support");
+#else
apr_status_t rv;
apr_pollset_t *pollset;
const apr_pollfd_t *hot_files;
@@ -497,6 +505,7 @@
(hot_files[1].client_data == (void *)4)) ||
((hot_files[0].client_data == (void *)4) &&
(hot_files[1].client_data == (void *)1)));
+#endif
}
abts_suite *testpoll(abts_suite *suite)
@@ -527,9 +536,7 @@
abts_run_test(suite, clear_middle_pollset, NULL);
abts_run_test(suite, send_last_pollset, NULL);
abts_run_test(suite, clear_last_pollset, NULL);
-
abts_run_test(suite, pollset_remove, NULL);
-
abts_run_test(suite, close_all_sockets, NULL);
return suite;
diff -urN apr-1.0.1.orig/test/testsockopt.c apr-1.0.1/test/testsockopt.c
--- apr-1.0.1.orig/test/testsockopt.c 2004-08-01 00:36:03.000000000 +0200
+++ apr-1.0.1/test/testsockopt.c 2004-12-17 15:19:11.000000000 +0100
@@ -19,6 +19,11 @@
#include "apr_lib.h"
#include "testutil.h"
+/* non-BONE BeOS versions don't know SO_KEEPALIVE */
+#if defined(BEOS) && !defined(HAVE_BONE_VERSION)
+# define NO_SO_KEEPALIVE 1
+#endif
+
static apr_socket_t *sock = NULL;
static void create_socket(abts_case *tc, void *data)
@@ -32,6 +37,9 @@
static void set_keepalive(abts_case *tc, void *data)
{
+#ifdef NO_SO_KEEPALIVE
+ ABTS_NOT_IMPL(tc, "no SO_KEEPALIVE socket option");
+#else
apr_status_t rv;
apr_int32_t ck;
@@ -41,6 +49,7 @@
rv = apr_socket_opt_get(sock, APR_SO_KEEPALIVE, &ck);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
ABTS_INT_EQUAL(tc, 1, ck);
+#endif
}
static void set_debug(abts_case *tc, void *data)
@@ -62,6 +71,9 @@
static void remove_keepalive(abts_case *tc, void *data)
{
+#ifdef NO_SO_KEEPALIVE
+ ABTS_NOT_IMPL(tc, "no SO_KEEPALIVE socket option");
+#else
apr_status_t rv;
apr_int32_t ck;
@@ -75,6 +87,7 @@
rv = apr_socket_opt_get(sock, APR_SO_KEEPALIVE, &ck);
ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
ABTS_INT_EQUAL(tc, 0, ck);
+#endif
}
static void corkable(abts_case *tc, void *data)
diff -urN apr-1.0.1.orig/threadproc/beos/Makefile.in apr-1.0.1/threadproc/beos/Makefile.in
--- apr-1.0.1.orig/threadproc/beos/Makefile.in 1970-01-01 01:00:00.000000000 +0100
+++ apr-1.0.1/threadproc/beos/Makefile.in 2004-12-17 15:18:45.000000000 +0100
@@ -0,0 +1,21 @@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+TARGETS = \
+ apr_proc_stub
+
+# bring in rules.mk for standard functionality
+@INCLUDE_RULES@
+
+INCDIR=../../include
+OSDIR=$(INCDIR)/arch/@OSDIR@
+DEFOSDIR=$(INCDIR)/arch/@DEFAULT_OSDIR@
+INCLUDES=-I$(INCDIR) -I$(INCDIR)/arch -I$(OSDIR) -I$(DEFOSDIR)
+
+CLEAN_TARGETS = apr_proc_stub /boot/home/config/bin/apr_proc_stub
+
+apr_proc_stub:
+ $(CC) apr_proc_stub.c \
+ && cp apr_proc_stub /boot/home/config/bin
+
+# DO NOT REMOVE
diff -urN apr-1.0.1.orig/threadproc/beos/apr_proc_stub.c apr-1.0.1/threadproc/beos/apr_proc_stub.c
--- apr-1.0.1.orig/threadproc/beos/apr_proc_stub.c 2004-02-13 10:38:38.000000000 +0100
+++ apr-1.0.1/threadproc/beos/apr_proc_stub.c 2004-12-17 15:19:11.000000000 +0100
@@ -13,15 +13,17 @@
* limitations under the License.
*/
+#include <errno.h>
#include <kernel/OS.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
struct pipefd {
- int in;
- int out;
- int err;
+ int in;
+ int out;
+ int err;
+ port_id port;
};
int main(int argc, char *argv[]) {
@@ -32,44 +34,65 @@
* argv[2] = progname to execute
* rest of arguments to be passed to program
*/
- char *progname = argv[2];
- char *directory = argv[1];
- struct pipefd *pfd;
- thread_id sender;
- void *buffer;
- char ** newargs;
- int i = 0;
-
- newargs = (char**)malloc(sizeof(char*) * (argc - 1));
-
- buffer = (void*)malloc(sizeof(struct pipefd));
- /* this will block until we get the data */
- receive_data(&sender, buffer, sizeof(struct pipefd));
- pfd = (struct pipefd*)buffer;
-
- if (pfd->in > STDERR_FILENO) {
- if (dup2(pfd->in, STDIN_FILENO) != STDIN_FILENO) return (-1);
- close (pfd->in);
- }
- if (pfd->out > STDERR_FILENO) {
- if (dup2(pfd->out, STDOUT_FILENO) != STDOUT_FILENO) return (-1);
- close (pfd->out);
- }
- if (pfd->err > STDERR_FILENO) {
- if (dup2(pfd->err, STDERR_FILENO) != STDERR_FILENO) return (-1);
- close (pfd->err);
- }
-
- for (i=3;i<=argc;i++){
- newargs[i-3] = argv[i];
- }
-
- /* tell the caller we're OK to start */
- send_data(sender,1,NULL,0);
-
- if (directory != NULL)
- chdir(directory);
- execve (progname, newargs, environ);
+ char *progname = argv[2];
+ char *directory = argv[1];
+ struct pipefd pfd;
+ thread_id sender;
+ char **newargs = argv + 3;
+ int i = 0;
+ status_t error = B_OK;
+
+ /* this will block until we get the data */
+ receive_data(&sender, &pfd, sizeof(struct pipefd));
+
+ if (argc < 3)
+ error = B_BAD_VALUE;
+
+ newargs = (char**)malloc(sizeof(char*) * (argc - 1));
+ for (i=3;i<=argc;i++) {
+ newargs[i-3] = argv[i];
+ }
+
+ if (error == B_OK && pfd.in > STDERR_FILENO) {
+ if (dup2(pfd.in, STDIN_FILENO) != STDIN_FILENO)
+ error = errno;
+ close(pfd.in);
+ }
+ if (error == B_OK && pfd.out > STDERR_FILENO) {
+ if (dup2(pfd.out, STDOUT_FILENO) != STDOUT_FILENO)
+ error = errno;
+ close(pfd.out);
+ }
+ if (error == B_OK && pfd.err > STDERR_FILENO) {
+ if (dup2(pfd.err, STDERR_FILENO) != STDERR_FILENO)
+ error = errno;
+ close(pfd.err);
+ }
+
+ if (error == B_OK && chdir(directory) < 0)
+ error = errno;
+
+ if (error == B_OK) {
+ /* get our parent's team ID (the port owner) and our team ID */
+ port_info portInfo;
+ thread_info threadInfo;
+ get_port_info(pfd.port, &portInfo);
+ get_thread_info(find_thread(NULL), &threadInfo);
+
+ /* transfer the port ownership to us, so the the port will
+ * automatically be deleted, if execv() succeeds */
+ set_port_owner(pfd.port, threadInfo.team);
+
+ if (execv(progname, newargs) < 0)
+ error = errno;
+
+ /* execv() failed; transfer the port ownership back to our parent,
+ * so that we can send the error code to it */
+ set_port_owner(pfd.port, portInfo.team);
+ }
- return (-1);
+ /* something went wrong; send our parent the error code */
+ write_port(pfd.port, 0, &error, sizeof(error));
+
+ return (-1);
}
diff -urN apr-1.0.1.orig/threadproc/beos/proc.c apr-1.0.1/threadproc/beos/proc.c
--- apr-1.0.1.orig/threadproc/beos/proc.c 2004-06-29 18:35:57.000000000 +0200
+++ apr-1.0.1/threadproc/beos/proc.c 2004-12-17 15:19:11.000000000 +0100
@@ -13,13 +13,22 @@
* limitations under the License.
*/
+#include "apr_arch_shm.h"
#include "apr_arch_threadproc.h"
+#include "apr_random.h"
+#include "apr_signal.h"
#include "apr_strings.h"
+#include <stdlib.h>
+#include <string.h>
+
+#include <image.h>
+
struct send_pipe {
- int in;
- int out;
- int err;
+ int in;
+ int out;
+ int err;
+ port_id port;
};
APR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new, apr_pool_t *pool)
@@ -113,18 +122,11 @@
APR_DECLARE(apr_status_t) apr_procattr_dir_set(apr_procattr_t *attr,
const char *dir)
{
- char * cwd;
- if (dir[0] != '/') {
- cwd = (char*)malloc(sizeof(char) * PATH_MAX);
- getcwd(cwd, PATH_MAX);
- attr->currdir = (char *)apr_pstrcat(attr->pool, cwd, "/", dir, NULL);
- free(cwd);
- } else {
- attr->currdir = (char *)apr_pstrdup(attr->pool, dir);
- }
+ attr->currdir = apr_pstrdup(attr->pool, dir);
if (attr->currdir) {
return APR_SUCCESS;
}
+
return APR_ENOMEM;
}
@@ -144,53 +146,53 @@
APR_DECLARE(apr_status_t) apr_proc_fork(apr_proc_t *proc, apr_pool_t *pool)
{
int pid;
+ port_id port;
+ status_t error = B_OK;
+ status_t childInitError = B_OK;
+ int32 code;
+
+ /* we create a port through which the child will send us whether its
+ * initialization was successful */
+ port = create_port(1, "apr_fork");
+ if (port < 0)
+ return port;
if ((pid = fork()) < 0) {
+ delete_port(port);
return errno;
}
else if (pid == 0) {
- /* This is really ugly...
- * The semantics of BeOS's fork() are that areas (used for shared
- * memory) get COW'd :-( The only way we can make shared memory
- * work across fork() is therefore to find any areas that have
- * been created and then clone them into our address space.
- * Thankfully only COW'd areas have the lock variable set at
- * anything but 0, so we can use that to find the areas we need to
- * copy. Of course what makes it even worse is that the loop through
- * the area's will go into an infinite loop, eating memory and then
- * eventually segfault unless we know when we reach then end of the
- * "original" areas and stop. Why? Well, we delete the area and then
- * add another to the end of the list...
- */
- area_info ai;
- int32 cookie = 0;
- area_id highest = 0;
-
- while (get_next_area_info(0, &cookie, &ai) == B_OK)
- if (ai.area > highest)
- highest = ai.area;
- cookie = 0;
- while (get_next_area_info(0, &cookie, &ai) == B_OK) {
- if (ai.area > highest)
- break;
- if (ai.lock > 0) {
- area_id original = find_area(ai.name);
- delete_area(ai.area);
- clone_area(ai.name, &ai.address, B_CLONE_ADDRESS,
- ai.protection, original);
- }
- }
-
proc->pid = pid;
- proc->in = NULL;
+ proc->in = NULL;
proc->out = NULL;
proc->err = NULL;
+
+ error = apr_beos_shmem_child_init();
+ write_port(port, 0, &error, sizeof(error));
+ if (error != B_OK)
+ exit(1);
+
+ apr_random_after_fork(proc);
+
return APR_INCHILD;
}
proc->pid = pid;
proc->in = NULL;
proc->out = NULL;
proc->err = NULL;
+
+ /* get the child initialization status */
+ do {
+ error = read_port(port, &code, &childInitError, sizeof(childInitError));
+ } while (error == EINTR);
+
+ delete_port(port);
+
+ if (error >= B_OK)
+ error = childInitError;
+ if (error != B_OK)
+ return error;
+
return APR_INPARENT;
}
@@ -215,62 +217,234 @@
return APR_SUCCESS;
}
+static status_t find_program(const char **resolvedProgramName,
+ const char *programName, apr_procattr_t *attr,
+ const char *const *env, apr_pool_t *pool)
+{
+ const char *pathVarName = "PATH=";
+ int pathVarNameLen = strlen(pathVarName);
+ const char *paths = NULL;
+ int programNameLen = strlen(programName);
+ int i;
+
+ /* If the program name is absolute, then there's nothing to do.
+ * If the program name consists of more than one path element, then we
+ * consider it a relative path and don't search in PATH either. */
+ if (*programName == '/' || strchr(programName, '/')) {
+ *resolvedProgramName = programName;
+ return B_OK;
+ }
+
+ /* get the PATH environment variable */
+ for (i = 0; env[i]; i++) {
+ const char *var = env[i];
+ if (strncmp(var, pathVarName, pathVarNameLen) == 0) {
+ paths = var + pathVarNameLen;
+ break;
+ }
+ }
+ if (!paths)
+ return APR_ENOENT;
+
+ /* iterate through the paths */
+ do {
+ const char *pathEnd = strchr(paths, ':');
+ int pathLen = (pathEnd ? pathEnd - paths : strlen(paths));
+
+ /* We skip empty paths and those that would become too long.
+ * The latter is not really correct, but practically irrelevant. */
+ if (pathLen > 0
+ && pathLen + 1 + programNameLen < B_PATH_NAME_LENGTH) {
+ /* get the path */
+ char path[B_PATH_NAME_LENGTH];
+ struct stat st;
+ memcpy(path, paths, pathLen);
+ path[pathLen] = '\0';
+
+ /* get the program path */
+ strcat(path, "/");
+ strcat(path, programName);
+
+ /* stat() the path to be sure, there is a file */
+ if (stat(path, &st) == 0 && S_ISREG(st.st_mode)) {
+ /* If the path is relative, we make it absolute by
+ * prepending the current working directory, so there
+ * won't be problems when changing the cwd later */
+ if (*path == '/') {
+ *resolvedProgramName = apr_pstrdup(pool, path);
+ }
+ else {
+ char cwd[B_PATH_NAME_LENGTH];
+ getcwd(cwd, sizeof(cwd));
+ *resolvedProgramName = apr_pstrcat(pool, cwd, "/",
+ path, NULL);
+ }
+ return B_OK;
+ }
+ }
+
+ paths = (pathEnd ? pathEnd + 1 : NULL);
+ } while (paths);
+
+ /* not found in PATH */
+ return APR_ENOENT;
+}
+
+typedef struct char_buffer {
+ char *buffer;
+ int size;
+} char_buffer;
+
+static void append_char(char_buffer *buffer, char c)
+{
+ if (buffer->buffer) {
+ *(buffer->buffer) = c;
+ buffer->buffer++;
+ }
+ buffer->size++;
+}
+
+static void prepare_shell_args(const char *progname, const char * const *args,
+ int argc, char_buffer *buffer)
+{
+ int i;
+
+ for (i = 0; i < argc; i++) {
+ const char *arg = args[i];
+
+ /* replace the first argument with the program name and separate the
+ * other arguments with a space */
+ if (i == 0)
+ arg = progname;
+ else
+ append_char(buffer, ' ');
+
+ if (*arg == '\0') {
+ /* empty arg */
+ append_char(buffer, '"');
+ append_char(buffer, '"');
+ }
+ else {
+ while (*arg) {
+ /* escape special characters */
+ if (strchr(" ()?*&\"'[]^\\~|;!<>*$", *arg))
+ append_char(buffer, '\\');
+ append_char(buffer, *arg);
+ arg++;
+ }
+ }
+ }
+}
+
APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new, const char *progname,
const char * const *args,
const char * const *env,
apr_procattr_t *attr,
apr_pool_t *pool)
{
- int i=0,nargs=0;
- char **newargs = NULL;
- thread_id newproc, sender;
- struct send_pipe *sp;
- char * dir = NULL;
-
- sp = (struct send_pipe *)apr_palloc(pool, sizeof(struct send_pipe));
+ int i = 0, nargs = 0;
+ const char **newargs = NULL;
+ thread_id newproc;
+ struct send_pipe sp;
+ const char *shellArgs[4] = { SHELL_PATH, "-c", NULL, NULL };
+ status_t error;
+ status_t childError;
new->in = attr->parent_in;
new->err = attr->parent_err;
new->out = attr->parent_out;
- sp->in = attr->child_in ? attr->child_in->filedes : -1;
- sp->out = attr->child_out ? attr->child_out->filedes : -1;
- sp->err = attr->child_err ? attr->child_err->filedes : -1;
+ sp.in = attr->child_in ? attr->child_in->filedes : -1;
+ sp.out = attr->child_out ? attr->child_out->filedes : -1;
+ sp.err = attr->child_err ? attr->child_err->filedes : -1;
+
+ /* Get the correct environment to use. */
+ switch (attr->cmdtype) {
+ case APR_SHELLCMD:
+ case APR_PROGRAM:
+ break;
+ case APR_PROGRAM_ENV:
+ case APR_PROGRAM_PATH:
+ case APR_SHELLCMD_ENV:
+ env = (const char *const*)environ;
+ break;
+ }
+ if (!env)
+ env = (const char *const*)environ;
+
+ /* In case of APR_PROGRAM_PATH we need to find the program ourselves. In
+ * the other cases, the program name shall either be considered a path or
+ * the shell searches for the program. */
+ if (attr->cmdtype == APR_PROGRAM_PATH) {
+ error = find_program(&progname, progname, attr, env, pool);
+ if (error != B_OK)
+ return error;
+ }
+
+ /* if the program shall be started via shell, we need to prepare the
+ * arguments */
+ if (attr->cmdtype == APR_SHELLCMD || attr->cmdtype == APR_SHELLCMD_ENV) {
+ char_buffer charBuffer = { NULL, 0 };
+ int argc = 0;
+
+ /* count the arguments */
+ while (args && args[argc]) {
+ argc++;
+ }
+ if (argc == 0)
+ return APR_EINVAL;
+
+ /* first we get the length */
+ prepare_shell_args(progname, args, argc, &charBuffer);
+ /* allocate the memory and get the args for real */
+ charBuffer.buffer = (char*)apr_palloc(pool, charBuffer.size + 1);
+ charBuffer.size = 0;
+ shellArgs[2] = charBuffer.buffer;
+ prepare_shell_args(progname, args, argc, &charBuffer);
+ *(charBuffer.buffer) = '\0';
+
+ /* replace the program name and the arguments */
+ progname = shellArgs[0];
+ args = shellArgs;
+ }
+
+ /* count the arguments */
i = 0;
while (args && args[i]) {
i++;
}
- newargs = (char**)malloc(sizeof(char *) * (i + 4));
- newargs[0] = strdup("/boot/home/config/bin/apr_proc_stub");
+ newargs = (const char**)malloc(sizeof(const char *) * (i + 4));
+ newargs[0] = "/boot/home/config/bin/apr_proc_stub";
if (attr->currdir == NULL) {
- /* we require the directory , so use a temp. variable */
- dir = malloc(sizeof(char) * PATH_MAX);
- getcwd(dir, PATH_MAX);
- newargs[1] = strdup(dir);
- free(dir);
- } else {
- newargs[1] = strdup(attr->currdir);
+ newargs[1] = ".";
}
- newargs[2] = strdup(progname);
+ else {
+ newargs[1] = attr->currdir;
+ }
+ newargs[2] = progname;
i=0;nargs = 3;
while (args && args[i]) {
- newargs[nargs] = strdup(args[i]);
+ newargs[nargs] = args[i];
i++;nargs++;
}
newargs[nargs] = NULL;
- /* ### we should be looking at attr->cmdtype in here... */
-
- newproc = load_image(nargs, (const char**)newargs, (const char**)env);
+ /* create a temporary port, the stub will use to report an error back to
+ * us */
+ sp.port = create_port(1, "apr_proc_create");
+ if (sp.port < 0)
+ return sp.port;
+
+ /* load the stub */
+ newproc = load_image(nargs, newargs, (const char**)env);
/* load_image copies the data so now we can free it... */
- while (--nargs >= 0)
- free (newargs[nargs]);
free(newargs);
if (newproc < B_NO_ERROR) {
+ delete_port(sp.port);
return errno;
}
@@ -286,15 +460,25 @@
apr_file_close(attr->child_err);
}
- send_data(newproc, 0, (void*)sp, sizeof(struct send_pipe));
+ send_data(newproc, 0, &sp, sizeof(struct send_pipe));
new->pid = newproc;
/* before we go charging on we need the new process to get to a
- * certain point. When it gets there it'll let us know and we
- * can carry on. */
- receive_data(&sender, (void*)NULL,0);
-
- return APR_SUCCESS;
+ * certain point. The stub will either send us an error code back through
+ * the port or simply delete the port, when everything went fine. */
+ do {
+ int32 code;
+ error = read_port(sp.port, &code, &childError, sizeof(childError));
+ } while (error == EINTR);
+
+ if (error == B_BAD_PORT_ID)
+ return APR_SUCCESS;
+
+ delete_port(sp.port);
+
+ if (error >= B_OK)
+ return childError;
+ return error;
}
APR_DECLARE(apr_status_t) apr_proc_wait_all_procs(apr_proc_t *proc,
@@ -360,10 +544,10 @@
apr_file_pipe_create(&attr->child_in, &attr->parent_in, attr->pool);
if (child_in != NULL)
- apr_file_dup(&attr->child_in, child_in, attr->pool);
+ apr_file_dup2(attr->child_in, child_in, attr->pool);
if (parent_in != NULL)
- apr_file_dup(&attr->parent_in, parent_in, attr->pool);
+ apr_file_dup2(attr->parent_in, parent_in, attr->pool);
return APR_SUCCESS;
}
@@ -375,10 +559,10 @@
apr_file_pipe_create(&attr->child_out, &attr->parent_out, attr->pool);
if (child_out != NULL)
- apr_file_dup(&attr->child_out, child_out, attr->pool);
+ apr_file_dup2(attr->child_out, child_out, attr->pool);
if (parent_out != NULL)
- apr_file_dup(&attr->parent_out, parent_out, attr->pool);
+ apr_file_dup2(attr->parent_out, parent_out, attr->pool);
return APR_SUCCESS;
}
@@ -390,10 +574,10 @@
apr_file_pipe_create(&attr->child_err, &attr->parent_err, attr->pool);
if (child_err != NULL)
- apr_file_dup(&attr->child_err, child_err, attr->pool);
+ apr_file_dup2(attr->child_err, child_err, attr->pool);
if (parent_err != NULL)
- apr_file_dup(&attr->parent_err, parent_err, attr->pool);
+ apr_file_dup2(attr->parent_err, parent_err, attr->pool);
return APR_SUCCESS;
}
diff -urN apr-1.0.1.orig/threadproc/beos/thread.c apr-1.0.1/threadproc/beos/thread.c
--- apr-1.0.1.orig/threadproc/beos/thread.c 2004-06-10 12:57:25.000000000 +0200
+++ apr-1.0.1/threadproc/beos/thread.c 2004-12-17 15:19:11.000000000 +0100
@@ -26,27 +26,27 @@
}
(*new)->pool = pool;
- (*new)->attr = (int32)B_NORMAL_PRIORITY;
+ (*new)->attr = (int32)B_NORMAL_PRIORITY;
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_threadattr_detach_set(apr_threadattr_t *attr, apr_int32_t on)
{
- if (on == 1){
- attr->detached = 1;
- } else {
- attr->detached = 0;
- }
+ if (on == 1){
+ attr->detached = 1;
+ } else {
+ attr->detached = 0;
+ }
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_threadattr_detach_get(apr_threadattr_t *attr)
{
- if (attr->detached == 1){
- return APR_DETACH;
- }
- return APR_NOTDETACH;
+ if (attr->detached == 1){
+ return APR_DETACH;
+ }
+ return APR_NOTDETACH;
}
APR_DECLARE(apr_status_t) apr_threadattr_stacksize_set(apr_threadattr_t *attr,
@@ -61,10 +61,11 @@
return APR_ENOTIMPL;
}
-static void *dummy_worker(void *opaque)
+static int32 dummy_worker(void *opaque)
{
apr_thread_t *thd = (apr_thread_t*)opaque;
- return thd->func(thd, thd->data);
+ thd->func(thd, thd->data);
+ return 0;
}
APR_DECLARE(apr_status_t) apr_thread_create(apr_thread_t **new, apr_threadattr_t *attr,
@@ -82,23 +83,21 @@
(*new)->pool = pool;
(*new)->data = data;
(*new)->func = func;
- (*new)->exitval = -1;
+ (*new)->exitval = 0;
+ (*new)->join_count = 0;
/* First we create the new thread...*/
- if (attr)
- temp = attr->attr;
- else
- temp = B_NORMAL_PRIORITY;
+ if (attr)
+ temp = attr->attr;
+ else
+ temp = B_NORMAL_PRIORITY;
stat = apr_pool_create(&(*new)->pool, pool);
if (stat != APR_SUCCESS) {
return stat;
}
- (*new)->td = spawn_thread((thread_func)dummy_worker,
- "apr thread",
- temp,
- (*new));
+ (*new)->td = spawn_thread(dummy_worker, "apr thread", temp, (*new));
/* Now we try to run it...*/
if (resume_thread((*new)->td) == B_NO_ERROR) {
@@ -128,7 +127,8 @@
return APR_SUCCESS;
}
-APR_DECLARE(apr_status_t) apr_thread_join(apr_status_t *retval, apr_thread_t *thd)
+APR_DECLARE(apr_status_t) apr_thread_join(apr_status_t *retval,
+ apr_thread_t *thd)
{
status_t rv = 0, ret;
ret = wait_for_thread(thd->td, &rv);
@@ -137,10 +137,10 @@
return APR_SUCCESS;
}
else {
- /* if we've missed the thread's death, did we set an exit value prior
- * to it's demise? If we did return that.
+ /* We've missed the thread's death, if noone joined it before us, we
+ * will succeed.
*/
- if (thd->exitval != -1) {
+ if (atomic_add(&thd->join_count, 1) == 0) {
*retval = thd->exitval;
return APR_SUCCESS;
} else
@@ -150,12 +150,27 @@
APR_DECLARE(apr_status_t) apr_thread_detach(apr_thread_t *thd)
{
- if (suspend_thread(thd->td) == B_NO_ERROR){
+ /*
+ if (suspend_thread(thd->td) == B_NO_ERROR){
return APR_SUCCESS;
}
else {
return errno;
}
+
+ * bonefish:
+ * The code above is definitely not correct. The OpenGroup specification
+ * of pthread_detach() says:
+ *
+ * "The pthread_detach() function shall indicate to the implementation that
+ * storage for the thread thread can be reclaimed when that thread
+ * terminates. If thread has not terminated, pthread_detach() shall not
+ * cause it to terminate. The effect of multiple pthread_detach() calls
+ * on the same target thread is unspecified."
+ *
+ * I don't really see, what we should do here.
+ */
+ return APR_SUCCESS;
}
void apr_thread_yield()
@@ -198,10 +213,8 @@
{
apr_thread_once_t *control = (apr_thread_once_t *)vcontrol;
- if (control->sem) {
- release_sem(control->sem);
+ if (control->sem >= 0)
delete_sem(control->sem);
- }
return APR_SUCCESS;
}
@@ -211,7 +224,6 @@
{
int rc;
*control = (apr_thread_once_t *)apr_pcalloc(p, sizeof(apr_thread_once_t));
- (*control)->hit = 0; /* we haven't done it yet... */
rc = ((*control)->sem = create_sem(1, "thread_once"));
if (rc < 0)
return rc;
@@ -225,10 +237,11 @@
APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control,
void (*func)(void))
{
- if (!control->hit) {
+ if (control->sem >= 0) {
if (acquire_sem(control->sem) == B_OK) {
- control->hit = 1;
func();
+ delete_sem(control->sem);
+ control->sem = -1;
}
}
return APR_SUCCESS;
diff -urN apr-1.0.1.orig/threadproc/beos/threadpriv.c apr-1.0.1/threadproc/beos/threadpriv.c
--- apr-1.0.1.orig/threadproc/beos/threadpriv.c 2004-02-13 10:38:38.000000000 +0100
+++ apr-1.0.1/threadproc/beos/threadpriv.c 2004-12-17 15:19:11.000000000 +0100
@@ -14,135 +14,51 @@
*/
#include "apr_arch_threadproc.h"
+#include <TLS.h>
-static struct beos_key key_table[BEOS_MAX_DATAKEYS];
-static struct beos_private_data *beos_data[BEOS_MAX_DATAKEYS];
-static sem_id lock;
+static void threadkey_cleanup(void *_key)
+{
+ apr_threadkey_t *key = (apr_threadkey_t *)_key;
+ void* data = tls_get(key->key);
+
+ if (data && key->destructor) {
+ (*key->destructor)(data);
+ }
+}
APR_DECLARE(apr_status_t) apr_threadkey_private_create(apr_threadkey_t **key,
void (*dest)(void *), apr_pool_t *pool)
{
- (*key) = (apr_threadkey_t *)apr_palloc(pool, sizeof(apr_threadkey_t));
+ (*key) = (apr_threadkey_t *)apr_pcalloc(pool, sizeof(apr_threadkey_t));
+
if ((*key) == NULL) {
return APR_ENOMEM;
}
+ (*key)->key = tls_allocate();
(*key)->pool = pool;
-
- acquire_sem(lock);
- for ((*key)->key=0; (*key)->key < BEOS_MAX_DATAKEYS; (*key)->key++){
- if (key_table[(*key)->key].assigned == 0){
- key_table[(*key)->key].assigned = 1;
- key_table[(*key)->key].destructor = dest;
- release_sem(lock);
- return APR_SUCCESS;
- }
-
- }
- release_sem(lock);
- return APR_ENOMEM;
+ (*key)->destructor = dest;
+
+ on_exit_thread(&threadkey_cleanup, *key);
+
+ return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_threadkey_private_get(void **new, apr_threadkey_t *key)
{
- thread_id tid;
- int i, index=0;
- tid = find_thread(NULL);
- for (i=0;i<BEOS_MAX_DATAKEYS;i++){
- if (beos_data[i]->data){
- /* it's been used */
- if (beos_data[i]->td == tid){
- index = i;
- }
- }
- }
- if (index == 0){
- /* no storage for thread so we can't get anything... */
- return APR_ENOMEM;
- }
-
- if ((key->key < BEOS_MAX_DATAKEYS) && (key_table)){
- acquire_sem(key_table[key->key].lock);
- if (key_table[key->key].count){
- (*new) = (void*)beos_data[index]->data[key->key];
- } else {
- (*new) = NULL;
- }
- release_sem(key_table[key->key].lock);
- } else {
- (*new) = NULL;
- }
- return APR_SUCCESS;
+ (*new) = tls_get(key->key);
+ return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_threadkey_private_set(void *priv, apr_threadkey_t *key)
{
- thread_id tid;
- int i,index = 0, ret = 0;
-
- tid = find_thread(NULL);
- for (i=0; i < BEOS_MAX_DATAKEYS; i++){
- if (beos_data[i]->data){
- if (beos_data[i]->td == tid){index = i;}
- }
- }
- if (index==0){
- /* not yet been allocated */
- for (i=0; i< BEOS_MAX_DATAKEYS; i++){
- if (! beos_data[i]->data){
- /* we'll take this one... */
- index = i;
- beos_data[i]->data = (const void **)malloc(sizeof(void *) * BEOS_MAX_DATAKEYS);
- memset((void *)beos_data[i]->data, 0, sizeof(void *) * BEOS_MAX_DATAKEYS);
- beos_data[i]->count = (int)malloc(sizeof(int));
- beos_data[i]->td = (thread_id)malloc(sizeof(thread_id));
- beos_data[i]->td = tid;
- }
- }
- }
- if (index == 0){
- /* we're out of luck.. */
- return APR_ENOMEM;
- }
- if ((key->key < BEOS_MAX_DATAKEYS) && (key_table)){
- acquire_sem(key_table[key->key].lock);
- if (key_table[key->key].count){
- if (beos_data[index]->data[key->key] == NULL){
- if (priv != NULL){
- beos_data[index]->count++;
- key_table[key->key].count++;
- }
- } else {
- if (priv == NULL){
- beos_data[index]->count--;
- key_table[key->key].count--;
- }
- }
- beos_data[index]->data[key->key] = priv;
- ret = 1;
- } else {
- ret = 0;
- }
- release_sem(key_table[key->key].lock);
- }
- if (ret)
- return APR_SUCCESS;
- return APR_ENOMEM;
+ tls_set(key->key, priv);
+ return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_threadkey_private_delete(apr_threadkey_t *key)
{
- if (key->key < BEOS_MAX_DATAKEYS){
- acquire_sem(key_table[key->key].lock);
- if (key_table[key->key].count == 1){
- key_table[key->key].destructor = NULL;
- key_table[key->key].count = 0;
- }
- release_sem(key_table[key->key].lock);
- } else {
- return APR_ENOMEM;
- }
- return APR_SUCCESS;
+ return APR_ENOTIMPL;
}
APR_DECLARE(apr_status_t) apr_threadkey_data_get(void **data, const char *key,
diff -urN apr-1.0.1.orig/user/unix/userinfo.c apr-1.0.1/user/unix/userinfo.c
--- apr-1.0.1.orig/user/unix/userinfo.c 2004-02-13 10:38:38.000000000 +0100
+++ apr-1.0.1/user/unix/userinfo.c 2004-12-17 15:19:11.000000000 +0100
@@ -31,6 +31,28 @@
#define PWBUF_SIZE 512
+/* on BeOS R5 (also for BONE systems?) getpwnam() is broken */
+#ifdef BEOS
+static struct passwd *beos_getpwnam(const char *name)
+{
+ struct passwd *p;
+ while ((p = getpwent()) != NULL) {
+ if (strcmp(p->pw_name, name) == 0)
+ break;
+ }
+ endpwent();
+
+ if (!p) {
+ errno = ENOENT;
+ /* probably not the correct error code, but that doesn't really
+ * matter anyway */
+ }
+ return p;
+}
+#define getpwnam beos_getpwnam
+#endif
+
+
static apr_status_t getpwnam_safe(const char *username,
struct passwd *pw,
char pwbuf[PWBUF_SIZE])