Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / utility / rw_lock.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*
24  * $XConsortium: rw_lock.cc /main/3 1996/06/11 17:38:50 cde-hal $
25  *
26  * Copyright (c) 1993 HAL Computer Systems International, Ltd.
27  * All rights reserved.  Unpublished -- rights reserved under
28  * the Copyright Laws of the United States.  USE OF A COPYRIGHT
29  * NOTICE IS PRECAUTIONARY ONLY AND DOES NOT IMPLY PUBLICATION
30  * OR DISCLOSURE.
31  * 
32  * THIS SOFTWARE CONTAINS CONFIDENTIAL INFORMATION AND TRADE
33  * SECRETS OF HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.  USE,
34  * DISCLOSURE, OR REPRODUCTION IS PROHIBITED WITHOUT THE
35  * PRIOR EXPRESS WRITTEN PERMISSION OF HAL COMPUTER SYSTEMS
36  * INTERNATIONAL, LTD.
37  * 
38  *                         RESTRICTED RIGHTS LEGEND
39  * Use, duplication, or disclosure by the Government is subject
40  * to the restrictions as set forth in subparagraph (c)(l)(ii)
41  * of the Rights in Technical Data and Computer Software clause
42  * at DFARS 252.227-7013.
43  *
44  *          HAL COMPUTER SYSTEMS INTERNATIONAL, LTD.
45  *                  1315 Dell Avenue
46  *                  Campbell, CA  95008
47  * 
48  */
49
50
51 #include "atomic_lock.h"
52 #include "rw_lock.h"
53
54 Boolean read_lock(char* lock_file_path,
55                   char* writing_lock_file_path, 
56                   char* ai_path, 
57                   char* reader_info, int& offset,
58                   char*& ai_info
59                  )
60 {
61    atomic_lock l(lock_file_path);
62
63    if ( l.lock() == false ) {
64       MESSAGE(cerr, "read_lock(): can't do atomic locking");
65       return false;
66    }
67
68    Boolean ok;
69
70    if ( false == exist_file( writing_lock_file_path ) ) {
71
72       fstream x(ai_path, ios::app);
73       if ( !x ) {
74          MESSAGE(cerr, "read_lock(): can't open lock file");
75          throw(streamException(x.rdstate()));
76       }
77
78       offset = bytes(x.rdbuf() -> fd());
79       x << "A-" << reader_info << "\n";
80
81       x.close();
82       ok = true;
83
84    } else {
85
86       fstream x(ai_path, ios::in);
87       if ( !x ) {
88          MESSAGE(cerr, "read_lock(): can't open lock file");
89          throw(streamException(x.rdstate()));
90       }
91
92       int sz = bytes(x.rdbuf() -> fd());
93
94       ai_info = new char[sz+1];
95       ai_info[0] = 0;
96
97       x.getline(ai_info, sz);
98
99       x.close();
100
101       ok = false;
102    }
103
104    if ( l.unlock() == false ) {
105      MESSAGE(cerr, "read_lock(): can't do atomic unlocking");
106      return false;
107    }
108
109    return ok;
110 }
111
112 Boolean read_unlock(char* lock_file_path, char* ai_path, int offset)
113 {
114    atomic_lock l(lock_file_path);
115
116    if ( l.lock() == false ) {
117       MESSAGE(cerr, "read_lock(): can't do atomic locking");
118       return false;
119    }
120
121    Boolean ok ;
122
123    fstream x(ai_path, ios::in|ios::out);
124    if ( !x ) {
125       MESSAGE(cerr, "read_unlock(): can't open lock file");
126       throw(streamException(x.rdstate()));
127    }
128
129    x.seekg( offset, ios::beg );
130    x.put('I');
131
132 ///////////////////////////////////////////////
133 // truncate the info_file if no active readers
134 // and the file size is over 1k
135 ///////////////////////////////////////////////
136
137    if ( bytes(x.rdbuf() -> fd()) > 1024 ) {
138
139       ok = false;
140       char buf[BUFSIZ];
141 /////////////////////////////////////////
142 // scan the info file for active readers
143 /////////////////////////////////////////
144       while ( x.getline(buf, BUFSIZ) ) {
145          if ( buf[0] == 'A' ) {
146             ok = true;
147             break;
148          }
149       }
150
151       if ( ok == false )
152          if ( truncate(ai_path, 0) != 0 ) {
153             MESSAGE(cerr, "read_unlock(): can't truncate");
154             throw(systemException(errno));
155          }
156    }
157
158    x.close();
159
160    if ( l.unlock() == false ) {
161      MESSAGE(cerr, "read_lock(): can't do atomic locking");
162      return false;
163    }
164
165    return true;
166 }
167
168
169 Boolean write_lock(char* lock_file_path, 
170                    char* writing_lock_path, 
171                    char* ai_path, char* writer_info,
172                    char*& ai_info
173                   )
174 {
175    atomic_lock l(lock_file_path);
176
177    if ( l.lock() == false ) {
178       MESSAGE(cerr, "write_lock(): can't do atomic locking");
179       return false;
180    }
181
182    Boolean ok = true;
183
184    fstream x(ai_path, ios::in|ios::out); 
185
186    if (!x) {
187       MESSAGE(cerr, "write_lock(): can't open info file");
188       throw(streamException(x.rdstate()));
189    }
190
191    char buf[BUFSIZ];
192
193    int sz = bytes(x.rdbuf() -> fd());
194    ai_info = new char[sz+1]; 
195    ai_info[0] = 0;
196    
197 /////////////////////////////////////////
198 // scan the info file for active readers
199 /////////////////////////////////////////
200    while ( x.getline(buf, BUFSIZ) ) {
201       if ( buf[0] == 'A' ) {
202          ok = false;
203          strcat(ai_info, buf+1);
204          strcat(ai_info, "\n");
205       }
206    }
207    
208    x.close();
209
210    if ( exist_file( writing_lock_path ) == false ) {
211
212       if ( ok == true ) {
213    
214          delete ai_info;
215 /////////////////////////////////////////
216 // create the access info file
217 /////////////////////////////////////////
218          truncate(ai_path, 0);
219          fstream x(ai_path, ios::out);
220          x << "A-" << writer_info << "\n";
221    
222 /////////////////////////////////////////
223 // create the writing lock file
224 /////////////////////////////////////////
225          if ( creat(writing_lock_path, 0755) == -1 )
226             ok = false;
227      }
228
229    } else 
230       ok = false;
231
232    if ( l.unlock() == false ) {
233       MESSAGE(cerr, "write_lock(): can't do atomic unlocking");
234       return false;
235    }
236
237    return ok;
238 }
239
240 Boolean write_unlock(char* lock_file_path, char* writing_lock_path, 
241                      char* ai_path 
242                     )
243 {
244    atomic_lock l(lock_file_path);
245
246    if ( l.lock() == false ) {
247       MESSAGE(cerr, "write_unlock(): can't do atomic locking");
248       return false;
249    }
250
251    Boolean ok; 
252
253    if ( del_file(writing_lock_path) == 0 &&
254         del_file(ai_path) == 0 
255       ) 
256       ok = true; 
257    else
258       ok = false; 
259
260    if ( l.unlock() == false ) {
261       MESSAGE(cerr, "write_unlock(): can't do atomic unlocking");
262       return false;
263    }
264
265    return ok;
266 }