17
17
18
18
#include < fcntl.h>
19
19
#ifdef WIN32
20
- #include < windows.h>
21
- #include < io.h>
20
+ #include < algorithm>
22
21
#endif
23
22
24
23
@@ -34,7 +33,32 @@ SharedFiles::handlers_map::iterator SharedFiles::add_new_handler(
34
33
return m_handlers.end ();
35
34
}
36
35
37
- return m_handlers.insert ({ fileName, {fp, 0 } }).first ;
36
+ #ifdef WIN32
37
+ // replace invalid characters for a Win32 named object
38
+ auto tmp = fileName;
39
+ std::replace (tmp.begin (), tmp.end (), ' \\ ' , ' _' );
40
+ std::replace (tmp.begin (), tmp.end (), ' /' , ' _' );
41
+
42
+ // use named mutex for multi-process locking support
43
+ const auto mutexName = " Global\\ ModSecurity_" + tmp;
44
+
45
+ HANDLE hMutex = CreateMutex (NULL , FALSE , mutexName.c_str ());
46
+ if (hMutex == NULL ) {
47
+ error->assign (" Failed to create mutex for shared file: " + fileName);
48
+ fclose (fp);
49
+ return m_handlers.end ();
50
+ }
51
+ #endif
52
+
53
+ auto handler = handler_info {
54
+ fp,
55
+ #ifdef WIN32
56
+ hMutex,
57
+ #endif
58
+ 0
59
+ };
60
+ // cppcheck-suppress resourceLeak ; false positive, fp is closed in SharedFiles::close
61
+ return m_handlers.insert ({ fileName, handler }).first ;
38
62
}
39
63
40
64
@@ -69,6 +93,9 @@ void SharedFiles::close(const std::string& fileName) {
69
93
if (it->second .cnt == 0 )
70
94
{
71
95
fclose (it->second .fp );
96
+ #ifdef WIN32
97
+ CloseHandle (it->second .hMutex );
98
+ #endif
72
99
73
100
m_handlers.erase (it);
74
101
}
@@ -92,9 +119,11 @@ bool SharedFiles::write(const std::string& fileName,
92
119
lock.l_type = F_WRLCK;
93
120
fcntl (fileno (it->second .fp ), F_SETLKW, &lock);
94
121
#else
95
- auto handle = reinterpret_cast <HANDLE>(_get_osfhandle (fileno (it->second .fp )));
96
- OVERLAPPED overlapped = { 0 };
97
- ::LockFileEx (handle, LOCKFILE_EXCLUSIVE_LOCK, 0 , MAXDWORD, MAXDWORD, &overlapped);
122
+ DWORD dwWaitResult = WaitForSingleObject (it->second .hMutex , INFINITE);
123
+ if (dwWaitResult != WAIT_OBJECT_0) {
124
+ error->assign (" couldn't lock shared file: " + fileName);
125
+ return false ;
126
+ }
98
127
#endif
99
128
100
129
auto wrote = fwrite (msg.c_str (), 1 , msg.size (), it->second .fp );
@@ -109,8 +138,7 @@ bool SharedFiles::write(const std::string& fileName,
109
138
lock.l_type = F_UNLCK;
110
139
fcntl (fileno (it->second .fp ), F_SETLKW, &lock);
111
140
#else
112
- overlapped = { 0 };
113
- ::UnlockFileEx (handle, 0 , MAXDWORD, MAXDWORD, &overlapped);
141
+ ::ReleaseMutex (it->second.hMutex);
114
142
#endif
115
143
116
144
return ret;
0 commit comments