resolve cyclic dependency with zstd
[platform/upstream/cmake.git] / Source / cmFileLockUnix.cxx
1 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2    file Copyright.txt or https://cmake.org/licensing for details.  */
3 #include <cerrno> // errno
4 #include <cstdio> // SEEK_SET
5
6 #include <fcntl.h>
7 #include <unistd.h>
8
9 #include "cmFileLock.h"
10 #include "cmSystemTools.h"
11
12 cmFileLock::cmFileLock() = default;
13
14 cmFileLockResult cmFileLock::Release()
15 {
16   if (this->Filename.empty()) {
17     return cmFileLockResult::MakeOk();
18   }
19   const int lockResult = this->LockFile(F_SETLK, F_UNLCK);
20
21   this->Filename = "";
22
23   ::close(this->File);
24   this->File = -1;
25
26   if (lockResult == 0) {
27     return cmFileLockResult::MakeOk();
28   }
29   return cmFileLockResult::MakeSystem();
30 }
31
32 cmFileLockResult cmFileLock::OpenFile()
33 {
34   this->File = ::open(this->Filename.c_str(), O_RDWR);
35   if (this->File == -1) {
36     return cmFileLockResult::MakeSystem();
37   }
38   return cmFileLockResult::MakeOk();
39 }
40
41 cmFileLockResult cmFileLock::LockWithoutTimeout()
42 {
43   if (this->LockFile(F_SETLKW, F_WRLCK) == -1) {
44     return cmFileLockResult::MakeSystem();
45   }
46   return cmFileLockResult::MakeOk();
47 }
48
49 cmFileLockResult cmFileLock::LockWithTimeout(unsigned long seconds)
50 {
51   while (true) {
52     if (this->LockFile(F_SETLK, F_WRLCK) == -1) {
53       if (errno != EACCES && errno != EAGAIN) {
54         return cmFileLockResult::MakeSystem();
55       }
56     } else {
57       return cmFileLockResult::MakeOk();
58     }
59     if (seconds == 0) {
60       return cmFileLockResult::MakeTimeout();
61     }
62     --seconds;
63     cmSystemTools::Delay(1000);
64   }
65 }
66
67 int cmFileLock::LockFile(int cmd, int type) const
68 {
69   struct ::flock lock;
70   lock.l_start = 0;
71   lock.l_len = 0;                         // lock all bytes
72   lock.l_pid = 0;                         // unused (for F_GETLK only)
73   lock.l_type = static_cast<short>(type); // exclusive lock
74   lock.l_whence = SEEK_SET;
75   return ::fcntl(this->File, cmd, &lock);
76 }