campo-sirio/cb5/f4lock.c

376 lines
7.5 KiB
C
Raw Normal View History

/* f4lock.c (c)Copyright Sequiter Software Inc., 1990-1994. All rights reserved. */
#include "d4all.h"
#ifdef S4IBMOS2
#define INCL_DOSFILEMGR
#include <os2.h>
#ifndef NO_ERROR
#define NO_ERROR 0
#define ERROR_LOCK_VIOLATION 33
#define S4BYTE_DEFINED
#endif
#endif
#ifndef S4UNIX
#ifdef __TURBOC__
#pragma hdrstop
#endif
#endif
#ifdef S4TEMP
#include "t4test.h"
#endif
#include <time.h>
#ifndef S4SINGLE
#ifdef S4UNIX
#ifdef S4LOCKF
#include <unistd.h>
#else
#ifndef S4MACINTOSH
#include <sys/locking.h>
#endif
#endif
#else
#ifndef S4WIN32
#ifndef __TURBOC__
#ifndef S4IBMOS2
#include <sys\locking.h>
#define S4LOCKING
#endif
#endif
#ifdef __ZTC__
extern int errno ;
#endif
#ifdef _MSC_VER
#include <sys\types.h>
#endif
#ifdef __TURBOC__
#ifndef S4OS2
#ifdef __BORLANDC__
#include <sys\locking.h> /* Borland C++ compilers */
#else
#include <locking.h> /* Turbo C++ for DOS compilers */
/* #include <sys\locking.h> */ /* Turbo C++ for Win compilers */
#endif
/* extern int cdecl errno ; */
#endif
#endif
#include <sys\stat.h>
#include <share.h>
#endif
#endif
#endif
#include <fcntl.h>
#include <errno.h>
#ifdef S4ERRNO
extern int errno ;
#endif
#ifdef S4LOCK_HOOK
/* Add alternative code to specify how to handle locking failures.
This function is commented out to give you the option of defining
it in your own separate source code file.
WARNING: The printed documentation does not mention the extra
parameter of information containing the number
of locking tries so far on this attempted file lock.
int file4lock_hook( CODE4 *cb, char *file_name, long offset, long num_bytes, int num_tries )
{
return 0 ;
}
*/
#endif
int S4FUNCTION file4lock( FILE4 *file, long pos_start, long num_bytes )
{
#ifdef S4SINGLE
return 0 ;
#else
int rc, num_attempts ;
#ifdef S4IBMOS2
struct LockStrc
{
long FileOffset ;
long RangeLength ;
} L4RANGE ;
#endif
#ifdef S4MACINTOSH
ParamBlockRec MACParmBlk ;
#endif
#ifdef S4DEBUG
if ( file == 0 )
e4severe( e4parm, E4_F4LOCK ) ;
#ifndef S4MDX
if ( num_bytes < 0 || pos_start < 0 )
e4severe( e4parm, E4_F4LOCK ) ;
#endif
#endif
if ( file->is_read_only || file->is_exclusive ) /* don't check error code */
return 0 ;
if ( file->code_base->error_code < 0 )
return -1 ;
#ifdef S4LOCK_HOOK
num_attempts = 0 ;
#else
num_attempts = file->code_base->lock_attempts ;
if ( num_attempts == 0 )
num_attempts = 1 ;
#endif
errno = 0 ;
for( ;; )
{
#ifdef S4LOCKING
#ifdef S4WINDOWS
_llseek( file->hand, pos_start, 0 ) ;
#else
lseek( file->hand, pos_start, 0 ) ;
#endif
#ifdef S4LOCKF
if ( num_attempts == -1 ) /* sleep until lock */
rc = lockf( file->hand, F_LOCK, num_bytes ) ;
else
rc = lockf( file->hand, F_TLOCK, num_bytes ) ;
#else
rc = locking( file->hand, LK_NBLCK, num_bytes ) ;
#endif
#else
#ifdef S4IBMOS2
L4RANGE.FileOffset = pos_start ;
L4RANGE.RangeLength = num_bytes ;
rc = DosSetFileLocks( (HFILE) file->hand, 0L,(PFILELOCK) &L4RANGE, 100L, 0L ) ;
#endif
#ifdef S4MACINTOSH
MACParmBlk.ioParam.ioRefNum = file->hand ;
MACParmBlk.ioParam.ioReqCount = num_bytes ;
MACParmBlk.ioParam.ioPosMode = fsFromStart ;
MACParmBlk.ioParam.ioPosOffset = pos_start ;
PBLockRange( &MACParmBlk, FALSE ) ;
rc = MACParmBlk.ioParam.ioResult ;
#endif
#ifdef __TURBOC__
rc = lock( file->hand, pos_start, num_bytes ) ;
#endif
#ifdef S4WIN32
rc = LOWORD(pos_start) ;
rc = HIWORD(pos_start) ;
rc = LOWORD(num_bytes) ;
rc = HIWORD(num_bytes) ;
if ( LockFile( (HANDLE)file->hand, LOWORD(pos_start), HIWORD(pos_start),
LOWORD(num_bytes), HIWORD(num_bytes) ) )
rc = NO_ERROR ;
else
rc = GetLastError() ;
#endif
#endif
#ifdef __ZTC__
if (rc == 0 || errno == 1)
#else
#ifdef S4IBMOS2
if (rc == NO_ERROR )
#else
#ifdef S4MACINTOSH
if (rc == 0 )
#else
#ifdef S4WIN32
if (rc == NO_ERROR )
#else
if (rc == 0 || errno == EINVAL)
#endif
#endif
#endif
#endif
{
#ifdef S4LOCK_CHECK
l4lock_save( file->hand, pos_start, num_bytes ) ;
#endif
return 0 ;
}
if ( rc == 0 )
{
#ifdef S4LOCK_CHECK
l4lock_save( file->hand, pos_start, num_bytes ) ;
#endif
#ifndef S4OPTIMIZE_OFF
file4set_write_opt( file, 1 ) ;
#endif
return 0 ;
}
#ifdef S4WIN32
if ( rc != ERROR_LOCK_VIOLATION )
#else
#ifdef _MSC_VER
#if _MSC_VER == 600
#ifdef S4WINDOWS
if (errno != -1 ) /* Microsoft 6.00a does not return */
#else /* valid 'errno' under Windows, */
if (errno != EACCES) /* but performs locking correctly */
#endif
#else
if (errno != EACCES)
#endif
#else
#ifdef __ZTC__
if (errno != 33)
#else
#ifdef S4IBMOS2
if ( rc != ERROR_LOCK_VIOLATION )
#else
#ifdef S4MACINTOSH
if (rc != fLckdErr )
#else
if (errno != EACCES && errno != 0 )
#endif
#endif
#endif
#endif
#endif
return e4( file->code_base, e4lock, file->name ) ;
#ifdef S4LOCK_HOOK
rc = file4lock_hook( file->code_base, file->name, pos_start, num_bytes,
++num_attempts ) ;
if( rc )
return rc ;
#else
if ( num_attempts == 1 )
return r4locked ;
if ( num_attempts > 1 )
num_attempts-- ;
#endif
#ifdef S4TEMP
if ( d4display_quit( &display ) )
e4severe( e4result, E4_RESULT_EXI ) ;
#endif
u4delay_sec() ; /* wait a second & try lock again */
}
#endif
}
int S4FUNCTION file4unlock( FILE4 *file, long pos_start, long num_bytes )
{
#ifndef S4SINGLE
int rc ;
#ifdef S4IBMOS2
struct LockStrc
{
long FileOffset ;
long RangeLength ;
} L4RANGE ;
#endif
#ifdef S4MACINTOSH
ParamBlockRec MACParmBlk ;
#endif
#ifdef S4DEBUG
if ( file == 0 )
e4severe( e4parm, E4_F4UNLOCK ) ;
#ifndef S4MDX
if ( num_bytes < 0 || pos_start < 0 )
e4severe( e4parm, E4_F4UNLOCK ) ;
#endif
#endif
if ( file->is_read_only || file->is_exclusive )
return 0 ;
#ifndef S4OPTIMIZE_OFF
file4set_write_opt( file, 0 ) ;
#endif
#ifdef S4LOCK_CHECK
l4lock_remove( file->hand, pos_start, num_bytes ) ;
#endif
errno = 0 ;
#ifdef S4LOCKING
#ifdef S4WINDOWS
_llseek( file->hand, pos_start, 0 ) ;
#else
lseek( file->hand, pos_start, 0 ) ;
#endif
#ifdef S4LOCKF /* lockf() replaces locking() for SUN OS, AT&T */
rc = lockf( file->hand, F_ULOCK, num_bytes ) ;
#else
rc = locking( file->hand, LK_UNLCK, num_bytes ) ;
#endif
#else
#ifdef S4IBMOS2
L4RANGE.FileOffset = pos_start ;
L4RANGE.RangeLength = num_bytes ;
rc = DosSetFileLocks( (HFILE)file->hand, (PFILELOCK) &L4RANGE, 0L, 100L , 0L ) ;
#endif
#ifdef S4MACINTOSH
MACParmBlk.ioParam.ioRefNum = file->hand ;
MACParmBlk.ioParam.ioReqCount = num_bytes ;
MACParmBlk.ioParam.ioPosMode = fsFromStart ;
MACParmBlk.ioParam.ioPosOffset = pos_start ;
PBUnlockRange( &MACParmBlk, FALSE ) ;
rc = MACParmBlk.ioParam.ioResult ;
#endif
#ifdef __TURBOC__
rc = unlock( file->hand, pos_start, num_bytes ) ;
#endif
#ifdef S4WIN32
if ( UnlockFile( (HANDLE)file->hand, LOWORD(pos_start), HIWORD(pos_start),
LOWORD(num_bytes), HIWORD(num_bytes) ) )
rc = NO_ERROR ;
else
rc = -1 ;
#endif
#endif
#ifdef __ZTC__
if (rc < 0 && errno != 1 )
#else
#ifdef S4IBMOS2
if (rc != NO_ERROR )
#else
#ifdef S4MACINTOSH
if (rc != 0 )
#else
#ifdef S4WIN32
if (rc != NO_ERROR )
#else
if (rc < 0 && errno != EINVAL )
#endif
#endif
#endif
#endif
return e4( file->code_base, e4unlock, file->name ) ;
#endif
return 0 ;
}