diff options
author | Daniel Dunbar <daniel@zuster.org> | 2012-10-17 16:30:54 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2012-10-17 16:30:54 +0000 |
commit | 81e35ff722ce941857ea88e40f9b2edbf69b6256 (patch) | |
tree | 085e0d0c82b58d971ff1e46c2ba56646a60700f3 | |
parent | 324d96b9e265b0fd8bf63a28340910def64e2164 (diff) |
Support: Don't remove special files on signals.
- Similar to Path::eraseFromDisk(), we don't want LLVM to remove things like
/dev/null, even if it has the permission.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@166105 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Support/Unix/Signals.inc | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/lib/Support/Unix/Signals.inc b/lib/Support/Unix/Signals.inc index cf64fa8f38..9e94068c9c 100644 --- a/lib/Support/Unix/Signals.inc +++ b/lib/Support/Unix/Signals.inc @@ -121,17 +121,29 @@ static void UnregisterHandlers() { /// NB: This must be an async signal safe function. It cannot allocate or free /// memory, even in debug builds. static void RemoveFilesToRemove() { - // Note: avoid iterators in case of debug iterators that allocate or release + // We avoid iterators in case of debug iterators that allocate or release // memory. for (unsigned i = 0, e = FilesToRemove.size(); i != e; ++i) { - // Note that we don't want to use any external code here, and we don't care - // about errors. We're going to try as hard as we can as often as we need - // to to make these files go away. If these aren't files, too bad. - // - // We do however rely on a std::string implementation for which repeated - // calls to 'c_str()' don't allocate memory. We pre-call 'c_str()' on all - // of these strings to try to ensure this is safe. - unlink(FilesToRemove[i].c_str()); + // We rely on a std::string implementation for which repeated calls to + // 'c_str()' don't allocate memory. We pre-call 'c_str()' on all of these + // strings to try to ensure this is safe. + const char *path = FilesToRemove[i].c_str(); + + // Get the status so we can determine if it's a file or directory. If we + // can't stat the file, ignore it. + struct stat buf; + if (stat(path, &buf) != 0) + continue; + + // If this is not a regular file, ignore it. We want to prevent removal of + // special files like /dev/null, even if the compiler is being run with the + // super-user permissions. + if (!S_ISREG(buf.st_mode)) + continue; + + // Otherwise, remove the file. We ignore any errors here as there is nothing + // else we can do. + unlink(path); } } |