Branch data Line data Source code
1 : : // Copyright (c) 2017-present The Bitcoin Core developers
2 : : // Distributed under the MIT software license, see the accompanying
3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 : :
5 : : #include <util/fs.h>
6 : : #include <util/syserror.h>
7 : :
8 : : #ifndef WIN32
9 : : #include <cstring>
10 : : #include <fcntl.h>
11 : : #include <sys/file.h>
12 : : #include <sys/utsname.h>
13 : : #include <unistd.h>
14 : : #else
15 : : #include <limits>
16 : : #include <windows.h>
17 : : #endif
18 : :
19 : : #include <cassert>
20 : : #include <cerrno>
21 : : #include <string>
22 : :
23 : : namespace fsbridge {
24 : :
25 : 808802 : FILE *fopen(const fs::path& p, const char *mode)
26 : : {
27 : : #ifndef WIN32
28 : 808802 : return ::fopen(p.c_str(), mode);
29 : : #else
30 : : return ::fopen(p.utf8string().c_str(), mode);
31 : : #endif
32 : : }
33 : :
34 : 1031 : fs::path AbsPathJoin(const fs::path& base, const fs::path& path)
35 : : {
36 [ - + ]: 1031 : assert(base.is_absolute());
37 [ - + + - ]: 4124 : return path.empty() ? base : fs::path(base / path);
38 : : }
39 : :
40 : : #ifndef WIN32
41 : :
42 : 0 : static std::string GetErrorReason()
43 : : {
44 : 0 : return SysErrorString(errno);
45 : : }
46 : :
47 [ # # ]: 0 : FileLock::FileLock(const fs::path& file)
48 : : {
49 [ # # ]: 0 : fd = open(file.c_str(), O_RDWR);
50 [ # # ]: 0 : if (fd == -1) {
51 [ # # ]: 0 : reason = GetErrorReason();
52 : : }
53 : 0 : }
54 : :
55 : 0 : FileLock::~FileLock()
56 : : {
57 [ # # ]: 0 : if (fd != -1) {
58 : 0 : close(fd);
59 : : }
60 : 0 : }
61 : :
62 : 0 : bool FileLock::TryLock()
63 : : {
64 [ # # ]: 0 : if (fd == -1) {
65 : : return false;
66 : : }
67 : :
68 : 0 : struct flock lock;
69 : 0 : lock.l_type = F_WRLCK;
70 : 0 : lock.l_whence = SEEK_SET;
71 : 0 : lock.l_start = 0;
72 : 0 : lock.l_len = 0;
73 [ # # ]: 0 : if (fcntl(fd, F_SETLK, &lock) == -1) {
74 : 0 : reason = GetErrorReason();
75 : 0 : return false;
76 : : }
77 : :
78 : : return true;
79 : : }
80 : : #else
81 : :
82 : : static std::string GetErrorReason() {
83 : : return Win32ErrorString(GetLastError());
84 : : }
85 : :
86 : : FileLock::FileLock(const fs::path& file)
87 : : {
88 : : hFile = CreateFileW(file.wstring().c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
89 : : nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
90 : : if (hFile == INVALID_HANDLE_VALUE) {
91 : : reason = GetErrorReason();
92 : : }
93 : : }
94 : :
95 : : FileLock::~FileLock()
96 : : {
97 : : if (hFile != INVALID_HANDLE_VALUE) {
98 : : CloseHandle(hFile);
99 : : }
100 : : }
101 : :
102 : : bool FileLock::TryLock()
103 : : {
104 : : if (hFile == INVALID_HANDLE_VALUE) {
105 : : return false;
106 : : }
107 : : _OVERLAPPED overlapped = {};
108 : : if (!LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, std::numeric_limits<DWORD>::max(), std::numeric_limits<DWORD>::max(), &overlapped)) {
109 : : reason = GetErrorReason();
110 : : return false;
111 : : }
112 : : return true;
113 : : }
114 : : #endif
115 : :
116 : : } // namespace fsbridge
|