开发者

Recursive file delete in C on Linux

I have a C program that, at one point in the program has this:

system("rm -rf foo");

Where foo is a directory. I decided that, rather than calling system, it would be better to do the recursive delete right in the code. I assumed a piece of code to do this would be easy to find. Silly me. Anyway, I ended up writing this:

#include <stdio.h>
#include <sys/stat.h>
#include <dirent.h>
#include <libgen.h>

int recursiveDelete(char* dirname) {

  DIR *dp;
  struct dirent *ep;

  char abs_filename[FILENAME_MAX];

  dp = opendir (dirname);
  if (dp != NULL)
    {
      while (ep = readdir (dp)) {
        struct stat stFileInfo;

        snprintf(abs_filename, FILENAME_MAX, "%s/%s", dirname, ep->d_name);

        if (lstat(abs_filename, &stFileInfo) < 0)
          perror ( abs_filename );

        if(S_ISDIR(stFileInfo.st_mode)) {
          if(strcmp(ep->d_name, ".") && 
             strcmp(ep->d_name, "..")) {
            printf("%s directory\n",abs_filename);
            recursiveDelete(abs_filename);
          }
        } else {
          printf("%s file\n",abs_filename);
                  remove(abs_filename);
        }
          }
      (void) closedir (dp);
        }
  else
    perror ("Couldn't open the directory");


  remove(dirname);
  return 0;

}

This seems to work, but I'm too scared to actually use it in production. I'm sure I've done something wrong. Does anyone know of 开发者_如何学运维a C library to do recursive delete I've missed, or can someone point out any mistakes I've made?

Thanks.


POSIX has a function called ftw(3) (file tree walk) that

walks through the directory tree that is located under the directory dirpath, and calls fn() once for each entry in the tree.


kudos for being scared to death, that's a healthy attitude to have in a case like this.

I have no library to suggest in which case you have two options:

1) 'run' this code exhaustively
  a) not on a machine; on paper, with pencil. take an existing directory tree, list all the elements and run the program through each step, verify that it works
  b) compile the code but replace all of the deletion calls with a line that does a printf - verify that it does what it should do
  c) re-insert the deletion calls and run

2) use your original method (call system())


I would suggest one additional precaution that you can take.

Almost always when you delete multiple files and/or directories it would be a good idea to chroot() into the dir before executing anything that can destroy your data outside this directory.


I think you will need to call closedir() before recursiveDelete() (because you don't want/need all the directories open as you step into them. Also closedir() before calling remove() because remove() will probably give an error on the open directory. You should step through this once carefully to make sure that readdir() does not pickup the '..'. Also be wary of linked directories, you probably wouldn't want to recurse into directories that are symbolic or hard links.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜