[llvm] r204422 - [Support] Make sure sys::fs::remove can remove symbolic links and make sure LockFileManager can handle a symbolic link that points nowhere.

Argyrios Kyrtzidis akyrtzi at gmail.com
Thu Mar 20 18:25:37 PDT 2014


Author: akirtzidis
Date: Thu Mar 20 20:25:37 2014
New Revision: 204422

URL: http://llvm.org/viewvc/llvm-project?rev=204422&view=rev
Log:
[Support] Make sure sys::fs::remove can remove symbolic links and make sure LockFileManager can handle a symbolic link that points nowhere.

Modified:
    llvm/trunk/lib/Support/LockFileManager.cpp
    llvm/trunk/lib/Support/Unix/Path.inc
    llvm/trunk/unittests/Support/LockFileManagerTest.cpp

Modified: llvm/trunk/lib/Support/LockFileManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/LockFileManager.cpp?rev=204422&r1=204421&r2=204422&view=diff
==============================================================================
--- llvm/trunk/lib/Support/LockFileManager.cpp (original)
+++ llvm/trunk/lib/Support/LockFileManager.cpp Thu Mar 20 20:25:37 2014
@@ -29,16 +29,13 @@ using namespace llvm;
 /// \returns The process ID of the process that owns this lock file
 Optional<std::pair<std::string, int> >
 LockFileManager::readLockFile(StringRef LockFileName) {
-  // Check whether the lock file exists. If not, clearly there's nothing
-  // to read, so we just return.
-  if (!sys::fs::exists(LockFileName))
-    return None;
-
   // Read the owning host and PID out of the lock file. If it appears that the
   // owning process is dead, the lock file is invalid.
   std::unique_ptr<MemoryBuffer> MB;
-  if (MemoryBuffer::getFile(LockFileName, MB))
+  if (MemoryBuffer::getFile(LockFileName, MB)) {
+    sys::fs::remove(LockFileName);
     return None;
+  }
 
   StringRef Hostname;
   StringRef PIDStr;

Modified: llvm/trunk/lib/Support/Unix/Path.inc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/Path.inc?rev=204422&r1=204421&r2=204422&view=diff
==============================================================================
--- llvm/trunk/lib/Support/Unix/Path.inc (original)
+++ llvm/trunk/lib/Support/Unix/Path.inc Thu Mar 20 20:25:37 2014
@@ -305,7 +305,7 @@ error_code remove(const Twine &path, boo
   StringRef p = path.toNullTerminatedStringRef(path_storage);
 
   struct stat buf;
-  if (stat(p.begin(), &buf) != 0) {
+  if (lstat(p.begin(), &buf) != 0) {
     if (errno != errc::no_such_file_or_directory || !IgnoreNonExisting)
       return error_code(errno, system_category());
     return error_code::success();
@@ -316,7 +316,7 @@ error_code remove(const Twine &path, boo
   // check ensures that what we're trying to erase is a regular file. It
   // effectively prevents LLVM from erasing things like /dev/null, any block
   // special file, or other things that aren't "regular" files.
-  if (!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode))
+  if (!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode) && !S_ISLNK(buf.st_mode))
     return make_error_code(errc::operation_not_permitted);
 
   if (::remove(p.begin()) == -1) {

Modified: llvm/trunk/unittests/Support/LockFileManagerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/LockFileManagerTest.cpp?rev=204422&r1=204421&r2=204422&view=diff
==============================================================================
--- llvm/trunk/unittests/Support/LockFileManagerTest.cpp (original)
+++ llvm/trunk/unittests/Support/LockFileManagerTest.cpp Thu Mar 20 20:25:37 2014
@@ -44,4 +44,36 @@ TEST(LockFileManagerTest, Basic) {
   ASSERT_FALSE(EC);
 }
 
+TEST(LockFileManagerTest, LinkLockExists) {
+  SmallString<64> TmpDir;
+  error_code EC;
+  EC = sys::fs::createUniqueDirectory("LockFileManagerTestDir", TmpDir);
+  ASSERT_FALSE(EC);
+
+  SmallString<64> LockedFile(TmpDir);
+  sys::path::append(LockedFile, "file");
+
+  SmallString<64> FileLocK(TmpDir);
+  sys::path::append(FileLocK, "file.lock");
+
+  SmallString<64> TmpFileLock(TmpDir);
+  sys::path::append(TmpFileLock, "file.lock-000");
+
+  EC = sys::fs::create_link(TmpFileLock.str(), FileLocK.str());
+  ASSERT_FALSE(EC);
+
+  {
+    // The lock file doesn't point to a real file, so we should successfully
+    // acquire it.
+    LockFileManager Locked(LockedFile);
+    EXPECT_EQ(LockFileManager::LFS_Owned, Locked.getState());
+  }
+
+  // Now that the lock is out of scope, the file should be gone.
+  EXPECT_FALSE(sys::fs::exists(StringRef(LockedFile)));
+
+  EC = sys::fs::remove(StringRef(TmpDir));
+  ASSERT_FALSE(EC);
+}
+
 } // end anonymous namespace





More information about the llvm-commits mailing list