diff options
author | wrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68> | 2003-03-19 02:26:34 +0000 |
---|---|---|
committer | wrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68> | 2003-03-19 02:26:34 +0000 |
commit | 98c6ca66d6c3a1cc8fe11c97a88de25ba10e0bf1 (patch) | |
tree | d45c0d6f53baf38dee06ca131fe7e257288c71a8 /file_io | |
parent | c9d35ca0dd0a5b099ebdb68e46cc3990e9e7e2be (diff) | |
download | libapr-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
Diffstat (limited to 'file_io')
-rw-r--r-- | file_io/unix/filedup.c | 22 |
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); } |