Рекурсивное удаление файла в C на Linux

У меня есть программа на C, которая в какой-то момент в программе имеет следующее:

( "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 для рекурсивного удаления, которое я пропустил, или кто-то может указать на какие-либо ошибки, которые я сделал?

Спасибо.

Ответ 1

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

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

Ответ 2

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

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

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

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

Ответ 3

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

Ответ 4

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

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