diff --git a/runtime/bin/directory_macos.cc b/runtime/bin/directory_macos.cc index a3fe8e5b7fd..4b5e9afc6e3 100644 --- a/runtime/bin/directory_macos.cc +++ b/runtime/bin/directory_macos.cc @@ -104,20 +104,17 @@ ListType DirectoryListingEntry::Next(DirectoryListing* listing) { // Iterate the directory and post the directories and files to the // ports. - int status = 0; - dirent entry; - dirent* result; - status = NO_RETRY_EXPECTED( - readdir_r(reinterpret_cast(lister_), &entry, &result)); - if ((status == 0) && (result != nullptr)) { - if (!listing->path_buffer().Add(entry.d_name)) { + errno = 0; + dirent* entry = readdir(reinterpret_cast(lister_)); + if (entry != nullptr) { + if (!listing->path_buffer().Add(entry->d_name)) { done_ = true; return kListError; } - switch (entry.d_type) { + switch (entry->d_type) { case DT_DIR: - if ((strcmp(entry.d_name, ".") == 0) || - (strcmp(entry.d_name, "..") == 0)) { + if ((strcmp(entry->d_name, ".") == 0) || + (strcmp(entry->d_name, "..") == 0)) { return Next(listing); } return kListDirectory; @@ -171,16 +168,16 @@ ListType DirectoryListingEntry::Next(DirectoryListing* listing) { // Recurse into the subdirectory with current_link added to the // linked list of seen file system links. link_ = new LinkList(current_link); - if ((strcmp(entry.d_name, ".") == 0) || - (strcmp(entry.d_name, "..") == 0)) { + if ((strcmp(entry->d_name, ".") == 0) || + (strcmp(entry->d_name, "..") == 0)) { return Next(listing); } return kListDirectory; } } if (S_ISDIR(entry_info.st_mode)) { - if ((strcmp(entry.d_name, ".") == 0) || - (strcmp(entry.d_name, "..") == 0)) { + if ((strcmp(entry->d_name, ".") == 0) || + (strcmp(entry->d_name, "..") == 0)) { return Next(listing); } return kListDirectory; @@ -195,14 +192,13 @@ ListType DirectoryListingEntry::Next(DirectoryListing* listing) { default: // We should have covered all the bases. If not, let's get an error. - FATAL("Unexpected d_type: %d\n", entry.d_type); + FATAL("Unexpected d_type: %d\n", entry->d_type); return kListError; } } done_ = true; - if (status != 0) { - errno = status; + if (errno != 0) { return kListError; } @@ -266,18 +262,29 @@ static bool DeleteRecursively(PathBuffer* path) { // Iterate the directory and delete all files and directories. int path_length = path->length(); - dirent entry; - dirent* result; - while (NO_RETRY_EXPECTED(readdir_r(dir_pointer, &entry, &result)) == 0) { - if (result == nullptr) { + while (true) { + // In case `readdir()` returns `nullptr` we distinguish between + // end-of-stream and error by looking if `errno` was updated. + errno = 0; + // In mac 26.4, readdir_r is deprecated. + dirent* entry = readdir(dir_pointer); + if (entry == nullptr) { + // Failed to read next directory entry. + if (errno != 0) { + break; + } // End of directory. - return (NO_RETRY_EXPECTED(closedir(dir_pointer)) == 0) && - (NO_RETRY_EXPECTED(remove(path->AsString())) == 0); + int status = NO_RETRY_EXPECTED(closedir(dir_pointer)); + if (status != 0) { + return false; + } + status = NO_RETRY_EXPECTED(remove(path->AsString())); + return status == 0; } bool ok = false; - switch (entry.d_type) { + switch (entry->d_type) { case DT_DIR: - ok = DeleteDir(entry.d_name, path); + ok = DeleteDir(entry->d_name, path); break; case DT_BLK: case DT_CHR: @@ -288,10 +295,10 @@ static bool DeleteRecursively(PathBuffer* path) { // Treat all links as files. This will delete the link which // is what we want no matter if the link target is a file or a // directory. - ok = DeleteFile(entry.d_name, path); + ok = DeleteFile(entry->d_name, path); break; case DT_UNKNOWN: { - if (!path->Add(entry.d_name)) { + if (!path->Add(entry->d_name)) { break; } // On some file systems the entry type is not determined by @@ -303,18 +310,18 @@ static bool DeleteRecursively(PathBuffer* path) { } path->Reset(path_length); if (S_ISDIR(entry_info.st_mode)) { - ok = DeleteDir(entry.d_name, path); + ok = DeleteDir(entry->d_name, path); } else { // Treat links as files. This will delete the link which is // what we want no matter if the link target is a file or a // directory. - ok = DeleteFile(entry.d_name, path); + ok = DeleteFile(entry->d_name, path); } break; } default: // We should have covered all the bases. If not, let's get an error. - FATAL("Unexpected d_type: %d\n", entry.d_type); + FATAL("Unexpected d_type: %d\n", entry->d_type); break; } if (!ok) {