summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68>2003-03-19 02:26:34 +0000
committerwrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68>2003-03-19 02:26:34 +0000
commit98c6ca66d6c3a1cc8fe11c97a88de25ba10e0bf1 (patch)
treed45c0d6f53baf38dee06ca131fe7e257288c71a8
parentc9d35ca0dd0a5b099ebdb68e46cc3990e9e7e2be (diff)
downloadlibapr-98c6ca66d6c3a1cc8fe11c97a88de25ba10e0bf1.tar.gz
Fix bug #4 of the evening; it is altogether possible for the user to have
called apr_file_close() against the original handle, and then invoke apr_file_dup2(). However, in that case the apr_file_t has already been unregistered from the cleanups. Always register a cleanup within _file_dup(), yet kill any remaining cleanup for the existing apr_file_t in the apr_file_dup2() situation. This also prevents double-registration, but in a more robust manner. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@64426 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--file_io/unix/filedup.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/file_io/unix/filedup.c b/file_io/unix/filedup.c
index 830840bf3..c5a6cd57b 100644
--- a/file_io/unix/filedup.c
+++ b/file_io/unix/filedup.c
@@ -122,6 +122,9 @@ static apr_status_t _file_dup(apr_file_t **new_file,
*/
(*new_file)->flags = old_file->flags & ~APR_INHERIT;
+ apr_pool_cleanup_register((*new_file)->pool, (void *)(*new_file),
+ apr_unix_file_cleanup, apr_unix_file_cleanup);
+
return APR_SUCCESS;
}
@@ -131,21 +134,22 @@ APR_DECLARE(apr_status_t) apr_file_dup(apr_file_t **new_file,
apr_status_t rv;
rv = _file_dup(new_file, old_file, p, 1);
- if (rv != APR_SUCCESS)
- return rv;
-
- /* we do this here as we don't want to double register an existing
- * apr_file_t for cleanup
- */
- apr_pool_cleanup_register((*new_file)->pool, (void *)(*new_file),
- apr_unix_file_cleanup, apr_unix_file_cleanup);
return rv;
-
}
APR_DECLARE(apr_status_t) apr_file_dup2(apr_file_t *new_file,
apr_file_t *old_file, apr_pool_t *p)
{
+ apr_status_t rv;
+
+ /* an existing apr_file_t may already be closed, and therefore
+ * have no cleanup remaining; but we don't want to double-register
+ * the same cleanup in _file_dup. Kill the existing cleanup before
+ * invoking _file_dup to the existing new_file.
+ */
+ apr_pool_cleanup_kill(new_file->pool, (void *)(new_file),
+ apr_unix_file_cleanup);
+
return _file_dup(&new_file, old_file, p, 2);
}