This patch adds an apr_file_setaside() function that moves an apr_file_t from one pool to another without doing any dup(2) or mmap(2) operations.
The motivation behind this is to provide the foundation for setting aside small files in core_output_filter()'s keepalive code without having to read in their contents. Can someone with a win32 build environment please let me know if the win32 version looks okay? Thanks, --Brian
Index: include/apr_file_io.h =================================================================== RCS file: /home/cvs/apr/include/apr_file_io.h,v retrieving revision 1.128 diff -u -r1.128 apr_file_io.h --- include/apr_file_io.h 29 Jun 2002 22:53:30 -0000 1.128 +++ include/apr_file_io.h 29 Jun 2002 23:55:20 -0000 @@ -458,6 +458,21 @@ apr_pool_t *p); /** + * move the specified file descriptor to a new pool + * @param new_file Pointer in which to return the new apr_file_t + * @param old_file The file to move + * @param p The pool to which the descriptor is to be moved + * @remark Unlike apr_file_dup2(), this function doesn't do an + * OS dup() operation on the underlying descriptor; it just + * moves the descriptor's apr_file_t wrapper to a new pool. + * @remark The new pool need not be an ancestor of old_file's pool. + * @remark After calling this function, old_file may not be used + */ +APR_DECLARE(apr_status_t) apr_file_setaside(apr_file_t **new_file, + apr_file_t *old_file, + apr_pool_t *p); + +/** * Move the read/write file offset to a specified byte within a file. * @param thefile The file descriptor * @param where How to move the pointer, one of: Index: file_io/unix/filedup.c =================================================================== RCS file: /home/cvs/apr/file_io/unix/filedup.c,v retrieving revision 1.48 diff -u -r1.48 filedup.c --- file_io/unix/filedup.c 8 Jun 2002 22:32:11 -0000 1.48 +++ file_io/unix/filedup.c 29 Jun 2002 23:55:20 -0000 @@ -148,3 +148,38 @@ #endif } +APR_DECLARE(apr_status_t) apr_file_setaside(apr_file_t **new_file, + apr_file_t *old_file, + apr_pool_t *p) +{ + *new_file = (apr_file_t *)apr_palloc(p, sizeof(apr_file_t)); + memcpy(*new_file, old_file, sizeof(apr_file_t)); + (*new_file)->pool = p; + if (old_file->buffered) { + (*new_file)->buffer = apr_palloc(p, APR_FILE_BUFSIZE); + if (old_file->direction == 1) { + memcpy((*new_file)->buffer, old_file->buffer, old_file->bufpos); + } + else { + memcpy((*new_file)->buffer, old_file->buffer, old_file->dataRead); + } + if (old_file->thlock) { + apr_thread_mutex_create(&((*new_file)->thlock), + APR_THREAD_MUTEX_DEFAULT, p); + apr_thread_mutex_destroy(old_file->thlock); + } + } + if (old_file->fname) { + (*new_file)->fname = apr_pstrdup(p, old_file->fname); + } + if (!(old_file->flags & APR_FILE_NOCLEANUP)) { + apr_pool_cleanup_register(p, (void *)(*new_file), + apr_unix_file_cleanup, + apr_unix_file_cleanup); + } + + old_file->filedes = -1; + apr_pool_cleanup_kill(old_file->pool, (void *)old_file, + apr_unix_file_cleanup); + return APR_SUCCESS; +} Index: file_io/win32/filedup.c =================================================================== RCS file: /home/cvs/apr/file_io/win32/filedup.c,v retrieving revision 1.45 diff -u -r1.45 filedup.c --- file_io/win32/filedup.c 20 Mar 2002 08:54:42 -0000 1.45 +++ file_io/win32/filedup.c 29 Jun 2002 23:55:20 -0000 @@ -150,3 +150,38 @@ #endif /* !defined(_WIN32_WCE) */ } +APR_DECLARE(apr_status_t) apr_file_setaside(apr_file_t **new_file, + apr_file_t *old_file, + apr_pool_t *p) +{ + *new_file = (apr_file_t *)apr_palloc(p, sizeof(apr_file_t)); + memcpy(*new_file, old_file, sizeof(apr_file_t)); + (*new_file)->pool = p; + if (old_file->buffered) { + (*new_file)->buffer = apr_palloc(p, APR_FILE_BUFSIZE); + if (old_file->direction == 1) { + memcpy((*new_file)->buffer, old_file->buffer, old_file->bufpos); + } + else { + memcpy((*new_file)->buffer, old_file->buffer, old_file->dataRead); + } + if (old_file->thlock) { + apr_thread_mutex_create(&((*new_file)->thlock), + APR_THREAD_MUTEX_DEFAULT, p); + apr_thread_mutex_destroy(old_file->thlock); + } + } + if (old_file->fname) { + (*new_file)->fname = apr_pstrdup(p, old_file->fname); + } + if (!(old_file->flags & APR_FILE_NOCLEANUP)) { + apr_pool_cleanup_register(p, (void *)(*new_file), + file_cleanup, + file_cleanup); + } + + old_file->filedes = -1; + apr_pool_cleanup_kill(old_file->pool, (void *)old_file, + file_cleanup); + return APR_SUCCESS; +}