| 350 | } |
| 351 | |
| 352 | void |
| 353 | RemoveDirectoryRecursive(std::string const& path) |
| 354 | { |
| 355 | if (path.size() > PATH_MAX) |
| 356 | { |
| 357 | errno = ENAMETOOLONG; |
| 358 | throw std::invalid_argument(GetLastCErrorStr()); |
| 359 | } |
| 360 | |
| 361 | int res = -1; |
| 362 | errno = 0; |
| 363 | DIR* dir = opendir(path.c_str()); |
| 364 | if (dir != nullptr) |
| 365 | { |
| 366 | res = 0; |
| 367 | |
| 368 | struct dirent* ent = nullptr; |
| 369 | while (!res && (ent = readdir(dir)) != nullptr) |
| 370 | { |
| 371 | // Skip the names "." and ".." as we don't want to recurse on them. |
| 372 | if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) |
| 373 | { |
| 374 | continue; |
| 375 | } |
| 376 | |
| 377 | std::string child = path + DIR_SEP + ent->d_name; |
| 378 | if |
| 379 | #ifdef _DIRENT_HAVE_D_TYPE |
| 380 | (ent->d_type == DT_DIR) |
| 381 | #else |
| 382 | (IsDirectory(child)) |
| 383 | #endif |
| 384 | { |
| 385 | RemoveDirectoryRecursive(child); |
| 386 | } |
| 387 | else |
| 388 | { |
| 389 | res = us_unlink(child.c_str()); |
| 390 | } |
| 391 | } |
| 392 | int old_err = errno; |
| 393 | errno = 0; |
| 394 | closedir(dir); // error ignored |
| 395 | if (old_err) |
| 396 | { |
| 397 | errno = old_err; |
| 398 | } |
| 399 | } |
| 400 | |
| 401 | if (!res) |
| 402 | { |