diff options
author | 2018-04-09 02:49:33 -0700 | |
---|---|---|
committer | 2018-04-09 02:50:49 -0700 | |
commit | f3de7d5ff2834ad601975929aa189cfe268a6fb9 (patch) | |
tree | ed951b24bce022d9730c7326502f27889f113b2f /src/main | |
parent | b6069dce1121bb81a667bd9c636681862209e48c (diff) |
Made 'file_posix.cc' POSIX compatible
The `d_type` field is not part of the POSIX specification. Added a compile time check to see if we can use it. When not present fallback to a (slightly more expensive) call to 'stat'.
The reason why I need this is because I'm trying to port Bazel to a POSIX compliant platform. Even though my porting effort might fail miserably ;-) I think having a POSIX implementation which is POSIX compliant would be of benefit to the Bazel project.
Besides the POSIX spec I've based the implementation on information I found here:
* https://stackoverflow.com/questions/2197918/cross-platform-way-of-testing-whether-a-file-is-a-directory
* https://stackoverflow.com/questions/23958040/checking-if-a-dir-entry-returned-by-readdir-is-a-directory-link-or-file#answer-29094555
* https://stackoverflow.com/questions/39429803/how-to-list-first-level-directories-only-in-c/39430337#39430337
Closes #4967.
PiperOrigin-RevId: 192102522
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/cpp/util/file_posix.cc | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/src/main/cpp/util/file_posix.cc b/src/main/cpp/util/file_posix.cc index f143ab125b..5136df0655 100644 --- a/src/main/cpp/util/file_posix.cc +++ b/src/main/cpp/util/file_posix.cc @@ -445,22 +445,26 @@ void ForEachDirectoryEntry(const string &path, string filename(blaze_util::JoinPath(path, ent->d_name)); bool is_directory; - if (ent->d_type == DT_UNKNOWN) { - struct stat buf; - if (lstat(filename.c_str(), &buf) == -1) { - BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR) - << "stat failed for filename '" << filename - << "': " << GetLastErrorString(); - } - is_directory = S_ISDIR(buf.st_mode); - } else { +// 'd_type' field isn't part of the POSIX spec. +#ifdef _DIRENT_HAVE_D_TYPE + if (ent->d_type != DT_UNKNOWN) { is_directory = (ent->d_type == DT_DIR); + } else // NOLINT (the brace is on the next line) +#endif + { + struct stat buf; + if (lstat(filename.c_str(), &buf) == -1) { + BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR) + << "stat failed for filename '" << filename + << "': " << GetLastErrorString(); + } + is_directory = S_ISDIR(buf.st_mode); + } + + consume->Consume(filename, is_directory); } - consume->Consume(filename, is_directory); + closedir(dir); } - closedir(dir); -} - } // namespace blaze_util |