1 ////////////////////////////////////////////////////////////////////////
2 // FILE: lockfile.cpp
3 // AUTHOR: Johannes Winkelmann, jw@tks6.net
4 // COPYRIGHT: (c) 2002 by Johannes Winkelmann
5 // ---------------------------------------------------------------------
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 ////////////////////////////////////////////////////////////////////////
11
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15
16 #include <cstdio>
17
18 #include "lockfile.h"
19
20 using namespace std;
21
22 string LockFile::LOCK_SUFFIX = ".lock";
23 string LockFile::WRITE_LOCK_STRING = "write_lock";
24 string LockFile::READ_LOCK_STRING = "read_lock";
25 string LockFile::READ_WRITE_LOCK_STRING = "read_write_lock";
26
27
28 /*!
29 \brief a file locking class
30 */
31 LockFile::LockFile()
32 : m_readLock( false ),
33 m_writeLock( false )
34 {
35 }
36
37
38 bool LockFile::lockRead()
39 {
40 if ( m_readLock ) {
41 // we already lock it, so it's a good lock
42 return true;
43 }
44
45 if ( m_writeLock ) {
46 // can't lock for read and write separatedly
47 return false;
48 }
49
50 struct stat buf;
51 if ( stat( m_fileName.c_str(), &buf) == 0 ) {
52 FILE* fp = fopen( m_fileName.c_str(), "w" );
53 if ( fp ) {
54 // file did not exist, could be created
55 m_writeLock = true;
56 fprintf( fp, "%s", READ_LOCK_STRING.c_str() );
57 fclose( fp );
58 return true;
59 }
60 } else {
61 // file exists, but it could be a read lock
62
63 // TODO: allow locking, increment lock count
64 }
65
66 // couldn't lock
67 return false;
68 }
69
70
71 /*!
72 lock the file
73 \return true if we have a lock
74 */
75 bool LockFile::lockWrite()
76 {
77 if ( m_writeLock ) {
78 // we already lock it, so it's a good lock
79 return true;
80 }
81
82 if ( m_readLock ) {
83 // can't lock for read and write separatedly
84 return false;
85 }
86
87 struct stat buf;
88 if ( stat( m_fileName.c_str(), &buf) == -1 ) {
89 // file can not be stat'ed
90 FILE* fp = fopen( m_fileName.c_str(), "w" );
91 if ( fp ) {
92 // file did not exist, could be created
93 m_writeLock = true;
94 fprintf( fp, "%s", WRITE_LOCK_STRING.c_str() );
95 fclose( fp );
96 return true;
97 }
98 }
99
100 // couldn't lock
101 return false;
102 }
103
104 bool LockFile::lockReadWrite()
105 {
106 if ( m_readWriteLock ) {
107 // we already lock it, so it's a good lock
108 return true;
109 }
110
111 if ( m_writeLock || m_readLock ) {
112 // can't lock for read and write separatedly
113 return false;
114 }
115
116 struct stat buf;
117 if ( stat( m_fileName.c_str(), &buf) == 0 ) {
118 FILE* fp = fopen( m_fileName.c_str(), "w" );
119 if ( fp ) {
120 // file did not exist, could be created
121 m_writeLock = true;
122 fprintf( fp, "%s", READ_WRITE_LOCK_STRING.c_str() );
123 fclose( fp );
124 return true;
125 }
126 }
127
128 // couldn't lock
129 return false;
130
131 }
132
133 bool LockFile::unlock()
134 {
135 if ( m_readLock || m_writeLock || m_readWriteLock ) {
136 // TODO: check whether lock count is 0
137 if ( unlink( m_fileName.c_str() ) == 0 ) {
138 m_readLock = m_writeLock = m_readWriteLock = false;
139 return true;
140 }
141 }
142
143 return false;
144 }
145
146
147 void LockFile::setFile( const string& fileName )
148 {
149 m_fileName = fileName + LOCK_SUFFIX;
150 }
|