joes 2004/07/23 10:49:14
Modified: src apreq.c
Log:
The apr_pools.c implementation of run_cleanups makes it unsafe to remove
other pool cleanups within a cleanup handler. So we drop apr_file_close and
register our cleanup before calling apr_file_mktemp, so it'll actually run last.
Revision Changes Path
1.48 +21 -13 httpd-apreq-2/src/apreq.c
Index: apreq.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -r1.47 -r1.48
--- apreq.c 23 Jul 2004 17:22:54 -0000 1.47
+++ apreq.c 23 Jul 2004 17:49:14 -0000 1.48
@@ -737,16 +737,15 @@
}
+struct cleanup_data {
+ const char *fname;
+ apr_pool_t *pool;
+};
-static apr_status_t apreq_file_cleanup(void *f)
+static apr_status_t apreq_file_cleanup(void *d)
{
- apr_file_t *file = f;
- apr_finfo_t finfo;
-
- apr_file_info_get(&finfo, APR_FINFO_NAME, file);
-
- apr_file_close(file); /*deregister any other pool cleanups */
- return apr_file_remove(finfo.fname, finfo.pool);
+ struct cleanup_data *data = d;
+ return apr_file_remove(data->fname, data->pool);
}
/*
@@ -766,6 +765,7 @@
{
apr_status_t rc;
char *tmpl;
+ struct cleanup_data *data;
if (path == NULL) {
rc = apr_temp_dir_get(&path, pool);
@@ -778,15 +778,23 @@
if (rc != APR_SUCCESS)
return rc;
+ data = apr_palloc(pool, sizeof *data);
+ /* cleanups are LIFO, so this one will run just after
+ the cleanup set by mktemp */
+ apr_pool_cleanup_register(pool, data,
+ apreq_file_cleanup, apreq_file_cleanup);
+
rc = apr_file_mktemp(fp, tmpl, /* NO APR_DELONCLOSE! see comment above */
APR_CREATE | APR_READ | APR_WRITE
| APR_EXCL | APR_BINARY, pool);
- /* cleanups are LIFO, so this one will run first, thus removing the
- one just set by mktemp */
- apr_pool_cleanup_register(pool, (void *)(*fp),
- apreq_file_cleanup, apreq_file_cleanup);
-
+ if (rc == APR_SUCCESS) {
+ apr_file_name_get(&data->fname, *fp);
+ data->pool = pool;
+ }
+ else {
+ apr_pool_cleanup_kill(pool, data, apreq_file_cleanup);
+ }
return rc;
}