home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frostbyte's 1980s DOS Shareware Collection
/
floppyshareware.zip
/
floppyshareware
/
DOOG
/
CBASE09.ZIP
/
BLKIO10.ZIP
/
BOPS.C
< prev
next >
Wrap
Text File
|
1989-08-30
|
14KB
|
589 lines
/* Copyright (c) 1989 Citadel */
/* All Rights Reserved */
/* #ident "bops.c 1.1 - 89/07/03" */
#include <bool.h>
#include <errno.h>
/* #include <stdlib.h> */
/* #include <string.h> */
#include "blkio_.h"
/*man---------------------------------------------------------------------------
NAME
b_alloc - allocate memory for block file
SYNOPSIS
#include "blkio_.h"
int b_alloc(bp)
BLKFILE *bp;
DESCRIPTION
The b_alloc function allocates the memory needed by bp. A call to
b_alloc should normally be followed by a call to b_init to construct
the linked list for LRU replacement.
b_alloc will fail if one or more of the following is true:
[EINVAL] bp is not a valid BLKFILE pointer.
[ENOMEM] Enough memory is not available for the
calling process to allocate.
[BENOPEN] bp is not open.
SEE ALSO
b_free.
DIAGNOSTICS
Upon successful completion, a value of 0 is returned. Otherwise, a
value of -1 is returned, and errno set to indicate the error.
------------------------------------------------------------------------------*/
int b_alloc(bp)
BLKFILE *bp;
{
errno = 0;
#ifdef DEBUG
/* validate arguments */
if (!b_valid(bp)) {
BEPRINT;
errno = EINVAL;
return -1;
}
/* check if not open */
if (!(bp->flags & BIOOPEN)) {
BEPRINT;
errno = BENOPEN;
return -1;
}
#endif
/* free any previously allocated storage */
b_free(bp);
/* check if not buffered */
if (bp->bufcnt == 0) {
errno = 0;
return 0;
}
/* allocate buffer storage (header + bufcnt blocks) */
if (bp->blksize == 0) {
BEPRINT;
errno = BEPANIC;
return -1;
}
bp->block_p = (block_t *)calloc(bp->bufcnt + 1, sizeof(block_t));
if (bp->block_p == NULL) {
BEPRINT;
errno = ENOMEM;
return -1;
}
if (!(bp->flags & BIOUSRBUF)) {
bp->blkbuf = calloc(1, bp->hdrsize + bp->bufcnt * bp->blksize);
if (bp->blkbuf == NULL) {
BEPRINT;
free(bp->block_p);
bp->block_p = NULL;
errno = ENOMEM;
return -1;
}
}
errno = 0;
return 0;
}
/*man---------------------------------------------------------------------------
NAME
b_block_p - pointer to block structure
SYNOPSIS
#include "blkio_.h"
block_t *b_block_p(bp, i)
BLKFILE * bp;
size_t i;
DESCRIPTION
b_block_p returns a pointer to the ith block structure in the buffer
list of block file bp. If bp is not a valid open block file or i is
not in the range [0..bp->bufcnt] the results are undefined. b_block_p
is a macro.
------------------------------------------------------------------------------*/
/* b_block_p is #defined in blkio_.h */
/*man---------------------------------------------------------------------------
NAME
b_blkbuf - pointer to block buffer
SYNOPSIS
#include "blkio_.h"
void *b_blkbuf(bp, i)
BLKFILE * bp;
size_t i;
DESCRIPTION
b_blkbuf returns a pointer to the ith buffer in the buffer list of
block file bp. A value of zero for i indicates the header buffer.
If bp is not a valid BLKFILE pointer to an open file or i is not in
the range [0..bp->bufcnt] the results are undefined. b_blkbuf is a
macro.
------------------------------------------------------------------------------*/
/* b_blkbuf is #defined in blkio_.h */
/*man---------------------------------------------------------------------------
NAME
b_free - free memory allocated for block file
SYNOPSIS
#include "blkio_.h"
void b_free(bp)
BLKFILE *bp;
DESCRIPTION
The b_free function frees all memory allocated for block file bp.
If bp is not a valid BLKFILE pointer, no action is taken. User
supplied buffers are not freed.
------------------------------------------------------------------------------*/
void b_free(bp)
BLKFILE *bp;
{
/* validate arguments */
if (!b_valid(bp)) {
BEPRINT;
return;
}
/* free memory */
if (!(bp->flags & BIOUSRBUF)) { /* don't free if user buffer */
if (bp->blkbuf != NULL) {
free(bp->blkbuf);
bp->blkbuf = NULL;
}
}
bp->blkbuf = NULL;
if (bp->block_p != NULL) {
free((void *)bp->block_p);
bp->block_p = NULL;
}
return;
}
/*man---------------------------------------------------------------------------
NAME
b_get - get block from block file
SYNOPSIS
#include "blkio_.h"
int b_get(bp, i)
BLKFILE *bp;
size_t i;
DESCRIPTION
The b_get function reads the ith block in the buffer list from the
block file associated with BLKFILE pointer bp. The number of the block
read is the value of the block number field of the block structure for
that entry in the buffer list. If i has a value of 0, the header is
read. The the read flag is set and all others including the write flag
cleared for that buffer block.
b_get will fail if one or more of the following is true:
[EINVAL] bp is not a valid BLKFILE pointer.
[EINVAL] i is not in the range [0..bp->bufcnt].
[BEEOF] End of file occured before end of block.
[BENBUF] bp is not buffered.
SEE ALSO
b_put.
DIAGNOSTICS
Upon successful completion, a value of 0 is returned. Otherwise, a
value of -1 is returned, and errno set to indicate the error.
------------------------------------------------------------------------------*/
int b_get(bp, i)
BLKFILE * bp;
size_t i;
{
int rs = 0;
#ifdef DEBUG
/* validate arguments */
if (!b_valid(bp)) {
BEPRINT;
errno = EINVAL;
return -1;
}
/* check if not open */
if (!(bp->flags & BIOOPEN)) {
BEPRINT;
errno = BENOPEN;
return -1;
}
/* check if file is not buffered */
if (bp->bufcnt == 0) {
BEPRINT;
errno = BENBUF;
return -1;
}
/* validate arguments */
if ((i > bp->bufcnt)) {
BEPRINT;
errno = EINVAL;
return -1;
}
/* check if block number set */
if ((b_block_p(bp, i)->bn == 0) && (i != 0)) {
BEPRINT;
errno = BEPANIC;
return -1;
}
#endif
/* check if block needs to be written to disk */
if (b_block_p(bp, i)->flags & BLKWRITE) {
errno = BEPANIC;
return -1;
}
/* read block from file */
if (i == 0) {
rs = b_ugetf(bp, (bpos_t)0, (size_t)0, b_blkbuf(bp, (size_t)0), bp->hdrsize);
} else {
rs = b_ugetf(bp, b_block_p(bp, i)->bn, (size_t)0, b_blkbuf(bp, i), bp->blksize);
}
if (rs == -1) {
BEPRINT;
return -1;
}
/* set read flag and clear all others */
b_block_p(bp, i)->flags = BLKREAD;
errno = 0;
return 0;
}
/*man---------------------------------------------------------------------------
NAME
b_init - initialize block file
SYNOPSIS
#include "blkio_.h"
int b_init(bp)
BLKFILE *bp;
DESCRIPTION
The b_init function initializes a block file buffer list of the block
file associated with BLKFILE pointer bp to empty and constructs the
linked list.
b_init will fail if one or more of the following is true:
[EINVAL] bp is not a valid block file.
DIAGNOSTICS
Upon successful completion, a value of 0 is returned. Otherwise, a
value of -1 is returned, and errno set to indicate the error.
------------------------------------------------------------------------------*/
int b_init(bp)
BLKFILE *bp;
{
size_t i = 0;
errno = 0;
#ifdef DEBUG
/* validate arguments */
if (!b_valid(bp)) {
BEPRINT;
errno = EINVAL;
return -1;
}
/* check if not open */
if (!(bp->flags & BIOOPEN)) {
BEPRINT;
errno = BENOPEN;
return -1;
}
#endif
/* initialize head and tail of list */
bp->most = 0;
bp->least = 0;
/* check if not buffered */
if (bp->bufcnt == 0) {
errno = 0;
return 0;
}
/* initialize linked list */
bp->most = bp->bufcnt;
bp->least = 1;
for (i = 1; i <= bp->bufcnt; i++) {
b_block_p(bp, i)->bn = 0;
b_block_p(bp, i)->flags = 0;
b_block_p(bp, i)->more = i + 1;
b_block_p(bp, i)->less = i - 1;
}
b_block_p(bp, bp->most)->more = 0;
b_block_p(bp, bp->least)->less = 0;
/* initialize block structure for header */
b_block_p(bp, (size_t)0)->bn = 0;
b_block_p(bp, (size_t)0)->flags = 0;
b_block_p(bp, (size_t)0)->more = 0;
b_block_p(bp, (size_t)0)->less = 0;
/* scrub buffer storage area */
memset(bp->blkbuf, 0, bp->hdrsize + bp->bufcnt * bp->blksize);
errno = 0;
return 0;
}
/*man---------------------------------------------------------------------------
NAME
b_mkmru - make most recently used block
SYNOPSIS
#include "blkio_.h"
int b_mkmru(bp, i)
BLKFILE *bp;
size_t i;
DESCRIPTION
The b_mkmru function moves the ith block in the buffer list to the
most recently used end of the buffer list.
b_mkmru will fail if one or more of the following is true:
[EINVAL] bp is not a valid block file.
[EINVAL] i is not in the range [1..bp->bufcnt].
[BENBUF] bp is not buffered.
DIAGNOSTICS
Upon successful completion, a value of 0 is returned. Otherwise, a
value of -1 is returned, and errno set to indicate the error.
------------------------------------------------------------------------------*/
int b_mkmru(bp, i)
BLKFILE *bp;
size_t i;
{
size_t more = 0;
size_t less = 0;
errno = 0;
#ifdef DEBUG
/* validate arguments */
if (!b_valid(bp)) {
BEPRINT;
errno = EINVAL;
return -1;
}
/* check if not open */
if (!(bp->flags & BIOOPEN)) {
BEPRINT;
errno = BENOPEN;
return -1;
}
/* check if file is not buffered */
if (bp->bufcnt == 0) {
BEPRINT;
errno = BENBUF;
return -1;
}
/* validate arguments */
if ((i < 1) || (i > bp->bufcnt)) {
BEPRINT;
errno = EINVAL;
return -1;
}
#endif
/* check block addresses */
more = b_block_p(bp, i)->more;
less = b_block_p(bp, i)->less;
if ((more > bp->bufcnt) || (less > bp->bufcnt)) {
BEPRINT;
errno = BEPANIC;
return -1;
}
/* check if already most recently used */
if (more == 0) {
errno = 0;
return 0;
}
/* remove block i from linked list */
b_block_p(bp, more)->less = less;
if (less != 0) {
b_block_p(bp, less)->more = more;
} else {
bp->least = more;
}
/* connect ith block as most recently used */
b_block_p(bp, i)->more = 0;
b_block_p(bp, i)->less = bp->most;
b_block_p(bp, bp->most)->more = i;
bp->most = i;
errno = 0;
return 0;
}
/*man---------------------------------------------------------------------------
NAME
b_put - put block into block file
SYNOPSIS
#include "blkio_.h"
int b_put(bp, i)
BLKFILE *bp;
size_t i;
DESCRIPTION
The b_put function writes the ith block in the buffer list to
the file. The number of the block written is the value of the block
number field of the ith entry in the buffer list. If i has a
value of 0, the header is written. If the write flag is not set,
nothing is written. After writing, the write flag is cleared.
b_put will fail if one or more of the following is true:
[EINVAL] bp is not a valid block file.
[EINVAL] i is not in the range [0..bp->bufcnt].
[BENBUF] bp is not buffered.
SEE ALSO
b_get.
DIAGNOSTICS
Upon successful completion, a value of 0 is returned. Otherwise, a
value of -1 is returned, and errno set to indicate the error.
------------------------------------------------------------------------------*/
int b_put(bp, i)
BLKFILE * bp;
size_t i;
{
int rs = 0;
#ifdef DEBUG
/* validate arguments */
if (!b_valid(bp)) {
BEPRINT;
errno = EINVAL;
return -1;
}
/* check if not open */
if (!(bp->flags & BIOOPEN)) {
BEPRINT;
errno = BENOPEN;
return -1;
}
/* check if file is not buffered */
if (bp->bufcnt == 0) {
BEPRINT;
errno = BENBUF;
return -1;
}
/* validate arguments */
if (i > bp->bufcnt) {
BEPRINT;
errno = EINVAL;
return -1;
}
#endif
/* check if block doesn't need to be written to disk */
if (!(b_block_p(bp, i)->flags & BLKWRITE)) {
errno = 0;
return 0;
}
/* check for inconsistent read flag setting */
if (!(b_block_p(bp, i)->flags & BLKREAD)) {
BEPRINT;
errno = BEPANIC;
return 0;
}
/* write block to disk */
if (i == 0) {
rs = b_uputf(bp, (bpos_t)0, (size_t)0, b_blkbuf(bp, (size_t)0), bp->hdrsize);
} else {
rs = b_uputf(bp, b_block_p(bp, i)->bn, (size_t)0, b_blkbuf(bp, i), bp->blksize);
}
if (rs == -1) {
BEPRINT;
return -1;
}
/* clear all but read flag */
b_block_p(bp, i)->flags = BLKREAD;
errno = 0;
return 0;
}
/*man---------------------------------------------------------------------------
NAME
b_valid - validate block file
SYNOPSIS
#include "blkio_.h"
bool b_valid(bp)
BLKFILE *bp;
DESCRIPTION
The b_valid function determines if bp points to a valid block file
control structure. If it is valid, TRUE is returned. If not,
then FALSE is returned.
------------------------------------------------------------------------------*/
bool b_valid(bp)
BLKFILE *bp;
{
if ((bp < biob) || (bp > (biob + BOPEN_MAX - 1))) {
return FALSE;
}
if (((size_t)((char *)bp - (char *)biob)) % sizeof(biob[0]) != 0) {
return FALSE;
}
return TRUE;
}