You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Philip Martin <ph...@codematters.co.uk> on 2002/02/02 21:34:44 UTC
[PATCH] APR turn off readonly/executable, add apr_file_attrs_get
Greg Stein <gs...@lyra.org> writes:
> (btw, for completeness, we'd also want ways to turn off readonly and to the
> executable state)
Here's a patch that does that, and provides a way to query the
attributes. It also makes the permission setting by apr_file_attrs_set
respect the umask of the process. So when removing readonly, the world
write flag, for example, only gets set if the umask allows.
Index: file_io/unix/filestat.c
===================================================================
RCS file: /home/cvspublic/apr/file_io/unix/filestat.c,v
retrieving revision 1.49
diff -u -r1.49 filestat.c
--- file_io/unix/filestat.c 1 Feb 2002 01:40:38 -0000 1.49
+++ file_io/unix/filestat.c 2 Feb 2002 20:32:36 -0000
@@ -109,6 +109,42 @@
*/
}
+/* This function is necessary because the APR mutex interface doesn't
+ * provide static mutex initialisation, i.e. there is nothing equivalent
+ * to PTHREAD_MUTEX_INITIALIZER. It's difficult to see how it could, given
+ * the need for a pool.
+ */
+static apr_thread_mutex_t *umask_mutex;
+apr_status_t apr_unix_setup_umask(apr_pool_t *cont)
+{
+ return apr_thread_mutex_create(&umask_mutex, APR_THREAD_MUTEX_DEFAULT, cont);
+}
+
+static apr_status_t get_umask(apr_fileperms_t *umask_perms, apr_pool_t *cont)
+{
+ apr_status_t status;
+ mode_t umask_raw;
+
+#ifdef APR_HAS_THREADS
+ status = apr_thread_mutex_lock(umask_mutex);
+ if (!APR_STATUS_IS_SUCCESS(status))
+ return status;
+#endif
+
+ umask_raw = umask(0);
+ umask(umask_raw);
+
+#ifdef APR_HAS_THREADS
+ status = apr_thread_mutex_unlock(umask_mutex);
+ if (!APR_STATUS_IS_SUCCESS(status))
+ return status;
+#endif
+
+ *umask_perms = apr_unix_mode2perms(umask_raw);
+
+ return APR_SUCCESS;
+}
+
APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo,
apr_int32_t wanted,
apr_file_t *thefile)
@@ -142,26 +178,84 @@
{
apr_status_t status;
apr_finfo_t finfo;
+ apr_fileperms_t mask;
+ apr_fileperms_t attr_perms;
status = apr_stat(&finfo, fname, APR_FINFO_PROT, cont);
if (!APR_STATUS_IS_SUCCESS(status))
return status;
if (attributes & APR_FILE_ATTR_READONLY) {
+ /* Make readonly by removing all write bits */
finfo.protection &= ~APR_UWRITE;
finfo.protection &= ~APR_GWRITE;
finfo.protection &= ~APR_WWRITE;
}
+ else {
+ /* Make non-readonly by setting all write bits permitted by umask */
+ attr_perms = APR_UWRITE | APR_GWRITE | APR_WWRITE;
+ status = get_umask(&mask, cont);
+ if (!APR_STATUS_IS_SUCCESS(status))
+ return status;
+ attr_perms &= ~mask;
+ finfo.protection |= attr_perms;
+ }
+
if (attributes & APR_FILE_ATTR_EXECUTABLE) {
- /* ### TODO: should this be umask'd? */
- finfo.protection |= APR_UEXECUTE;
- finfo.protection |= APR_GEXECUTE;
- finfo.protection |= APR_WEXECUTE;
+ /* Make executable by setting all execute bits permitted by umask */
+ attr_perms = APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE;
+ status = get_umask(&mask, cont);
+ if (!APR_STATUS_IS_SUCCESS(status))
+ return status;
+ attr_perms &= ~mask;
+ finfo.protection |= attr_perms;
+ }
+ else {
+ /* Make non-executable by removing all execute bits */
+ finfo.protection &= ~APR_UEXECUTE;
+ finfo.protection &= ~APR_GEXECUTE;
+ finfo.protection &= ~APR_WEXECUTE;
}
return apr_file_perms_set(fname, finfo.protection);
}
+APR_DECLARE(apr_status_t) apr_file_attrs_get(const char *fname,
+ apr_fileattrs_t *attributes,
+ apr_pool_t *cont)
+{
+ apr_status_t status;
+ apr_finfo_t finfo;
+ apr_fileperms_t perm_mask;
+ mode_t mask;
+
+ status = apr_stat(&finfo, fname, APR_FINFO_PROT, cont);
+ if (!APR_STATUS_IS_SUCCESS(status))
+ return status;
+
+ *attributes = 0;
+
+ /* All the write bits */
+ perm_mask = APR_UWRITE | APR_GWRITE | APR_WWRITE;
+
+ /* Claim readonly only if no write bits are set */
+ if (!(finfo.protection & perm_mask))
+ *attributes |= APR_FILE_ATTR_READONLY;
+
+ /* All the execute bits allowed by umask */
+ perm_mask = APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE;
+ status = get_umask(&mask, cont);
+ if (!APR_STATUS_IS_SUCCESS(status))
+ return status;
+ perm_mask &= ~mask;
+
+ /* Claim executable only if all execute bits are set */
+ if ((finfo.protection & perm_mask) == perm_mask)
+ *attributes |= APR_FILE_ATTR_EXECUTABLE;
+
+ return APR_SUCCESS;
+}
+
APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo,
const char *fname,
apr_int32_t wanted, apr_pool_t *cont)
Index: file_io/win32/filestat.c
===================================================================
RCS file: /home/cvspublic/apr/file_io/win32/filestat.c,v
retrieving revision 1.62
diff -u -r1.62 filestat.c
--- file_io/win32/filestat.c 1 Feb 2002 01:40:38 -0000 1.62
+++ file_io/win32/filestat.c 2 Feb 2002 20:32:36 -0000
@@ -618,3 +618,10 @@
{
return APR_ENOTIMPL;
}
+
+APR_DECLARE(apr_status_t) apr_file_attrs_get(const char *fname,
+ apr_fileattrs_t *attributes,
+ apr_pool_t *cont)
+{
+ return APR_ENOTIMPL;
+}
Index: include/apr_file_io.h
===================================================================
RCS file: /home/cvspublic/apr/include/apr_file_io.h,v
retrieving revision 1.117
diff -u -r1.117 apr_file_io.h
--- include/apr_file_io.h 1 Feb 2002 01:40:38 -0000 1.117
+++ include/apr_file_io.h 2 Feb 2002 20:32:37 -0000
@@ -578,7 +578,7 @@
/**
* Set attributes of the specified file.
* @param fname The full path to the file (using / on all systems)
- * @param attributes Or'd combination of
+ * @param attributes Or'd combination of attribute flags
* <PRE>
* APR_FILE_ATTR_READONLY - make the file readonly
* APR_FILE_ATTR_EXECUTABLE - make the file executable
@@ -588,11 +588,29 @@
* of the file permissions, because the operations to provide these
* attributes are platform specific and may involve more than simply
* setting permission bits.
+ * @remark If any of the attribute flags are not set in the parameter passed
+ * to this function, then those attributes will be removed from the file.
* @warning Platforms which do not implement this feature will return
* APR_ENOTIMPL.
*/
APR_DECLARE(apr_status_t) apr_file_attrs_set(const char *fname,
apr_fileattrs_t attributes,
+ apr_pool_t *cont);
+
+/**
+ * Get attributes of the specified file.
+ * @param fname The full path to the file (using / on all systems)
+ * @param attributes Pointer to variable in which to store the file's attributes
+ * @param cont the pool to use.
+ * @remark This function should be used in preference to explict examination
+ * of the file permissions, because the operations to provide these
+ * attributes are platform specific and may involve more than simply
+ * setting permission bits.
+ * @warning Platforms which do not implement this feature will return
+ * APR_ENOTIMPL.
+ */
+APR_DECLARE(apr_status_t) apr_file_attrs_get(const char *fname,
+ apr_fileattrs_t *attributes,
apr_pool_t *cont);
/**
Index: include/arch/unix/fileio.h
===================================================================
RCS file: /home/cvspublic/apr/include/arch/unix/fileio.h,v
retrieving revision 1.37
diff -u -r1.37 fileio.h
--- include/arch/unix/fileio.h 21 Nov 2001 04:21:04 -0000 1.37
+++ include/arch/unix/fileio.h 2 Feb 2002 20:32:37 -0000
@@ -154,5 +154,7 @@
mode_t apr_unix_perms2mode(apr_fileperms_t perms);
apr_fileperms_t apr_unix_mode2perms(mode_t mode);
+apr_status_t apr_unix_setup_umask(apr_pool_t *cont);
+
#endif /* ! FILE_IO_H */
Index: misc/unix/start.c
===================================================================
RCS file: /home/cvspublic/apr/misc/unix/start.c,v
retrieving revision 1.61
diff -u -r1.61 start.c
--- misc/unix/start.c 1 Feb 2002 17:27:38 -0000 1.61
+++ misc/unix/start.c 2 Feb 2002 20:32:37 -0000
@@ -132,6 +132,11 @@
#endif
apr_signal_init(pool);
+#if !defined(BEOS) && !defined(OS2) && !defined(WIN32)
+ if ((status = apr_unix_setup_umask(pool)) != APR_SUCCESS) {
+ return status;
+ }
+#endif
return APR_SUCCESS;
}
--
Philip
Re: [PATCH] APR turn off readonly/executable, add apr_file_attrs_get
Posted by Philip Martin <ph...@codematters.co.uk>.
Philip Martin <ph...@codematters.co.uk> writes:
> > > Shouldn't this be
> > > #if APR_HAS_THREADS
> > >
> > > i.e. isn't it always defined to either 0 or 1.
> >
> >
> > Yes, it should be.
>
> OK. I can make the mutex creation conditional as well.
Corrected patch.
* Adds apr_file_attrs_get to query file attributes.
* Modifies apr_file_attrs_set to allow removing of readonly/executable
attribute.
* Makes apr_file_attrs_set only set those permissions allowed by the
umask.
* Adds apr_unix_setup_umask and get_umask to enable apr_file_attrs_set
to query the current umask.
Index: file_io/unix/filestat.c
===================================================================
RCS file: /home/cvspublic/apr/file_io/unix/filestat.c,v
retrieving revision 1.49
diff -u -r1.49 filestat.c
--- file_io/unix/filestat.c 1 Feb 2002 01:40:38 -0000 1.49
+++ file_io/unix/filestat.c 3 Feb 2002 02:59:15 -0000
@@ -109,6 +109,48 @@
*/
}
+/* This function is necessary because the APR mutex interface doesn't
+ * provide static mutex initialisation, i.e. there is nothing equivalent
+ * to PTHREAD_MUTEX_INITIALIZER. It's difficult to see how it could, given
+ * the need for a pool.
+ */
+#if APR_HAS_THREADS
+static apr_thread_mutex_t *umask_mutex;
+#endif
+apr_status_t apr_unix_setup_umask(apr_pool_t *cont)
+{
+#if APR_HAS_THREADS
+ return apr_thread_mutex_create(&umask_mutex, APR_THREAD_MUTEX_DEFAULT, cont);
+#else
+ return APR_SUCCESS;
+#endif
+}
+
+static apr_status_t get_umask(apr_fileperms_t *umask_perms, apr_pool_t *cont)
+{
+ apr_status_t status;
+ mode_t umask_raw;
+
+#if APR_HAS_THREADS
+ status = apr_thread_mutex_lock(umask_mutex);
+ if (!APR_STATUS_IS_SUCCESS(status))
+ return status;
+#endif
+
+ umask_raw = umask(0);
+ umask(umask_raw);
+
+#if APR_HAS_THREADS
+ status = apr_thread_mutex_unlock(umask_mutex);
+ if (!APR_STATUS_IS_SUCCESS(status))
+ return status;
+#endif
+
+ *umask_perms = apr_unix_mode2perms(umask_raw);
+
+ return APR_SUCCESS;
+}
+
APR_DECLARE(apr_status_t) apr_file_info_get(apr_finfo_t *finfo,
apr_int32_t wanted,
apr_file_t *thefile)
@@ -142,26 +184,84 @@
{
apr_status_t status;
apr_finfo_t finfo;
+ apr_fileperms_t mask;
+ apr_fileperms_t attr_perms;
status = apr_stat(&finfo, fname, APR_FINFO_PROT, cont);
if (!APR_STATUS_IS_SUCCESS(status))
return status;
if (attributes & APR_FILE_ATTR_READONLY) {
+ /* Make readonly by removing all write bits */
finfo.protection &= ~APR_UWRITE;
finfo.protection &= ~APR_GWRITE;
finfo.protection &= ~APR_WWRITE;
}
+ else {
+ /* Make non-readonly by setting all write bits permitted by umask */
+ attr_perms = APR_UWRITE | APR_GWRITE | APR_WWRITE;
+ status = get_umask(&mask, cont);
+ if (!APR_STATUS_IS_SUCCESS(status))
+ return status;
+ attr_perms &= ~mask;
+ finfo.protection |= attr_perms;
+ }
+
if (attributes & APR_FILE_ATTR_EXECUTABLE) {
- /* ### TODO: should this be umask'd? */
- finfo.protection |= APR_UEXECUTE;
- finfo.protection |= APR_GEXECUTE;
- finfo.protection |= APR_WEXECUTE;
+ /* Make executable by setting all execute bits permitted by umask */
+ attr_perms = APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE;
+ status = get_umask(&mask, cont);
+ if (!APR_STATUS_IS_SUCCESS(status))
+ return status;
+ attr_perms &= ~mask;
+ finfo.protection |= attr_perms;
+ }
+ else {
+ /* Make non-executable by removing all execute bits */
+ finfo.protection &= ~APR_UEXECUTE;
+ finfo.protection &= ~APR_GEXECUTE;
+ finfo.protection &= ~APR_WEXECUTE;
}
return apr_file_perms_set(fname, finfo.protection);
}
+APR_DECLARE(apr_status_t) apr_file_attrs_get(const char *fname,
+ apr_fileattrs_t *attributes,
+ apr_pool_t *cont)
+{
+ apr_status_t status;
+ apr_finfo_t finfo;
+ apr_fileperms_t perm_mask;
+ mode_t mask;
+
+ status = apr_stat(&finfo, fname, APR_FINFO_PROT, cont);
+ if (!APR_STATUS_IS_SUCCESS(status))
+ return status;
+
+ *attributes = 0;
+
+ /* All the write bits */
+ perm_mask = APR_UWRITE | APR_GWRITE | APR_WWRITE;
+
+ /* Claim readonly only if no write bits are set */
+ if (!(finfo.protection & perm_mask))
+ *attributes |= APR_FILE_ATTR_READONLY;
+
+ /* All the execute bits allowed by umask */
+ perm_mask = APR_UEXECUTE | APR_GEXECUTE | APR_WEXECUTE;
+ status = get_umask(&mask, cont);
+ if (!APR_STATUS_IS_SUCCESS(status))
+ return status;
+ perm_mask &= ~mask;
+
+ /* Claim executable only if all execute bits are set */
+ if ((finfo.protection & perm_mask) == perm_mask)
+ *attributes |= APR_FILE_ATTR_EXECUTABLE;
+
+ return APR_SUCCESS;
+}
+
APR_DECLARE(apr_status_t) apr_stat(apr_finfo_t *finfo,
const char *fname,
apr_int32_t wanted, apr_pool_t *cont)
Index: file_io/win32/filestat.c
===================================================================
RCS file: /home/cvspublic/apr/file_io/win32/filestat.c,v
retrieving revision 1.62
diff -u -r1.62 filestat.c
--- file_io/win32/filestat.c 1 Feb 2002 01:40:38 -0000 1.62
+++ file_io/win32/filestat.c 3 Feb 2002 02:59:15 -0000
@@ -618,3 +618,10 @@
{
return APR_ENOTIMPL;
}
+
+APR_DECLARE(apr_status_t) apr_file_attrs_get(const char *fname,
+ apr_fileattrs_t *attributes,
+ apr_pool_t *cont)
+{
+ return APR_ENOTIMPL;
+}
Index: include/apr_file_io.h
===================================================================
RCS file: /home/cvspublic/apr/include/apr_file_io.h,v
retrieving revision 1.117
diff -u -r1.117 apr_file_io.h
--- include/apr_file_io.h 1 Feb 2002 01:40:38 -0000 1.117
+++ include/apr_file_io.h 3 Feb 2002 02:59:15 -0000
@@ -578,7 +578,7 @@
/**
* Set attributes of the specified file.
* @param fname The full path to the file (using / on all systems)
- * @param attributes Or'd combination of
+ * @param attributes Or'd combination of attribute flags
* <PRE>
* APR_FILE_ATTR_READONLY - make the file readonly
* APR_FILE_ATTR_EXECUTABLE - make the file executable
@@ -588,11 +588,29 @@
* of the file permissions, because the operations to provide these
* attributes are platform specific and may involve more than simply
* setting permission bits.
+ * @remark If any of the attribute flags are not set in the parameter passed
+ * to this function, then those attributes will be removed from the file.
* @warning Platforms which do not implement this feature will return
* APR_ENOTIMPL.
*/
APR_DECLARE(apr_status_t) apr_file_attrs_set(const char *fname,
apr_fileattrs_t attributes,
+ apr_pool_t *cont);
+
+/**
+ * Get attributes of the specified file.
+ * @param fname The full path to the file (using / on all systems)
+ * @param attributes Pointer to variable in which to store the file's attributes
+ * @param cont the pool to use.
+ * @remark This function should be used in preference to explict examination
+ * of the file permissions, because the operations to provide these
+ * attributes are platform specific and may involve more than simply
+ * setting permission bits.
+ * @warning Platforms which do not implement this feature will return
+ * APR_ENOTIMPL.
+ */
+APR_DECLARE(apr_status_t) apr_file_attrs_get(const char *fname,
+ apr_fileattrs_t *attributes,
apr_pool_t *cont);
/**
Index: include/arch/unix/fileio.h
===================================================================
RCS file: /home/cvspublic/apr/include/arch/unix/fileio.h,v
retrieving revision 1.37
diff -u -r1.37 fileio.h
--- include/arch/unix/fileio.h 21 Nov 2001 04:21:04 -0000 1.37
+++ include/arch/unix/fileio.h 3 Feb 2002 02:59:15 -0000
@@ -154,5 +154,7 @@
mode_t apr_unix_perms2mode(apr_fileperms_t perms);
apr_fileperms_t apr_unix_mode2perms(mode_t mode);
+apr_status_t apr_unix_setup_umask(apr_pool_t *cont);
+
#endif /* ! FILE_IO_H */
Index: misc/unix/start.c
===================================================================
RCS file: /home/cvspublic/apr/misc/unix/start.c,v
retrieving revision 1.61
diff -u -r1.61 start.c
--- misc/unix/start.c 1 Feb 2002 17:27:38 -0000 1.61
+++ misc/unix/start.c 3 Feb 2002 02:59:15 -0000
@@ -132,6 +132,11 @@
#endif
apr_signal_init(pool);
+#if !defined(BEOS) && !defined(OS2) && !defined(WIN32)
+ if ((status = apr_unix_setup_umask(pool)) != APR_SUCCESS) {
+ return status;
+ }
+#endif
return APR_SUCCESS;
}
--
Philip
Re: [PATCH] APR turn off readonly/executable, add apr_file_attrs_get
Posted by Philip Martin <ph...@codematters.co.uk>.
Cliff Woolley <cl...@yahoo.com> writes:
> On Sat, 2 Feb 2002, Kevin Pilch-Bisson wrote:
>
> > On Sat, Feb 02, 2002 at 08:34:44PM +0000, Philip Martin wrote:
> > > +#ifdef APR_HAS_THREADS
> > > + status = apr_thread_mutex_lock(umask_mutex);
> > > + if (!APR_STATUS_IS_SUCCESS(status))
> > > + return status;
> > > +#endif
> >
> > Shouldn't this be
> > #if APR_HAS_THREADS
> >
> > i.e. isn't it always defined to either 0 or 1.
>
>
> Yes, it should be.
OK. I can make the mutex creation conditional as well.
--
Philip
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Re: [PATCH] APR turn off readonly/executable, add apr_file_attrs_get
Posted by Philip Martin <ph...@codematters.co.uk>.
Cliff Woolley <cl...@yahoo.com> writes:
> On Sat, 2 Feb 2002, Kevin Pilch-Bisson wrote:
>
> > On Sat, Feb 02, 2002 at 08:34:44PM +0000, Philip Martin wrote:
> > > +#ifdef APR_HAS_THREADS
> > > + status = apr_thread_mutex_lock(umask_mutex);
> > > + if (!APR_STATUS_IS_SUCCESS(status))
> > > + return status;
> > > +#endif
> >
> > Shouldn't this be
> > #if APR_HAS_THREADS
> >
> > i.e. isn't it always defined to either 0 or 1.
>
>
> Yes, it should be.
OK. I can make the mutex creation conditional as well.
--
Philip
Re: [PATCH] APR turn off readonly/executable, add apr_file_attrs_get
Posted by Cliff Woolley <cl...@yahoo.com>.
On Sat, 2 Feb 2002, Kevin Pilch-Bisson wrote:
> On Sat, Feb 02, 2002 at 08:34:44PM +0000, Philip Martin wrote:
> > +#ifdef APR_HAS_THREADS
> > + status = apr_thread_mutex_lock(umask_mutex);
> > + if (!APR_STATUS_IS_SUCCESS(status))
> > + return status;
> > +#endif
>
> Shouldn't this be
> #if APR_HAS_THREADS
>
> i.e. isn't it always defined to either 0 or 1.
Yes, it should be.
--Cliff
--------------------------------------------------------------
Cliff Woolley
cliffwoolley@yahoo.com
Charlottesville, VA
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Re: [PATCH] APR turn off readonly/executable, add apr_file_attrs_get
Posted by Cliff Woolley <cl...@yahoo.com>.
On Sat, 2 Feb 2002, Kevin Pilch-Bisson wrote:
> On Sat, Feb 02, 2002 at 08:34:44PM +0000, Philip Martin wrote:
> > +#ifdef APR_HAS_THREADS
> > + status = apr_thread_mutex_lock(umask_mutex);
> > + if (!APR_STATUS_IS_SUCCESS(status))
> > + return status;
> > +#endif
>
> Shouldn't this be
> #if APR_HAS_THREADS
>
> i.e. isn't it always defined to either 0 or 1.
Yes, it should be.
--Cliff
--------------------------------------------------------------
Cliff Woolley
cliffwoolley@yahoo.com
Charlottesville, VA
Re: [PATCH] APR turn off readonly/executable, add apr_file_attrs_get
Posted by Kevin Pilch-Bisson <ke...@pilch-bisson.net>.
On Sat, Feb 02, 2002 at 08:34:44PM +0000, Philip Martin wrote:
> +#ifdef APR_HAS_THREADS
> + status = apr_thread_mutex_lock(umask_mutex);
> + if (!APR_STATUS_IS_SUCCESS(status))
> + return status;
> +#endif
Shouldn't this be
#if APR_HAS_THREADS
i.e. isn't it always defined to either 0 or 1.
And the rest below...
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Kevin Pilch-Bisson http://www.pilch-bisson.net
"Historically speaking, the presences of wheels in Unix
has never precluded their reinvention." - Larry Wall
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Re: [PATCH] APR turn off readonly/executable, add apr_file_attrs_get
Posted by Kevin Pilch-Bisson <ke...@pilch-bisson.net>.
On Sat, Feb 02, 2002 at 08:34:44PM +0000, Philip Martin wrote:
> +#ifdef APR_HAS_THREADS
> + status = apr_thread_mutex_lock(umask_mutex);
> + if (!APR_STATUS_IS_SUCCESS(status))
> + return status;
> +#endif
Shouldn't this be
#if APR_HAS_THREADS
i.e. isn't it always defined to either 0 or 1.
And the rest below...
--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Kevin Pilch-Bisson http://www.pilch-bisson.net
"Historically speaking, the presences of wheels in Unix
has never precluded their reinvention." - Larry Wall
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~