summaryrefslogtreecommitdiffstats
path: root/private/crt32/lowio/locking.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/crt32/lowio/locking.c')
-rw-r--r--private/crt32/lowio/locking.c187
1 files changed, 187 insertions, 0 deletions
diff --git a/private/crt32/lowio/locking.c b/private/crt32/lowio/locking.c
new file mode 100644
index 000000000..8eca84b29
--- /dev/null
+++ b/private/crt32/lowio/locking.c
@@ -0,0 +1,187 @@
+/***
+*locking.c - OS/2 file locking function
+*
+* Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* Defined the _locking() function - file locking and unlocking
+*
+*Revision History:
+* 06-09-89 PHG Module created, based on asm version
+* 08-10-89 JCR Changed DOS32FILELOCKS to DOS32SETFILELOCKS
+* 03-12-90 GJF Made calling type _CALLTYPE2 (for now), added #include
+* <cruntime.h> and fixed the copyright. Also, cleaned up
+* the formatting a bit.
+* 04-03-90 GJF Now _CALLTYPE1.
+* 07-24-90 SBM Removed '32' from API names
+* 08-14-90 SBM Compiles cleanly with -W3
+* 09-28-90 GJF New-style function declarator.
+* 12-04-90 GJF Appended Win32 version onto the source with #ifdef-s.
+* It is enough different that there is little point in
+* trying to more closely merge the two versions.
+* 12-04-90 SRW Changed to include <oscalls.h> instead of <doscalls.h>
+* 12-06-90 SRW Changed to use _osfile and _osfhnd instead of _osfinfo
+* 01-16-91 GJF ANSI naming.
+* 02-07-91 SRW Changed to call _get_osfhandle [_WIN32_]
+* 12-05-91 GJF Fixed usage of [Un]LockFile APIs [_WIN32_].
+* 02-13-92 GJF Replaced _nfile by _nhandle for Win32.
+* 05-06-92 SRW WIN32 LockFile API changed. [_WIN32_].
+*
+*******************************************************************************/
+
+#include <cruntime.h>
+#include <oscalls.h>
+#include <errno.h>
+#include <sys\locking.h>
+#include <io.h>
+#include <stdlib.h>
+#include <internal.h>
+#include <os2dll.h>
+
+/***
+*int _locking(fh,lmode,nbytes) - file record locking function
+*
+*Purpose:
+* Locks or unlocks nbytes of a specified file
+*
+* Multi-thread - Must lock/unlock the file handle to prevent
+* other threads from working on the file at the same time as us.
+* [NOTE: We do NOT release the lock during the 1 second delays
+* since some other thread could get in and do something to the
+* file. The DOSFILELOCK call locks out other processes, not
+* threads, so there is no multi-thread deadlock at the DOS file
+* locking level.]
+*
+*Entry:
+* int fh - file handle
+* int lmode - locking mode:
+* _LK_LOCK/_LK_RLCK -> lock, retry 10 times
+* _LK_NBLCK/_LK_N_BRLCK -> lock, don't retry
+* _LK_UNLCK -> unlock
+* long nbytes - number of bytes to lock/unlock
+*
+*Exit:
+* returns 0 if successful
+* returns -1 and sets errno if unsuccessful
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int _CALLTYPE1 _locking (
+ int fh,
+ int lmode,
+ long nbytes
+ )
+{
+ ULONG dosretval; /* OS/2 return code */
+ LONG lockoffset;
+ int retry; /* retry count */
+
+ /* validate file handle */
+#ifdef _WIN32_
+ if ( (unsigned)fh >= (unsigned)_nhandle ) {
+#else
+ if ((unsigned)fh >= (unsigned)_nfile) {
+#endif
+ /* fh out of range */
+ errno = EBADF;
+ _doserrno = 0; /* not an OS/2 error */
+ return -1;
+ }
+
+ _lock_fh(fh); /* acquire file handle lock */
+
+ /* obtain current position in file by calling _lseek */
+ /* Use _lseek_lk as we already own lock */
+ lockoffset = _lseek_lk(fh, 0L, 1);
+ if (lockoffset == -1) {
+ _unlock_fh(fh);
+ return -1;
+ }
+
+
+ /* set retry count based on mode */
+ if (lmode == _LK_LOCK || lmode == _LK_RLCK)
+ retry = 9; /* retry 9 times */
+ else
+ retry = 0; /* don't retry */
+
+ /* ask OS/2 to lock the file until success or retry count finished */
+ /* note that the only error possible is a locking violation, since */
+ /* an invalid handle would have already failed above */
+ for (;;) {
+#ifdef _CRUISER_
+ FILELOCK filelock; /* OS/2 file locking structure */
+
+ filelock.lOffset = lockoffset;
+ filelock.lRange = nbytes;
+
+ if (lmode == _LK_UNLCK)
+ dosretval = DOSSETFILELOCKS(fh, &filelock, NULL);
+ else
+ dosretval = DOSSETFILELOCKS(fh, NULL, &filelock);
+
+ if (retry <= 0 || dosretval == 0)
+ break; /* exit loop on success or retry exhausted */
+
+ DOSSLEEP(1000); /* wait 1 sec until try again */
+
+#else /* ndef _CRUISER_ */
+
+#ifdef _WIN32_
+
+ dosretval = 0;
+ if (lmode == _LK_UNLCK) {
+ if ( !(UnlockFile((HANDLE)_get_osfhandle(fh),
+ lockoffset,
+ 0L,
+ nbytes,
+ 0L))
+ )
+ dosretval = GetLastError();
+
+ } else {
+ if ( !(LockFile((HANDLE)_get_osfhandle(fh),
+ lockoffset,
+ 0L,
+ nbytes,
+ 0L))
+ )
+ dosretval = GetLastError();
+ }
+
+ if (retry <= 0 || dosretval == 0)
+ break; /* exit loop on success or retry exhausted */
+
+ Sleep(1000L);
+
+#else /* ndef _WIN32_ */
+
+#error ERROR - ONLY CRUISER OR WIN32 TARGET SUPPORTED!
+
+#endif /* _WIN32_ */
+
+#endif /* _CRUISER_ */
+
+ --retry;
+ }
+
+ _unlock_fh(fh); /* release the file handle lock */
+
+ if (dosretval != 0) {
+ /* OS/2 error occurred -- file was already locked; if a
+ blocking call, then return EDEADLOCK, otherwise map
+ error normally */
+ if (lmode == _LK_LOCK || lmode == _LK_RLCK) {
+ errno = EDEADLOCK;
+ _doserrno = dosretval;
+ }
+ else {
+ _dosmaperr(dosretval);
+ }
+ return -1;
+ }
+ else
+ return 0;
+}