2 // This file is part of the aMule Project.
4 // Copyright (c) 2006-2008 Mikkel Schubert ( xaignar@users.sourceforge.net )
5 // Copyright (c) 2006-2008 aMule Team ( admin@amule.org / http://www.amule.org )
7 // Any parts of this program derived from the xMule, lMule or eMule project,
8 // or contributed by third-party developers are copyrighted by their
11 // This program is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU General Public License as published by
13 // the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License for more details.
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include <unistd.h> // Do_not_auto_remove (Needed for OpenBSD)
34 #include <string> // Do_not_auto_remove (g++-4.0.1 except win32)
38 * This class provides an easy way to lock non-critical
39 * files used by multiple applications. However, since
40 * the implementation relies on fcntl, it may not work
41 * on all filesystems (NFS) and thus locking is not
44 * Currently, this lock holds an exclusive lock on the
45 * file in question. It is assumed that the file will
46 * be read/written by all users.
53 * Locks the lock-file for the specified file.
55 * The lock-file is a file named file + "_lock", and
56 * will be created if it does not already exist. This
57 * file is not removed afterwards.
59 CFileLock(const std::string
& file
)
63 hd
= CreateFileA((file
+ "_lock").c_str(),
64 GENERIC_READ
| GENERIC_WRITE
,
65 0, // share - not shareable
66 NULL
, // security - not inheritable
68 FILE_ATTRIBUTE_ARCHIVE
,
70 if (hd
!= INVALID_HANDLE_VALUE
) {
75 /** Releases the lock, if any is held. */
81 if (hd
!= INVALID_HANDLE_VALUE
) {
88 CFileLock(const CFileLock
&);
90 CFileLock
& operator=(const CFileLock
&);
92 /** Locks or unlocks the lock-file, returning true on success. */
93 bool SetLock(bool doLock
) {
94 // lock/unlock first byte in the file
96 ov
.Offset
= ov
.OffsetHigh
= 0;
99 // http://msdn.microsoft.com/en-us/library/ms891385.aspx
100 ret
= LockFileEx(hd
, LOCKFILE_EXCLUSIVE_LOCK
, 0, 1, 0, &ov
);
102 // http://msdn.microsoft.com/en-us/library/ms892364.aspx
103 ret
= UnlockFileEx(hd
, 0, 1, 0, &ov
);
109 //! Desriptor of the file being locked.
112 //! Specifies if the file-lock was aquired.
118 // File must be open with O_WRONLY to be able to set write-locks.
119 m_fd
= ::open((file
+ "_lock").c_str(), O_CREAT
| O_WRONLY
, 0600);
121 m_ok
= SetLock(true);
125 /** Releases the lock, if any is held. */
138 CFileLock(const CFileLock
&);
140 CFileLock
& operator=(const CFileLock
&);
142 /** Locks or unlocks the lock-file, returning true on success. */
143 bool SetLock(bool doLock
) {
145 lock
.l_type
= (doLock
? F_WRLCK
: F_UNLCK
);
147 // Lock the entire file
148 lock
.l_whence
= SEEK_SET
;
152 // Keep trying if interrupted by a signal.
154 if (fcntl(m_fd
, F_SETLKW
, &lock
) == 0) {
156 } else if ((errno
!= EACCES
) and (errno
!= EAGAIN
) and (errno
!= EINTR
)) {
157 // Not an error we can recover from.
166 //! Desribtor of the file being locked.
169 //! Specifies if the file-lock was aquired.
175 // File_checked_for_headers