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) {