Hi,

I've modified the version posted earlier(2001) by Ben Collins-Sussman in
this way:

    * if at any point some function fails (deleting a file, dir, reading
      the dir ... etc) we save the error code returned and continue to
      remove the rest of the files
    * we don't check for (this_entry.filetype == APR_REG) before
      deleting a file. We unlink all files that are not directories.
      Please correct me if this approach is wrong.
    * apr_dir_read internally calls lstat to get the filetype so if
      there are symlinks to directories, a recursive delete will not end
      up walking out of the tree being deleted. We delete symlinks as if
      they were regular files.
    * we return the *first* error encountered (I can change this to
      return the last error encountered (removing all "&& (retcode !=
      APR_SUCCESS)")
    * the subpool is destroyed before returning (I know this isn't
      necessary, but I don't see why it would hurt :) )
    * I'm testing for this_entry.fname, not this_entry.name.

It uses only APR functions so, if APR lives up to it's name, this should
be a portable function.
Note: I haven't tested it on anything else but an Ubuntu 6.10.
I'd really like to see this functionality APR, and I don;t think I'm the
only one ...

Lucian Adrian Grijincu wrote:
> Hi,
> I've seen on the mailing list archive a discussion about
> apr_dir_remove_recursively from 2001 with this recommendation:
>
>
>> Subject:    Re: [PATCH] apr_dir_remove_recursively
>> From:       "William A. Rowe, Jr." <admin () rowe-clan ! net>
>> Date:       2001-05-22 22:32:10
>>
>> No, don't duplicate.  Please create a file_io/unix/fileutil.c source for
>> functions that are common to all platforms (since they are implemented
>> in terms of apr itself.)
>>
>> Should do the trick.
>>
>> Bill
>>
>
> I've checked HEAD and there isn't any such function or file.
> Did someone forget to post the file or there is a strong reason why it
> was dropped?
>
> Best regards,
> Lucian Adrian Grijincu
>
>


--
Best regards,

Lucian Adrian Grijincu
Software Developer
Avira Soft srl

[EMAIL PROTECTED]
http://www.avira.com




-- 
Best regards,

Lucian Adrian Grijincu
Software Developer
Avira Soft srl

[EMAIL PROTECTED]
http://www.avira.com
-----------------------------------------------------------
DISCLAIMER: This message is confidential. It may also be
privileged or otherwise protected by work product immunity
or other legal rules. If you have received it by mistake
please let us know by reply and then delete it from your
system; you should not copy the message or disclose its
contents to anyone.
-----------------------------------------------------------

apr_status_t apr_dir_remove_recursively(const char *path, apr_pool_t *pool)
{
    apr_status_t status, retcode;
    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 (status != APR_SUCCESS)  {
        return status;
    }

    retcode = APR_SUCCESS;
    status = apr_dir_open (&this_dir, path, subpool);
    if (status != APR_SUCCESS) {
        retcode = status;
    }
    else {
        for (status = apr_dir_read (&this_entry, flags, this_dir);
             status == APR_SUCCESS;
             status = apr_dir_read (&this_entry, flags, this_dir)) {
            char *fullpath = apr_pstrcat (subpool, path, "/",
                                          this_entry.fname, NULL);

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


                status = apr_dir_remove_recursively (fullpath, subpool);
                if ((status != APR_SUCCESS) && (retcode != APR_SUCCESS)) {
                    retcode = status;
                }
            }
            else {
                status = apr_file_remove (fullpath, subpool);
                if ((status != APR_SUCCESS) && (retcode != APR_SUCCESS)) {
                    retcode = status;
                }
            }
        }

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

    status = apr_dir_remove (path, subpool);
    if ((status != APR_SUCCESS) && (retcode != APR_SUCCESS)) {
        retcode = status;
    }


    apr_pool_destroy (subpool);

    return retcode;
}

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to