As posted here:
http://www.mail-archive.com/[email protected]/msg17650.html
I've implemented an iterative apr_dir_remove_recursive
It's now attached as fileutil.c

This is based only on APR functions so a single entry of this
implementation should do it for all systems.

I'm not sure where it's best place is inside the structure of APR, so
any suggestions are welcome :)

--
Lucian Adrian Grijincu
#include "apr_general.h"
#include "apr.h"
#include "apr_file_io.h"
#include "apr_errno.h"
#include "apr_strings.h"

#define APR_DIR_REMOVE_RECURSIVELY_ARRSIZE (6)  /*what would be a propper value? */
#define PATH_SEPARATOR '/'      /*is one defined in a header somewhere else ? */

apr_status_t
apr_dir_remove_recursive(const char *param_path, apr_pool_t * pool)
{
    apr_status_t status, retcode, dirstatus;
    apr_dir_t *this_dir;
    apr_finfo_t this_entry;
    apr_pool_t *array_pool, *loop_pool;
    apr_array_header_t *arr;
    apr_int32_t flags = APR_FINFO_TYPE | APR_FINFO_NAME;
    char *dir_path, *file_path;
    int dir_is_empty;

    retcode = APR_SUCCESS;
    status = apr_pool_create(&array_pool, pool);
    if (status != APR_SUCCESS) {
        return status;
    }
    status = apr_pool_create(&loop_pool, pool);
    if (status != APR_SUCCESS) {
        apr_pool_destroy(array_pool);
        return status;
    }


    arr = apr_array_make(array_pool, APR_DIR_REMOVE_RECURSIVELY_ARRSIZE,
                         sizeof(const char *));
    if (arr == NULL) {
        apr_pool_destroy(array_pool);
        apr_pool_destroy(loop_pool);
        return APR_ENOMEM;
    }
    *(const char **) apr_array_push(arr) = param_path;



    while (!apr_is_empty_array(arr)) {
        apr_pool_clear(loop_pool);
        dir_path = apr_array_pstrcat(loop_pool, arr, PATH_SEPARATOR);
        if (dir_path == NULL) {
            retcode = APR_ENOMEM;
            break;
        }

        dir_is_empty = 1;

        dirstatus = apr_dir_open(&this_dir, dir_path, loop_pool);
        if (dirstatus != APR_SUCCESS) {
            retcode = dirstatus;
        }
        else {
            for (dirstatus = apr_dir_read(&this_entry, flags, this_dir);
                 dirstatus == APR_SUCCESS;
                 dirstatus = apr_dir_read(&this_entry, flags, this_dir)) {

                if (this_entry.filetype == APR_DIR) {
                    if (this_entry.name[0] == '.'
                        && (this_entry.name[1] == '\0'
                            || (this_entry.name[1] == '.'
                                && this_entry.name[2] == '\0')))
                        continue;

                    *(const char **) apr_array_push(arr) =
                        apr_pstrdup(array_pool, this_entry.name);
                    dir_is_empty = 0;
                    break;
                }
                else {
                    file_path =
                        apr_pstrcat(loop_pool, dir_path, PATH_SEPARATOR,
                                    this_entry.name, NULL);
                    status = apr_file_remove(file_path, loop_pool);
                    if ((status != APR_SUCCESS) && (retcode != APR_SUCCESS)) {
                        retcode = status;
                    }
                }
            }

            if (!(APR_STATUS_IS_ENOENT(dirstatus))
                && (retcode != APR_SUCCESS)) {
                retcode = dirstatus;
            }
            dirstatus = apr_dir_close(this_dir);
            if ((dirstatus != APR_SUCCESS) && (retcode != APR_SUCCESS)) {
                retcode = dirstatus;
            }
        }

        if (dir_is_empty) {
            dirstatus = apr_dir_remove(dir_path, loop_pool);
            if ((dirstatus != APR_SUCCESS) && (retcode != APR_SUCCESS)) {
                retcode = dirstatus;
            }
            apr_array_pop(arr);
        }
    }

    apr_pool_destroy(array_pool);
    apr_pool_destroy(loop_pool);
    return retcode;


}
#include <apr_file_io.h>
#include <apr_file_info.h>
#include <apr_pools.h>
#include <errno.h>
apr_status_t
apr_dir_remove_recursive(const char *param_path, apr_pool_t * pool);

int main(int argn, char * argv[])
{
	const char *path = "/tmp/dir1/dir2/dir3";
	apr_status_t rc = 0;
	apr_pool_t * pool;
	apr_finfo_t finfo;


	apr_initialize();
	atexit(apr_terminate);
	rc |= apr_pool_create(&pool, NULL);
	rc |= apr_dir_make_recursive (path, APR_UREAD|APR_UWRITE|APR_UEXECUTE|APR_GSETID|APR_GREAD|APR_GWRITE|APR_GEXECUTE|APR_WREAD|APR_WWRITE|APR_WEXECUTE, pool);

	rc = apr_dir_remove_recursive("/tmp/dir1", pool);
	if(rc)
	{
		printf("apr_dir_remove_recursive failed[%d]\n", rc);
		return rc;
	}

	rc = apr_stat(&finfo, path, APR_FINFO_NAME|APR_FINFO_DIRENT, pool);
	if(APR_ENOENT != rc)
	{
		errno = rc;
		perror("");
		printf("apr_stat failed[%d]\n", rc);
		return rc;
	}
	return 0;
}


 	    


Attachment: Makefile
Description: Binary data

Reply via email to