Upstream tarball 20080414
[amule.git] / src / FileLock.h
blobabfa469f6ca8de8c29dec35ade94bb514e1ea3b7
1 //
2 // This file is part of the aMule Project.
3 //
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 )
6 //
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
9 // respective authors.
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.
20 //
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
26 #ifndef FILELOCK_H
27 #define FILELOCK_H
29 #include <fcntl.h>
30 #include <cerrno>
31 #ifndef _MSC_VER
32 #include <unistd.h> // Do_not_auto_remove (Needed for OpenBSD)
33 #endif
34 #include <string> // Do_not_auto_remove (g++-4.0.1 except win32)
37 /**
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
42 * certain.
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.
49 class CFileLock
51 public:
52 /**
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)
60 #if defined(__WIN32__) || defined(_MSC_VER)
63 #else
64 : m_fd(-1),
65 m_ok(false)
67 // File must be open with O_WRONLY to be able to set write-locks.
68 m_fd = ::open((file + "_lock").c_str(), O_CREAT | O_WRONLY, 0600);
69 if (m_fd != -1) {
70 m_ok = SetLock(true);
74 /** Releases the lock, if any is held. */
75 ~CFileLock() {
76 if (m_ok) {
77 SetLock(false);
80 if (m_fd != -1) {
81 close(m_fd);
85 private:
86 //! Not copyable.
87 CFileLock(const CFileLock&);
88 //! Not assignable.
89 CFileLock& operator=(const CFileLock&);
91 /** Locks or unlocks the lock-file, returning true on success. */
92 bool SetLock(bool doLock) {
93 struct flock lock;
94 lock.l_type = (doLock ? F_WRLCK : F_UNLCK);
96 // Lock the entire file
97 lock.l_whence = SEEK_SET;
98 lock.l_start = 0;
99 lock.l_len = 0;
101 // Keep trying if interrupted by a signal.
102 while (true) {
103 if (fcntl(m_fd, F_SETLKW, &lock) == 0) {
104 return true;
105 } else if ((errno != EACCES) and (errno != EAGAIN) and (errno != EINTR)) {
106 // Not an error we can recover from.
107 break;
111 return false;
115 //! Desribtor of the file being locked.
116 int m_fd;
118 //! Specifies if the file-lock was aquired.
119 bool m_ok;
120 #endif
123 #endif
124 // File_checked_for_headers