1 /*
2  * locking.c
3  *
4  * This file implements record locking for platforms where the lock(),
5  * unlock() and/or sopen() functions are not available. It also
6  * implements the waitlock() routine, which is the same as lock(), but
7  * waits until the lock can be applied.
8  *
9  * EMX GCC on OS/2:
10  *   lock, unlock: implemented as OS/2 API calls
11  *   sopen: provided by the EMX
12  *
13  * EMX GCC on Windows 32 bit using RSXNT:
14  *   lock, unlock: implemented as Win32 API calls
15  *   sopen: provided by the RSX RTL
16  *
17  * UNIX:
18  *   lock, unlock: implemented as calls to fcntl
19  *   sopen: implemented as open with subsequent shared lock
20  *
21  * OTHER:
22  *   lock, unlock and sopen provieded by the CRTL
23  *   waitlock defined as a loop calling lock and then sleep
24  *
25  * Written by Tobias Ernst @ 2:2476/418, released to the public domain.
26  *
27  */
28 
29 #include "compiler.h"
30 
31 #ifdef __DJGPP__
32 #include <dpmi.h>
33 
shareloaded(void)34 sword far pascal shareloaded(void)
35 {
36     __dpmi_regs r;
37     r.x.ax = 0x1000;
38     __dpmi_int(0x2f, &r);
39     return (r.h.al == 0xff);
40 }
41 #endif
42 
43 #if (defined (__WATCOMC__) || defined(__EMX__) || defined(__IBMC__)) && defined(OS2)
44 
45 #include <os2.h>
46 
lock(int handle,long ofs,long length)47 int lock(int handle, long ofs, long length)
48 {
49     FILELOCK urange, lrange;
50     APIRET apiret;
51 
52     lrange.lOffset = ofs;
53     lrange.lRange = length;
54     urange.lRange = urange.lOffset = 0;
55 
56     if ((apiret = DosSetFileLocks((HFILE)handle, &urange, &lrange, 0, 0)) != 0)
57     {
58         return -1;
59     }
60 
61     return 0;
62 }
63 
unlock(int handle,long ofs,long length)64 int unlock(int handle, long ofs, long length)
65 {
66     FILELOCK urange, lrange;
67     APIRET apiret;
68 
69     urange.lOffset = ofs;
70     urange.lRange = length;
71     lrange.lRange = lrange.lOffset = 0;
72 
73     if ((apiret = DosSetFileLocks((HFILE)handle, &urange, &lrange, 0, 0)) != 0)
74     {
75         return -1;
76     }
77     return 0;
78 }
79 
waitlock(int handle,long ofs,long length)80 int waitlock(int handle, long ofs, long length)
81 {
82     FILELOCK urange, lrange;
83     APIRET apiret;
84 
85     lrange.lOffset = ofs;
86     lrange.lRange = length;
87     urange.lRange = urange.lOffset = 0;
88 
89     while ((apiret = DosSetFileLocks((HFILE)handle, &urange, &lrange, 60000, 0)) != 0);
90 
91     return 0;
92 }
93 
waitlock2(int handle,long ofs,long length,long t)94 int waitlock2(int handle, long ofs, long length, long t)
95 {
96     FILELOCK urange, lrange;
97     APIRET apiret;
98 
99     lrange.lOffset = ofs;
100     lrange.lRange = length;
101     urange.lRange = urange.lOffset = 0;
102 
103     return DosSetFileLocks((HFILE)handle, &urange, &lrange, t*1000l, 0);
104 }
105 
106 
107 #elif defined(__RSXNT__)
108 
109 #include <windows.h>
110 #include <emx/syscalls.h>
111 #include <stdlib.h>
112 
113 #ifndef F_GETOSFD
114 #define F_GETOSFD 6
115 #endif
116 
waitlock(int handle,long ofs,long length)117 int waitlock(int handle, long ofs, long length)
118 {
119     int nt_handle = __fcntl(handle, F_GETOSFD, 0);
120 
121     if (nt_handle < 0)
122     {
123         return -1;
124     }
125     while (LockFile(nt_handle, (DWORD)ofs, 0L, (DWORD)length, 0L) == FALSE)
126     {
127         sleep(1);
128     }
129 
130     return 0;
131 }
132 
133 /*
134  *  THERE SHOULD BE A BETTER WAY TO MAKE A TIMED LOCK.
135  */
136 
waitlock2(int handle,long ofs,long length,long t)137 int waitlock2(int handle, long ofs, long length, long t)
138 {
139     int forever = 0;
140     int rc;
141 
142     if (t==0)
143       forever = 1;
144 
145     t *= 10;
146     while ((rc = lock(handle, ofs, length)) == -1 && (t > 0 || forever))
147     {
148         tdelay(100);
149         t--;
150     }
151 
152     return rc;
153 }
154 
lock(int handle,long ofs,long length)155 int lock(int handle, long ofs, long length)
156 {
157     int nt_handle = __fcntl(handle, F_GETOSFD, 0);
158 
159     if (nt_handle < 0 ||
160         LockFile((DWORD)nt_handle, (DWORD)ofs, 0L, (DWORD)length, 0L) == FALSE)
161     {
162         return -1;
163     }
164     return 0;
165 }
166 
unlock(int handle,long ofs,long length)167 int unlock(int handle, long ofs, long length)
168 {
169     int nt_handle = __fcntl(handle, F_GETOSFD, 0);
170 
171     if (nt_handle < 0 ||
172         UnlockFile((DWORD)nt_handle, (DWORD)ofs, 0L, (DWORD)length,
173                    0L) == FALSE)
174     {
175         return -1;
176     }
177     return 0;
178 }
179 
180 #elif defined(__MINGW32__) || (defined(_MSC_VER) && (_MSC_VER >= 1200))
181 
182 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
183 #include <stdio.h>
184 #endif
185 
186 #include <io.h>
187 
waitlock(int handle,long ofs,long length)188 int waitlock(int handle, long ofs, long length)
189 {
190     long offset = tell(handle);
191 
192     if (offset == -1)
193         return -1;
194 
195     lseek(handle, ofs, SEEK_SET);
196     _locking(handle, 1, length);
197     lseek(handle, offset, SEEK_SET);
198 
199     return 0;
200 }
201 
202 /*
203  * THERE SHOULD BE A BETTER WAY TO MAKE A TIMED LOCK !!!!
204  */
waitlock2(int handle,long ofs,long length,long t)205 int waitlock2(int handle, long ofs, long length, long t)
206 {
207     int forever = 0;
208     int rc;
209 
210     if (t==0)
211       forever = 1;
212 
213     t *= 10;
214     while ((rc = lock(handle, ofs, length)) == -1 && (t > 0 || forever))
215     {
216         tdelay(100);
217         t--;
218     }
219 
220     return rc;
221 }
222 
223 
lock(int handle,long ofs,long length)224 int lock(int handle, long ofs, long length)
225 {
226     long offset = tell(handle);
227     int r;
228 
229     if (offset == -1)
230         return -1;
231 
232 
233     lseek(handle, ofs, SEEK_SET);
234     r = _locking(handle, 2, length);
235     lseek(handle, offset, SEEK_SET);
236 
237     if  (r)
238        return -1;
239 
240     return 0;
241 }
242 
unlock(int handle,long ofs,long length)243 int unlock(int handle, long ofs, long length)
244 {
245     long offset = tell(handle);
246 
247     if (offset == -1)
248         return -1;
249 
250     lseek(handle, ofs, SEEK_SET);
251     _locking(handle, 0, length);
252     lseek(handle, offset, SEEK_SET);
253 
254     return 0;
255 }
256 
257 #elif defined(_MSC_VER) && (_MSC_VER < 1200)
258 
259 #include <io.h>
260 #include <stdio.h>
261 
waitlock(int handle,long ofs,long length)262 int waitlock(int handle, long ofs, long length)
263 {
264     while (lock(handle, ofs, length) == -1)
265     {
266         tdelay(100);
267     }
268     return 0;
269 }
270 
waitlock2(int handle,long ofs,long length,long t)271 int waitlock2(int handle, long ofs, long length, long t)
272 {
273     int forever = 0;
274     int rc;
275 
276     if (t==0)
277       forever = 1;
278 
279     t *= 10;
280     while ((rc = lock(handle, ofs, length)) == -1 && (t > 0 || forever))
281     {
282         tdelay(100);
283         t--;
284     }
285 
286     return rc;
287 }
288 
lock(int handle,long ofs,long length)289 int lock(int handle, long ofs, long length)
290 {
291     long offset = tell(handle);
292     int r;
293 
294     if (offset == -1)
295         return -1;
296 
297     lseek(handle, ofs, SEEK_SET);
298     r = locking(handle, 2, length);
299     lseek(handle, offset, SEEK_SET);
300 
301     if  (r)
302        return -1;
303 
304     return 0;
305 }
306 
unlock(int handle,long ofs,long length)307 int unlock(int handle, long ofs, long length)
308 {
309     long offset = tell(handle);
310     int r;
311 
312     if (offset == -1)
313         return -1;
314 
315     lseek(handle, ofs, SEEK_SET);
316     r = locking(handle, 0, length);
317     lseek(handle, offset, SEEK_SET);
318 
319     if (r)
320         return -1;
321     return 0;
322 }
323 
324 
325 #elif defined(UNIX)
326 
327 #include <fcntl.h>
328 #include <unistd.h>
329 
file_lock(short type,long ofs,long length)330 static struct flock* file_lock(short type, long ofs, long length)
331 {
332     static struct flock ret;
333 
334     ret.l_type = type;
335     ret.l_start = ofs;
336     ret.l_whence = SEEK_SET;
337     ret.l_len = length;
338     ret.l_pid = getpid();
339     return &ret;
340 }
341 
lock(int handle,long ofs,long length)342 int lock(int handle, long ofs, long length)
343 {
344 #ifndef __BEOS__
345     return fcntl(handle, F_SETLK, file_lock(F_WRLCK, ofs, length));
346 #else
347 	return 0;
348 #endif
349 }
350 
waitlock(int handle,long ofs,long length)351 int waitlock(int handle, long ofs, long length)
352 {
353 #ifndef __BEOS__
354     return fcntl(handle, F_SETLKW, file_lock(F_WRLCK, ofs, length));
355 #else
356     return 0;
357 #endif
358 }
359 
360 /*
361  * waitlock2() wait <t> seconds for a lock
362  */
363 
waitlock2(int handle,long ofs,long length,long t)364 int waitlock2(int handle, long ofs, long length, long t)
365 {
366 #ifndef __BEOS__
367 	int rc;
368 
369 	alarm(t);
370 	rc = fcntl(handle, F_SETLKW, file_lock(F_WRLCK, ofs, length));
371 	alarm(0);
372 
373 	return rc;
374 #else
375   	return 0;
376 #endif
377 }
378 
379 
unlock(int handle,long ofs,long length)380 int unlock(int handle, long ofs, long length)
381 {
382 #ifndef __BEOS__
383     return fcntl(handle, F_SETLK, file_lock(F_UNLCK, ofs, length));
384 #else
385     return 0;
386 #endif
387 }
388 
389 #include <stdio.h>
390 
sopen(const char * name,int oflag,int ishared,int mode)391 int sopen(const char *name, int oflag, int ishared, int mode)
392 {
393     int fd = open(name, oflag, mode);
394 
395     /*
396      * I removed this code, 'cause there is no more need for it (i hope so)
397      */
398 /*
399 #ifndef NO_LOCKING
400     if (fd != -1 && fcntl(fd, F_SETLK,
401               file_lock((ishared == SH_DENYNONE) ? F_RDLCK : F_WRLCK, 0, 0)))
402 
403     {
404         close(fd);
405         return -1;
406     }
407 #endif
408 */
409     return fd;
410 }
411 
412 #else
413 
414 #ifdef OS2
415 #define INCL_DOSDATETIME
416 #include <os2.h>
417 #endif
418 
419 #if defined(__TURBOC__) && defined(__MSDOS__)
420 #include <io.h>
421 #include <dos.h>
422 #endif
423 
424 #ifdef UNIX
425 #include <unistd.h>
426 #endif
427 
waitlock(int handle,long ofs,long length)428 int waitlock(int handle, long ofs, long length)
429 {
430     while (lock(handle, ofs, length) == -1)
431     {
432         tdelay(100);
433     }
434     return 0;
435 }
436 
waitlock2(int handle,long ofs,long length,long t)437 int waitlock2(int handle, long ofs, long length, long t)
438 {
439     int forever = 0;
440     int rc;
441 
442     if (t==0)
443       forever = 1;
444 
445     t *= 10;
446 
447     while ((rc = lock(handle, ofs, length)) == -1 && (t > 0 || forever))
448     {
449         tdelay(100);
450         t--;
451     }
452 
453     return rc;
454 }
455 
456 
457 #endif
458