/*
* locking.c
*
* This file implements record locking for platforms where the lock(),
* unlock() and/or sopen() functions are not available. It also
* implements the waitlock() routine, which is the same as lock(), but
* waits until the lock can be applied.
*
* EMX GCC on OS/2:
* lock, unlock: implemented as OS/2 API calls
* sopen: provided by the EMX
*
* EMX GCC on Windows 32 bit using RSXNT:
* lock, unlock: implemented as Win32 API calls
* sopen: provided by the RSX RTL
*
* UNIX:
* lock, unlock: implemented as calls to fcntl
* sopen: implemented as open with subsequent shared lock
*
* OTHER:
* lock, unlock and sopen provieded by the CRTL
* waitlock defined as a loop calling lock and then sleep
*
* Written by Tobias Ernst @ 2:2476/418, released to the public domain.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include "compiler.h"
#ifdef HAS_DIRECT_H
# include <direct.h>
#endif
#ifdef HAS_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAS_IO_H
# include <io.h>
#endif
#ifdef HAS_DOS_H
# include <dos.h>
#endif
#include "prog.h"
#ifdef __DJGPP__
#include "msgapi.h"
#include <dpmi.h>
sword far pascal shareloaded(void)
{
__dpmi_regs r;
r.x.ax = 0x1000;
__dpmi_int(0x2f, &r);
return (r.h.al == 0xff);
}
#endif
/*#if defined (__WATCOMC__OS2__) || defined(__EMX__) || defined(__IBMC__OS2__)*/
#if defined (__OS2__)
#include <os2.h>
int lock(int handle, long ofs, long length)
{
FILELOCK urange, lrange;
APIRET apiret;
lrange.lOffset = ofs;
lrange.lRange = length;
urange.lRange = urange.lOffset = 0;
if ((apiret = DosSetFileLocks((HFILE)handle, &urange, &lrange, 0, 0)) != 0)
{
return -1;
}
return 0;
}
int unlock(int handle, long ofs, long length)
{
FILELOCK urange, lrange;
APIRET apiret;
urange.lOffset = ofs;
urange.lRange = length;
lrange.lRange = lrange.lOffset = 0;
if ((apiret = DosSetFileLocks((HFILE)handle, &urange, &lrange, 0, 0)) != 0)
{
return -1;
}
return 0;
}
int waitlock(int handle, long ofs, long length)
{
FILELOCK urange, lrange;
APIRET apiret;
lrange.lOffset = ofs;
lrange.lRange = length;
urange.lRange = urange.lOffset = 0;
while ((apiret = DosSetFileLocks((HFILE)handle, &urange, &lrange, 60000, 0)) != 0);
return 0;
}
int waitlock2(int handle, long ofs, long length, long t)
{
FILELOCK urange, lrange;
lrange.lOffset = ofs;
lrange.lRange = length;
urange.lRange = urange.lOffset = 0;
return DosSetFileLocks((HFILE)handle, &urange, &lrange, t*1000l, 0);
}
#elif defined(__RSXNT__)
#include <windows.h>
#include <emx/syscalls.h>
#ifndef F_GETOSFD
#define F_GETOSFD 6
#endif
int waitlock(int handle, long ofs, long length)
{
int nt_handle = __fcntl(handle, F_GETOSFD, 0);
if (nt_handle < 0)
{
return -1;
}
while (LockFile(nt_handle, (DWORD)ofs, 0L, (DWORD)length, 0L) == FALSE)
{
sleep(1);
}
return 0;
}
/*
* THERE SHOULD BE A BETTER WAY TO MAKE A TIMED LOCK.
*/
int waitlock2(int handle, long ofs, long length, long t)
{
int forever = 0;
int rc;
if (t==0)
forever = 1;
t *= 10;
while ((rc = lock(handle, ofs, length)) == -1 && (t > 0 || forever))
{
tdelay(100);
t--;
}
return rc;
}
int lock(int handle, long ofs, long length)
{
int nt_handle = __fcntl(handle, F_GETOSFD, 0);
if (nt_handle < 0 ||
LockFile((DWORD)nt_handle, (DWORD)ofs, 0L, (DWORD)length, 0L) == FALSE)
{
return -1;
}
return 0;
}
int unlock(int handle, long ofs, long length)
{
int nt_handle = __fcntl(handle, F_GETOSFD, 0);
if (nt_handle < 0 ||
UnlockFile((DWORD)nt_handle, (DWORD)ofs, 0L, (DWORD)length,
0L) == FALSE)
{
return -1;
}
return 0;
}
#elif defined(__MINGW32__) || defined(__MSVC__)
int waitlock(int handle, long ofs, long length)
{
long offset = tell(handle);
if (offset == -1)
return -1;
lseek(handle, ofs, SEEK_SET);
_locking(handle, 1, length);
lseek(handle, offset, SEEK_SET);
return 0;
}
/*
* THERE SHOULD BE A BETTER WAY TO MAKE A TIMED LOCK !!!!
*/
int waitlock2(int handle, long ofs, long length, long t)
{
int forever = 0;
int rc;
if (t==0)
forever = 1;
t *= 10;
while ((rc = lock(handle, ofs, length)) == -1 && (t > 0 || forever))
{
tdelay(100);
t--;
}
return rc;
}
int lock(int handle, long ofs, long length)
{
long offset = tell(handle);
int r;
if (offset == -1)
return -1;
lseek(handle, ofs, SEEK_SET);
r = _locking(handle, 2, length);
lseek(handle, offset, SEEK_SET);
if (r)
return -1;
return 0;
}
int unlock(int handle, long ofs, long length)
{
long offset = tell(handle);
if (offset == -1)
return -1;
lseek(handle, ofs, SEEK_SET);
_locking(handle, 0, length);
lseek(handle, offset, SEEK_SET);
return 0;
}
/* This #if-#elif-#else-#endif branch doing never!!!
#elif defined(__MSVC__)
#include <io.h>
#include <stdio.h>
int waitlock(int handle, long ofs, long length)
{
while (lock(handle, ofs, length) == -1)
{
tdelay(100);
}
return 0;
}
int waitlock2(int handle, long ofs, long length, long t)
{
int forever = 0;
int rc;
if (t==0)
forever = 1;
t *= 10;
while ((rc = lock(handle, ofs, length)) == -1 && (t > 0 || forever))
{
tdelay(100);
t--;
}
return rc;
}
int lock(int handle, long ofs, long length)
{
long offset = tell(handle);
int r;
if (offset == -1)
return -1;
lseek(handle, ofs, SEEK_SET);
r = locking(handle, 2, length);
lseek(handle, offset, SEEK_SET);
if (r)
return -1;
return 0;
}
int unlock(int handle, long ofs, long length)
{
long offset = tell(handle);
int r;
if (offset == -1)
return -1;
lseek(handle, ofs, SEEK_SET);
r = locking(handle, 0, length);
lseek(handle, offset, SEEK_SET);
if (r)
return -1;
return 0;
}
*/
#elif defined(__BEOS__)
int lock(int handle, long ofs, long length)
{
return 0;
}
int waitlock(int handle, long ofs, long length)
{
return 0;
}
int waitlock2(int handle, long ofs, long length, long t)
{
return 0;
}
int unlock(int handle, long ofs, long length)
{
return 0;
}
int sopen(const char *name, int oflag, int ishared, int mode)
{
int fd = open(name, oflag, mode);
return fd;
}
#elif defined(__UNIX__) && !defined(__BEOS__)
static struct flock* file_lock(short type, long ofs, long length, struct flock *ret)
{
ret->l_type = type;
ret->l_start = ofs;
ret->l_whence = SEEK_SET;
ret->l_len = length;
ret->l_pid = getpid();
return ret;
}
int lock(int handle, long ofs, long length)
{
struct flock fl;
return fcntl(handle, F_SETLK, file_lock(F_WRLCK, ofs, length, &fl));
}
int waitlock(int handle, long ofs, long length)
{
struct flock fl;
return fcntl(handle, F_SETLKW, file_lock(F_WRLCK, ofs, length, &fl));
}
/*
* waitlock2() wait <t> seconds for a lock
*/
int waitlock2(int handle, long ofs, long length, long t)
{
int rc;
struct flock fl;
alarm(t);
rc = fcntl(handle, F_SETLKW, file_lock(F_WRLCK, ofs, length, &fl));
alarm(0);
return rc;
}
int unlock(int handle, long ofs, long length)
{
struct flock fl;
return fcntl(handle, F_SETLK, file_lock(F_UNLCK, ofs, length, &fl));
}
int sopen(const char *name, int oflag, int ishared, int mode)
{
int fd = open(name, oflag, mode);
/* prevent compiler warning */
ishared = ishared;
/*
* I removed this code, 'cause there is no more need for it (i hope so)
*/
/*
#ifndef NO_LOCKING
struct flock fl;
if (fd != -1 && fcntl(fd, F_SETLK,
file_lock((ishared == SH_DENYNONE) ? F_RDLCK : F_WRLCK, 0, 0, &fl)))
{
close(fd);
return -1;
}
#endif
*/
return fd;
}
#else
#ifdef __OS2__
#define INCL_DOSDATETIME
#include <os2.h>
#endif
int waitlock(int handle, long ofs, long length)
{
while (lock(handle, ofs, length) == -1)
{
tdelay(100);
}
return 0;
}
int waitlock2(int handle, long ofs, long length, long t)
{
int forever = 0;
int rc;
if (t==0)
forever = 1;
t *= 10;
while ((rc = lock(handle, ofs, length)) == -1 && (t > 0 || forever))
{
tdelay(100);
t--;
}
return rc;
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1