home *** CD-ROM | disk | FTP | other *** search
- /*
- * Turbo C CTCLIB.C module
- *
- * This sample is setup for the MS-DOS 3.1/2/3 Operating System
- * and the BORLAND INTERNATIONAL TURBO C Compiler.
- * (It will also run in DOS 2 and DOS 3.0 environments.)
- *
- * Due to the highly restrictive nature of the DOS 3.1 locking protocols
- * (i.e., you cannot READ a region of a file locked by another process),
- * we have provided a work-around which requires a dummy file as file
- * number zero. In particular, the zeroth data file of each ISAM parameter
- * file should be a dummy file, have a record length of 128 bytes,
- * and file mode parameters indicating a SHARED, PERMANENT, FIXED length
- * file. Then, instead of actually locking the files in use, c-tree will
- * place ct_locks on corresponding regions of the dummy file.
- *
- * Due to the use of a dummy lock file, it is not necessary for the
- * lock routines to increment and decrement the lokcnt member which
- * is used for checking virtual files.
- *
- * (MS-DOS is a trademark of Microsoft)
- *
- * This program is the CONFIDENTIAL and PROPRIETARY property
- * of FairCom(R) Corporation. Any unauthorized use, reproduction or
- * transfer of this program is strictly prohibited.
- *
- * Copyright (c) 1985, 1986, 1987, 1988, 1989 FairCom
- * (Subject to limited distribution and
- * restricted disclosure only.)
- * *** ALL RIGHTS RESERVED ***
- *
- * 4006 West Broadway
- * Columbia, MO 65203
- *
- *
- * c-tree(R) Version 4.3
- * Release C
- * February 7, 1989 17:30
- *
- */
-
- #include "ctstdr.h" /* standard i/o header */
- #undef EXTERN
- #define EXTERN /* */
- #include "ctoptn.h" /* c-tree configuration options */
- #include "cterrc.h" /* c-tree error codes */
- #include "ctstrc.h" /* c-tree data structures */
- #include "ctgvar.h" /* c-tree global variables */
-
- #include <share.h> /* From Borland */
- #include <stat.h> /* From Borland */
-
- #define INFINITY 3000 /* loop termination count waiting for lock */
- #define LEFT_SHIFT 24 /* controls dummy lock capacity */
- /* 25 => 62 files: 32M fixed records or */
- /* 32MB var len file */
- /* 24 => 126 files: 16M fixed records or */
- /* 16MB var len file */
- /* 23 => 254 files: 8M fixed records or */
- /* 8MB var len file */
- /* 22 => 510 files: 4M fixed records or */
- /* 4MB var len file */
-
- COUNT ctseek(),uerr();
-
- RNDFILE mbopen(ctnum,opmode)
- PFAST CTFILE *ctnum;
- COUNT opmode; /* EXCLUSIVE or SHARED */
- {
- RNDFILE retval;
- int acflag,shflag;
-
- COUNT vtclose();
-
- ctnum->sekpos = 0L;
- acflag = BUPDATE;
- #ifdef FPUTFGET
- if (opmode & SHARED)
- shflag = SH_DENYNO;
- else if (opmode & READFIL) {
- shflag = SH_DENYWR;
- acflag = (O_BINARY | O_RDONLY);
- } else
- shflag = SH_DENYRW;
- #else
- shflag = 0;
- #endif
-
- if (!(opmode & PERMANENT) && ct_numvfil >= MAXVFIL)
- vtclose();
-
- if ((retval = _open(ctnum->flname,(acflag | shflag))) < 0)
- if (vtclose() == YES)
- retval = _open(ctnum->flname,(acflag | shflag));
-
- if (!(opmode & PERMANENT) && retval >= 0)
- ct_numvfil++;
-
- return(retval);
- }
-
- /* ------------------------------------------------------------ */
-
- RNDFILE mbcrat(ctnum)
- PFAST CTFILE *ctnum;
- {
- RNDFILE retval;
-
- COUNT vtclose();
-
- ctnum->sekpos = 0L;
- if (!(ctnum->flmode & PERMANENT) && ct_numvfil >= MAXVFIL)
- vtclose();
-
- if ((retval = open(ctnum->flname,
- BCREATE,(S_IREAD | S_IWRITE))) < 0)
- if (vtclose() == YES)
- retval = open(ctnum->flname,
- BCREATE,
- (S_IREAD | S_IWRITE));
-
- if (!(ctnum->flmode & PERMANENT) && retval >= 0)
- ct_numvfil++;
-
- return(retval);
- }
-
- /* ------------------------------------------------------------ */
-
- COUNT mbsave(ctnum)
- PFAST CTFILE *ctnum;
- {
- COUNT mbclos();
- RNDFILE mbopen();
-
- if (mbclos(ctnum,ctnum->flmode))
- return(uerr(FSAV_ERR));
- else if ((ctnum->fd = mbopen(ctnum,ctnum->flmode)) < 0)
- return(uerr(FSAV_ERR));
- else
- return(NO_ERROR);
- }
-
- VOID flushdos(datno)
- COUNT datno;
- {
- bdos(13,0,0);
- }
-
- #ifndef CTSERVER
-
- /* --------------------------------------------------------------------
- LOCK index node
- */
-
- COUNT LOCK(node,knum) /* node == 0 => header */
- LONG node;
- PFAST KEYFILE *knum;
- {
-
- /*
- * c-tree node locking protocol is guaranteed to be deadlock free. Therefore,
- * if a lock is unsucessful, this routine forces a short delay and then
- * attempts the lock again. The INFINITY parameter allows one to avoid
- * an infinite loop if there is a bug in the lock routines. Theoretically,
- * the while loop should never run indefinitely.
- */
-
-
- #ifdef FPUTFGET
-
- COUNT dummy,tries;
-
- tries = 0;
- knum -= knum->kmem;
- if (!(knum->flmode & NONEXCLUSIVE))
- return(NO_ERROR);
-
- /*
- * Notice how a lock region is converted to a phantom region of the dummy
- * file and the lock is applied to file zero (whose control structure is
- * pointed to by the global variable ct_key).
- */
- if (knum->clstyp != VAT_CLOSE)
- node /= knum->recsiz;
- node |= ((LONG) knum->filnum << LEFT_SHIFT);
- while (lock(ct_key->fd,node,1L))
- if (tries++ > INFINITY)
- return(uerr(LNOD_ERR));
- else
- /* delay and try again */
- for (dummy = 0; dummy++ < INFINITY; )
- ;
- return(NO_ERROR);
- #else
- return(NO_ERROR);
- #endif
-
- }
-
- /* --------------------------------------------------------------------
- UNLOCK index file node
- */
-
- COUNT UNLOCK(node,knum)
- LONG node;
- PFAST KEYFILE *knum;
- {
-
- #ifdef FPUTFGET
- knum -= knum->kmem;
- if (!(knum->flmode & NONEXCLUSIVE))
- return(NO_ERROR);
-
- if (knum->clstyp != VAT_CLOSE)
- node /= knum->recsiz;
- node |= ((LONG) knum->filnum << LEFT_SHIFT);
- if (unlock(ct_key->fd,node,1L))
- return(uerr(UNOD_ERR));
- else
- return(NO_ERROR);
- #else
- return(NO_ERROR);
- #endif
-
- }
-
-
- /* --------------------------------------------------------------------
- LOCK data record
- */
-
- COUNT DLOCK(recbyt,dnum) /* recbyt == 0 => header record */
- POINTER recbyt;
- PFAST DATFILE *dnum;
- {
-
- /*
- * the data record ct_locks are NOT guaranteed to be deadlock free. Therefore,
- * except for the header record which is only locked by internal c-tree
- * maintenance requests, the data record lock routine returns instead of
- * looping when a lock is denied because of a competing lock. The application
- * program must deal with the appropriate action if a lock is denied to a
- * data record.
- */
-
- #ifdef FPUTFGET
- COUNT dummy,tries,test;
- LONG actbyt;
-
- if (!(dnum->flmode & NONEXCLUSIVE))
- return(NO_ERROR);
-
- actbyt = recbyt;
- tries = 0;
- if (dnum->clstyp != VAT_CLOSE)
- recbyt /= dnum->reclen;
- recbyt |= ((LONG) dnum->filnum << LEFT_SHIFT);
- while ((test = lock(ct_key->fd,recbyt,1L)) &&
- actbyt == DRNZERO) /* i.e., the header record is locked */
- if (tries++ > INFINITY)
- return(uerr(DLOK_ERR));
- else
- /* delay and try again */
- for (dummy = 0; dummy++ < INFINITY; )
- ;
-
- if (!test) /* lock request is successful! */
- return(NO_ERROR);
- else
- return(uerr(DLOK_ERR));
- #else
- return(NO_ERROR);
- #endif
-
- }
-
- COUNT RLOCK(recbyt,dnum)
- POINTER recbyt;
- PFAST DATFILE *dnum;
- {
- return(NO_ERROR);
- }
-
- /* --------------------------------------------------------------------
- UNLOCK data record
- */
-
- COUNT UDLOCK(recbyt,dnum)
- POINTER recbyt;
- PFAST DATFILE *dnum;
- {
-
- #ifdef FPUTFGET
- if (!(dnum->flmode & NONEXCLUSIVE))
- return(NO_ERROR);
-
- if (dnum->clstyp != VAT_CLOSE)
- recbyt /= dnum->reclen;
- recbyt |= ((LONG) dnum->filnum << LEFT_SHIFT);
- if (unlock(ct_key->fd,recbyt,1L))
- return(uerr(UDLK_ERR));
- else
- return(NO_ERROR);
-
- #else
- return(NO_ERROR);
- #endif
-
- }
-
- #endif
-
- /* end of ctclib.tc */
-