home *** CD-ROM | disk | FTP | other *** search
- /*-----------------------------------------------------------------------*
- * filename - locking.c
- *
- * function(s)
- * wait1 - wait 1 second
- * locking - sets or resets file sharing locks (MSC compatible)
- *-----------------------------------------------------------------------*/
-
- /*
- * C/C++ Run Time Library - Version 5.0
- *
- * Copyright (c) 1991, 1992 by Borland International
- * All Rights Reserved.
- *
- */
-
-
- #include <io.h>
- #include <_io.h>
- #include <dos.h>
- #include <errno.h>
- #include <sys\locking.h>
-
-
- /*-----------------------------------------------------------------------*
-
- Name wait1 - wait 1 second
-
- Usage void wait1(void);
-
- Prototype in local
-
- Description wait1() uses _dos_gettime() in a spin loop to wait 1 second.
-
- Return value No value is returned.
-
- Portability Unique to MS-DOS. On multi-tasking operating systems
- this should be rewritten to do a wait.
-
- *------------------------------------------------------------------------*/
-
- static void pascal near wait1(void)
- {
- struct dostime_t start, end;
- unsigned char endsec;
-
- /* Get current time.
- */
- _dos_gettime(&start);
- if (start.second == 59)
- endsec = 0;
- else
- endsec = start.second + 1;
-
- /* Wait for second to change.
- */
- do {
- _dos_gettime(&end);
- } while (end.second == start.second);
-
- /* Wait for hundredths of seconds to catch up.
- */
- while (end.second == endsec && end.hsecond < start.hsecond) {
- _dos_gettime(&end);
- }
- }
-
- /*-----------------------------------------------------------------------*
-
- Name locking - sets file sharing locks
-
- Usage int locking(int handle, int mode, long length);
-
- Prototype in io.h
-
- Description locking provides an interface to the MS-DOS
- 3.x file-sharing mechanism. The region to be locked
- or unlocked starts at the current file position;
- the size of the region is given by length.
-
- The mode parameter specifies the action (values
- for mode are given in <sys\locking.h>):
-
- LK_LOCK lock the region; if unsuccessful, try
- once a second for 10 seconds before
- giving up.
- LK_NBLCK lock the region, if unsuccessful, give
- up immediately.
- LK_NBRLCK Same as LK_NBLCK.
- LK_RCLK Same as LK_LOCK.
- LK_UNLCK Unlock the region, which must have
- been previously locked.
-
- Locks can be placed on arbitrary, non-overlapping regions of
- any file. A program attempting to read or write into a
- locked region will retry the operation three times. If all
- three retries fail, the call fails with an error.
-
- unlock removes lock; to avoid error, lock must be removed
- before a file is closed. A program must release all lock(s)
- before completing.
-
- Return value Locking return 0 on success. On failure, -1 is returned,
- and errno is set to one of the following:
-
- EACCESS File already locked or unlocked
- EBADF Bad file number
- EDEADLOCK File cannot be locked after 10 retries
- (mode is LK_LOCK or LK_RLCK)
- EINVAL Invalid mode
-
-
- Portability Unique to MS-DOS 3.x. Older versions of MS-DOS do
- not support these calls.
-
- Note Compatible with Microsoft C. Not the same as lock().
-
-
- *------------------------------------------------------------------------*/
-
- int _FARFUNC locking(int handle, int mode, long length)
- {
- int tries;
- long offset;
-
- /* Get current file offset, which gives the start of
- * the region to be locked or unlocked. This also
- * verifies the file handle.
- */
- if (_dos_seek(handle,0L,SEEK_CUR,&offset) != 0)
- return (-1);
-
- switch (mode)
- {
- case LK_LOCK:
- case LK_RLCK:
-
- /* Try 10 times, once every second, to lock the file.
- */
- for (tries = 1; tries <= 10; tries++)
- {
- if (_dos_lock(handle,offset,length) == 0)
- return (0); /* success */
- if (errno != EACCES) /* not a locking violation? */
- return (-1); /* return right away */
- wait1(); /* failed - try again 1 sec later */
- }
- errno = EDEADLOCK; /* give up */
- return (-1);
-
- case LK_NBLCK:
- case LK_NBRLCK:
-
- /* Lock the region, give up immediately if not sucessful.
- */
- return (_dos_lock(handle,offset,length) == 0 ? 0 : -1);
-
- case LK_UNLCK:
-
- /* Unlock the region.
- */
- return (_dos_unlock(handle,offset,length) == 0 ? 0 : -1);
-
- default:
- errno = EINVAL;
- return (-1);
- }
- }
-