OK, it's not actually a patch, because I'm not sure where it ought to
live. I've attached it below.
The function apr_dir_remove() won't work on a non-empty directory, so
this routine fills the gap. It's equivalent to 'rm -rf'.
This routine currently lives in a Subversion library. I'd like to
move it into apr_file_io.h, but I'm not sure where the actual code
should live. It's implemented using nothing but other apr file
routines; does this mean duplicating the code into file_io/unix,
file_io/win32, file_io/os2?
---------------
apr_status_t
apr_dir_remove_recursively (const char *path, apr_pool_t *pool)
{
apr_status_t status;
apr_dir_t *this_dir;
apr_finfo_t this_entry;
apr_pool_t *subpool;
apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME;
status = apr_pool_create (&subpool, pool);
if (! (APR_STATUS_IS_SUCCESS (status))) return status;
status = apr_dir_open (&this_dir, path, subpool);
if (! (APR_STATUS_IS_SUCCESS (status))) return status;
for (status = apr_dir_read (&this_entry, flags, this_dir);
APR_STATUS_IS_SUCCESS (status);
status = apr_dir_read (&this_entry, flags, this_dir))
{
char *fullpath = apr_pstrcat (subpool, path, "/", this_entry.name, NULL);
if (this_entry.filetype == APR_DIR)
{
if ((strcmp (this_entry.name, ".") == 0)
|| (strcmp (this_entry.name, "..") == 0))
continue;
status = apr_dir_remove_recursively (fullpath, subpool);
if (! (APR_STATUS_IS_SUCCESS (status))) return status;
}
else if (this_entry.filetype == APR_REG)
{
status = apr_file_remove (fullpath, subpool);
if (! (APR_STATUS_IS_SUCCESS (status))) return status;
}
}
if (! (APR_STATUS_IS_ENOENT (status)))
return status;
else
{
status = apr_dir_close (this_dir);
if (! (APR_STATUS_IS_SUCCESS (status))) return status;
}
status = apr_dir_remove (path, subpool);
if (! (APR_STATUS_IS_SUCCESS (status))) return status;
apr_pool_destroy (subpool);
return APR_SUCCESS;
}