diff options
author | Ruslan Baratov <ruslan_baratov@yahoo.com> | 2014-11-25 22:49:25 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2014-12-03 14:47:44 (GMT) |
commit | e6db4c5a4ede8039ed525e3facebd7e0eb7ec1b7 (patch) | |
tree | f5e6a3dce7b89725f9fa4e5fcafd040114a85466 /Source/cmFileLockUnix.cxx | |
parent | 05d6531c7a8ecfad513a0e76b44b273b70fa919b (diff) | |
download | CMake-e6db4c5a4ede8039ed525e3facebd7e0eb7ec1b7.zip CMake-e6db4c5a4ede8039ed525e3facebd7e0eb7ec1b7.tar.gz CMake-e6db4c5a4ede8039ed525e3facebd7e0eb7ec1b7.tar.bz2 |
file: Add LOCK subcommand to do file and directory locking
Provide options to fail without blocking or to block up to a timeout.
Provide options to specify the scope containing the lock so it can be
released automatically at the end of a function, file, or process.
Extend the RunCMake.file test with cases covering the file(LOCK) command
usage and error cases.
Diffstat (limited to 'Source/cmFileLockUnix.cxx')
-rw-r--r-- | Source/cmFileLockUnix.cxx | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/Source/cmFileLockUnix.cxx b/Source/cmFileLockUnix.cxx new file mode 100644 index 0000000..038011e --- /dev/null +++ b/Source/cmFileLockUnix.cxx @@ -0,0 +1,102 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2014 Ruslan Baratov + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmFileLock.h" + +#include <errno.h> // errno +#include <stdio.h> // SEEK_SET +#include <fcntl.h> +#include "cmSystemTools.h" + +cmFileLock::cmFileLock(): File(-1) +{ +} + +cmFileLockResult cmFileLock::Release() +{ + if (this->Filename.empty()) + { + return cmFileLockResult::MakeOk(); + } + const int lockResult = this->LockFile(F_SETLK, F_UNLCK); + + this->Filename = ""; + + if (lockResult == 0) + { + return cmFileLockResult::MakeOk(); + } + else + { + return cmFileLockResult::MakeSystem(); + } +} + +cmFileLockResult cmFileLock::OpenFile() +{ + this->File = ::open(this->Filename.c_str(), O_RDWR); + if (this->File == -1) + { + return cmFileLockResult::MakeSystem(); + } + else + { + return cmFileLockResult::MakeOk(); + } +} + +cmFileLockResult cmFileLock::LockWithoutTimeout() +{ + if (this->LockFile(F_SETLKW, F_WRLCK) == -1) + { + return cmFileLockResult::MakeSystem(); + } + else + { + return cmFileLockResult::MakeOk(); + } +} + +cmFileLockResult cmFileLock::LockWithTimeout(unsigned seconds) +{ + while (true) + { + if (this->LockFile(F_SETLK, F_WRLCK) == -1) + { + if (errno != EACCES && errno != EAGAIN) + { + return cmFileLockResult::MakeSystem(); + } + } + else + { + return cmFileLockResult::MakeOk(); + } + if (seconds == 0) + { + return cmFileLockResult::MakeTimeout(); + } + --seconds; + cmSystemTools::Delay(1000); + } +} + +int cmFileLock::LockFile(int cmd, int type) +{ + struct ::flock lock; + lock.l_start = 0; + lock.l_len = 0; // lock all bytes + lock.l_pid = 0; // unused (for F_GETLK only) + lock.l_type = static_cast<short>(type); // exclusive lock + lock.l_whence = SEEK_SET; + return ::fcntl(this->File, cmd, &lock); +} |