| 55 | #if HAS_DIRS |
| 56 | |
| 57 | bool DeleteUnixPathTree(const char* path) |
| 58 | { |
| 59 | size_t pathLength; |
| 60 | DIR* dir; |
| 61 | struct stat statPath, statEntry; |
| 62 | struct dirent* entry; |
| 63 | |
| 64 | // Stat for the path |
| 65 | stat(path, &statPath); |
| 66 | |
| 67 | // If path does not exists or is not dir - exit with status -1 |
| 68 | if (S_ISDIR(statPath.st_mode) == 0) |
| 69 | { |
| 70 | // Is not directory |
| 71 | return true; |
| 72 | } |
| 73 | |
| 74 | // If not possible to read the directory for this user |
| 75 | if ((dir = opendir(path)) == NULL) |
| 76 | { |
| 77 | // Cannot open directory |
| 78 | return true; |
| 79 | } |
| 80 | |
| 81 | // The length of the path |
| 82 | pathLength = strlen(path); |
| 83 | |
| 84 | // Iteration through entries in the directory |
| 85 | while ((entry = readdir(dir)) != NULL) |
| 86 | { |
| 87 | // Skip entries "." and ".." |
| 88 | if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) |
| 89 | continue; |
| 90 | |
| 91 | // Determinate a full path of an entry |
| 92 | char full_path[256]; |
| 93 | ASSERT(pathLength + strlen(entry->d_name) < ARRAY_COUNT(full_path)); |
| 94 | strcpy(full_path, path); |
| 95 | strcat(full_path, "/"); |
| 96 | strcat(full_path, entry->d_name); |
| 97 | |
| 98 | // Stat for the entry |
| 99 | stat(full_path, &statEntry); |
| 100 | |
| 101 | // Recursively remove a nested directory |
| 102 | if (S_ISDIR(statEntry.st_mode) != 0) |
| 103 | { |
| 104 | if (DeleteUnixPathTree(full_path)) |
| 105 | return true; |
| 106 | continue; |
| 107 | } |
| 108 | |
| 109 | // Remove a file object |
| 110 | if (unlink(full_path) != 0) |
| 111 | return true; |
| 112 | } |
| 113 | |
| 114 | // Remove the devastated directory and close the object of it |