Рекурсивное удаление файлов в C на Linux - PullRequest
12 голосов
/ 30 сентября 2010

У меня есть программа на C, которая в какой-то момент в программе имеет это:

system ("rm -rf foo");

Где foo - это каталог. Я решил, что вместо вызова системы лучше сделать рекурсивное удаление прямо в коде. Я предполагал, что часть кода для этого будет легко найти. Дурак я. Так или иначе, я закончил тем, что написал это:

#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;

}

Кажется, это работает, но я слишком напуган, чтобы использовать его на производстве. Я уверен, что сделал что-то не так. Кто-нибудь знает библиотеку C для рекурсивного удаления, которую я пропустил, или кто-то может указать на мои ошибки?

Спасибо.

Ответы [ 4 ]

13 голосов
/ 30 сентября 2010

POSIX имеет функцию с именем ftw (3) (обход дерева файлов), которая

проходит по дереву каталогов, которое находится под каталогом dirpath, и вызывает fn () один раз для каждой записи в дереве.

2 голосов
/ 25 марта 2013

Я бы предложил одну дополнительную меру предосторожности, которую вы можете принять.

Почти всегда, когда вы удаляете несколько файлов и / или каталогов, было бы неплохо выполнить chroot () в dir перед выполнением чего-либо, что может уничтожитьваши данные за пределами этого каталога.

2 голосов
/ 30 сентября 2010

благодарность за то, что ты напуган до смерти, это здоровое отношение к делу в таком случае.

У меня нет библиотеки, чтобы предложить, в каком случае у тебя есть два варианта:

1)«выполнить» этот код исчерпывающе
а) не на машине;на бумаге, карандашом.возьмите существующее дерево каталогов, перечислите все элементы и запустите программу на каждом этапе, убедитесь, что оно работает
b) скомпилируйте код, но замените все вызовы удаления строкой, выполняющей printf, - убедитесь, что она делаетэто должно сделать
в) повторно вставить вызовы удаления и запустить

2) использовать ваш оригинальный метод (система вызовов ())

1 голос
/ 18 февраля 2012

Я думаю, что вам нужно будет вызвать closedir () перед recursiveDelete () (потому что вам не нужно / нужно, чтобы все каталоги открывались при входе в них. Также closedir () перед вызовом remove (), потому что remove () будет возможно, выдает ошибку в открытом каталоге. Вы должны тщательно пройти этот шаг, чтобы удостовериться, что readdir () не подхватывает «..». Также будьте осторожны со связанными каталогами, вы, вероятно, не захотите переходить в каталоги, которые являются символические или жесткие ссылки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...