summaryrefslogtreecommitdiff
path: root/Source/cmFileLockResult.cxx
diff options
context:
space:
mode:
authorRuslan Baratov <ruslan_baratov@yahoo.com>2014-11-26 01:49:25 +0300
committerBrad King <brad.king@kitware.com>2014-12-03 09:47:44 -0500
commite6db4c5a4ede8039ed525e3facebd7e0eb7ec1b7 (patch)
treef5e6a3dce7b89725f9fa4e5fcafd040114a85466 /Source/cmFileLockResult.cxx
parent05d6531c7a8ecfad513a0e76b44b273b70fa919b (diff)
downloadcmake-e6db4c5a4ede8039ed525e3facebd7e0eb7ec1b7.tar.gz
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/cmFileLockResult.cxx')
-rw-r--r--Source/cmFileLockResult.cxx111
1 files changed, 111 insertions, 0 deletions
diff --git a/Source/cmFileLockResult.cxx b/Source/cmFileLockResult.cxx
new file mode 100644
index 0000000000..045e7ee3cd
--- /dev/null
+++ b/Source/cmFileLockResult.cxx
@@ -0,0 +1,111 @@
+/*============================================================================
+ 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 "cmFileLockResult.h"
+
+#include <errno.h>
+
+cmFileLockResult cmFileLockResult::MakeOk()
+{
+ return cmFileLockResult(OK, 0);
+}
+
+cmFileLockResult cmFileLockResult::MakeSystem()
+{
+#if defined(_WIN32)
+ const Error lastError = GetLastError();
+#else
+ const Error lastError = errno;
+#endif
+ return cmFileLockResult(SYSTEM, lastError);
+}
+
+cmFileLockResult cmFileLockResult::MakeTimeout()
+{
+ return cmFileLockResult(TIMEOUT, 0);
+}
+
+cmFileLockResult cmFileLockResult::MakeAlreadyLocked()
+{
+ return cmFileLockResult(ALREADY_LOCKED, 0);
+}
+
+cmFileLockResult cmFileLockResult::MakeInternal()
+{
+ return cmFileLockResult(INTERNAL, 0);
+}
+
+cmFileLockResult cmFileLockResult::MakeNoFunction()
+{
+ return cmFileLockResult(NO_FUNCTION, 0);
+}
+
+bool cmFileLockResult::IsOk() const
+{
+ return this->Type == OK;
+}
+
+std::string cmFileLockResult::GetOutputMessage() const
+{
+ switch (this->Type)
+ {
+ case OK:
+ return "0";
+ case SYSTEM:
+#if defined(_WIN32)
+ {
+ char* errorText = NULL;
+
+ // http://stackoverflow.com/a/455533/2288008
+ DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_IGNORE_INSERTS;
+ ::FormatMessageA(
+ flags,
+ NULL,
+ this->ErrorValue,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR)&errorText,
+ 0,
+ NULL
+ );
+
+ if (errorText != NULL)
+ {
+ const std::string message = errorText;
+ ::LocalFree(errorText);
+ return message;
+ }
+ else
+ {
+ return "Internal error (FormatMessageA failed)";
+ }
+ }
+#else
+ return strerror(this->ErrorValue);
+#endif
+ case TIMEOUT:
+ return "Timeout reached";
+ case ALREADY_LOCKED:
+ return "File already locked";
+ case NO_FUNCTION:
+ return "'GUARD FUNCTION' not used in function definition";
+ case INTERNAL:
+ default:
+ return "Internal error";
+ }
+}
+
+cmFileLockResult::cmFileLockResult(ErrorType typeValue, Error errorValue):
+ Type(typeValue), ErrorValue(errorValue)
+{
+}