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 >
Text File  |  1989-08-30  |  14KB  |  589 lines

  1. /*    Copyright (c) 1989 Citadel    */
  2. /*       All Rights Reserved        */
  3.  
  4. /* #ident    "bops.c    1.1 - 89/07/03" */
  5.  
  6. #include <bool.h>
  7. #include <errno.h>
  8. /* #include <stdlib.h> */
  9. /* #include <string.h> */
  10. #include "blkio_.h"
  11.  
  12. /*man---------------------------------------------------------------------------
  13. NAME
  14.      b_alloc - allocate memory for block file
  15.  
  16. SYNOPSIS
  17.      #include "blkio_.h"
  18.  
  19.      int b_alloc(bp)
  20.      BLKFILE *bp;
  21.  
  22. DESCRIPTION
  23.      The b_alloc function allocates the memory needed by bp.  A call to
  24.      b_alloc should normally be followed by a call to b_init to construct
  25.      the linked list for LRU replacement.
  26.  
  27.      b_alloc will fail if one or more of the following is true:
  28.  
  29.      [EINVAL]       bp is not a valid BLKFILE pointer.
  30.      [ENOMEM]       Enough memory is not available for the
  31.                     calling process to allocate.
  32.      [BENOPEN]      bp is not open.
  33.  
  34. SEE ALSO
  35.      b_free.
  36.  
  37. DIAGNOSTICS
  38.      Upon successful completion, a value of 0 is returned.  Otherwise, a
  39.      value of -1 is returned, and errno set to indicate the error.
  40.  
  41. ------------------------------------------------------------------------------*/
  42. int b_alloc(bp)
  43. BLKFILE *bp;
  44. {
  45.     errno = 0;
  46.  
  47. #ifdef DEBUG
  48.     /* validate arguments */
  49.     if (!b_valid(bp)) {
  50.         BEPRINT;
  51.         errno = EINVAL;
  52.         return -1;
  53.     }
  54.  
  55.     /* check if not open */
  56.     if (!(bp->flags & BIOOPEN)) {
  57.         BEPRINT;
  58.         errno = BENOPEN;
  59.         return -1;
  60.     }
  61. #endif
  62.  
  63.     /* free any previously allocated storage */
  64.     b_free(bp);
  65.  
  66.     /* check if not buffered */
  67.     if (bp->bufcnt == 0) {
  68.         errno = 0;
  69.         return 0;
  70.     }
  71.  
  72.     /* allocate buffer storage (header + bufcnt blocks) */
  73.     if (bp->blksize == 0) {
  74.         BEPRINT;
  75.         errno = BEPANIC;
  76.         return -1;
  77.     }
  78.     bp->block_p = (block_t *)calloc(bp->bufcnt + 1, sizeof(block_t));
  79.     if (bp->block_p == NULL) {
  80.         BEPRINT;
  81.         errno = ENOMEM;
  82.         return -1;
  83.     }
  84.     if (!(bp->flags & BIOUSRBUF)) {
  85.         bp->blkbuf = calloc(1, bp->hdrsize + bp->bufcnt * bp->blksize);
  86.         if (bp->blkbuf == NULL) {
  87.             BEPRINT;
  88.             free(bp->block_p);
  89.             bp->block_p = NULL;
  90.             errno = ENOMEM;
  91.             return -1;
  92.         }
  93.     }
  94.  
  95.     errno = 0;
  96.     return 0;
  97. }
  98.  
  99. /*man---------------------------------------------------------------------------
  100. NAME
  101.      b_block_p - pointer to block structure
  102.  
  103. SYNOPSIS
  104.      #include "blkio_.h"
  105.  
  106.      block_t *b_block_p(bp, i)
  107.      BLKFILE * bp;
  108.      size_t    i;
  109.  
  110. DESCRIPTION
  111.      b_block_p returns a pointer to the ith block structure in the buffer
  112.      list of block file bp.  If bp is not a valid open block file or i is
  113.      not in the range [0..bp->bufcnt] the results are undefined.  b_block_p
  114.      is a macro.
  115.  
  116. ------------------------------------------------------------------------------*/
  117. /* b_block_p is #defined in blkio_.h */
  118.  
  119. /*man---------------------------------------------------------------------------
  120. NAME
  121.      b_blkbuf - pointer to block buffer
  122.  
  123. SYNOPSIS
  124.      #include "blkio_.h"
  125.  
  126.      void *b_blkbuf(bp, i)
  127.      BLKFILE * bp;
  128.      size_t    i;
  129.  
  130. DESCRIPTION
  131.      b_blkbuf returns a pointer to the ith buffer in the buffer list of
  132.      block file bp.  A value of zero for i indicates the header buffer.
  133.      If bp is not a valid BLKFILE pointer to an open file or i is not in
  134.      the range [0..bp->bufcnt] the results are undefined.  b_blkbuf is a
  135.      macro.
  136.  
  137. ------------------------------------------------------------------------------*/
  138. /* b_blkbuf is #defined in blkio_.h */
  139.  
  140. /*man---------------------------------------------------------------------------
  141. NAME
  142.      b_free - free memory allocated for block file
  143.  
  144. SYNOPSIS
  145.      #include "blkio_.h"
  146.  
  147.      void b_free(bp)
  148.      BLKFILE *bp;
  149.  
  150. DESCRIPTION
  151.      The b_free function frees all memory allocated for block file bp.
  152.      If bp is not a valid BLKFILE pointer, no action is taken.  User
  153.      supplied buffers are not freed.
  154.  
  155. ------------------------------------------------------------------------------*/
  156. void b_free(bp)
  157. BLKFILE *bp;
  158. {
  159.     /* validate arguments */
  160.     if (!b_valid(bp)) {
  161.         BEPRINT;
  162.         return;
  163.     }
  164.  
  165.     /* free memory */
  166.     if (!(bp->flags & BIOUSRBUF)) {        /* don't free if user buffer */
  167.         if (bp->blkbuf != NULL) {
  168.             free(bp->blkbuf);
  169.             bp->blkbuf = NULL;
  170.         }
  171.     }
  172.     bp->blkbuf = NULL;
  173.     if (bp->block_p != NULL) {
  174.         free((void *)bp->block_p);
  175.         bp->block_p = NULL;
  176.     }
  177.  
  178.     return;
  179. }
  180.  
  181. /*man---------------------------------------------------------------------------
  182. NAME
  183.      b_get - get block from block file
  184.  
  185. SYNOPSIS
  186.      #include "blkio_.h"
  187.  
  188.      int b_get(bp, i)
  189.      BLKFILE *bp;
  190.      size_t i;
  191.  
  192. DESCRIPTION
  193.      The b_get function reads the ith block in the buffer list from the
  194.      block file associated with BLKFILE pointer bp.  The number of the block
  195.      read is the value of the block number field of the block structure for
  196.      that entry in the buffer list.  If i has a value of 0, the header is
  197.      read.  The the read flag is set and all others including the write flag
  198.      cleared for that buffer block.
  199.  
  200.      b_get will fail if one or more of the following is true:
  201.  
  202.      [EINVAL]       bp is not a valid BLKFILE pointer.
  203.      [EINVAL]       i is not in the range [0..bp->bufcnt].
  204.      [BEEOF]        End of file occured before end of block.
  205.      [BENBUF]       bp is not buffered.
  206.  
  207. SEE ALSO
  208.      b_put.
  209.  
  210. DIAGNOSTICS
  211.      Upon successful completion, a value of 0 is returned.  Otherwise, a
  212.      value of -1 is returned, and errno set to indicate the error.
  213.  
  214. ------------------------------------------------------------------------------*/
  215. int b_get(bp, i)
  216. BLKFILE * bp;
  217. size_t    i;
  218. {
  219.     int rs = 0;
  220.  
  221. #ifdef DEBUG
  222.     /* validate arguments */
  223.     if (!b_valid(bp)) {
  224.         BEPRINT;
  225.         errno = EINVAL;
  226.         return -1;
  227.     }
  228.  
  229.     /* check if not open */
  230.     if (!(bp->flags & BIOOPEN)) {
  231.         BEPRINT;
  232.         errno = BENOPEN;
  233.         return -1;
  234.     }
  235.  
  236.     /* check if file is not buffered */
  237.     if (bp->bufcnt == 0) {
  238.         BEPRINT;
  239.         errno = BENBUF;
  240.         return -1;
  241.     }
  242.  
  243.     /* validate arguments */
  244.     if ((i > bp->bufcnt)) {
  245.         BEPRINT;
  246.         errno = EINVAL;
  247.         return -1;
  248.     }
  249.  
  250.     /* check if block number set */
  251.     if ((b_block_p(bp, i)->bn == 0) && (i != 0)) {
  252.         BEPRINT;
  253.         errno = BEPANIC;
  254.         return -1;
  255.     }
  256. #endif
  257.  
  258.     /* check if block needs to be written to disk */
  259.     if (b_block_p(bp, i)->flags & BLKWRITE) {
  260.         errno = BEPANIC;
  261.         return -1;
  262.     }
  263.  
  264.     /* read block from file */
  265.     if (i == 0) {
  266.         rs = b_ugetf(bp, (bpos_t)0, (size_t)0, b_blkbuf(bp, (size_t)0), bp->hdrsize);
  267.     } else {
  268.         rs = b_ugetf(bp, b_block_p(bp, i)->bn, (size_t)0, b_blkbuf(bp, i), bp->blksize);
  269.     }
  270.     if (rs == -1) {
  271.         BEPRINT;
  272.         return -1;
  273.     }
  274.  
  275.     /* set read flag and clear all others */
  276.     b_block_p(bp, i)->flags = BLKREAD;
  277.  
  278.     errno = 0;
  279.     return 0;
  280. }
  281.  
  282. /*man---------------------------------------------------------------------------
  283. NAME
  284.      b_init - initialize block file
  285.  
  286. SYNOPSIS
  287.      #include "blkio_.h"
  288.  
  289.      int b_init(bp)
  290.      BLKFILE *bp;
  291.  
  292. DESCRIPTION
  293.      The b_init function initializes a block file buffer list of the block
  294.      file associated with BLKFILE pointer bp to empty and constructs the
  295.      linked list.
  296.  
  297.      b_init will fail if one or more of the following is true:
  298.  
  299.      [EINVAL]       bp is not a valid block file.
  300.  
  301. DIAGNOSTICS
  302.      Upon successful completion, a value of 0 is returned.  Otherwise, a
  303.      value of -1 is returned, and errno set to indicate the error.
  304.  
  305. ------------------------------------------------------------------------------*/
  306. int b_init(bp)
  307. BLKFILE *bp;
  308. {
  309.     size_t i = 0;
  310.  
  311.     errno = 0;
  312.  
  313. #ifdef DEBUG
  314.     /* validate arguments */
  315.     if (!b_valid(bp)) {
  316.         BEPRINT;
  317.         errno = EINVAL;
  318.         return -1;
  319.     }
  320.  
  321.     /* check if not open */
  322.     if (!(bp->flags & BIOOPEN)) {
  323.         BEPRINT;
  324.         errno = BENOPEN;
  325.         return -1;
  326.     }
  327. #endif
  328.  
  329.     /* initialize head and tail of list */
  330.     bp->most = 0;
  331.     bp->least = 0;
  332.  
  333.     /* check if not buffered */
  334.     if (bp->bufcnt == 0) {
  335.         errno = 0;
  336.         return 0;
  337.     }
  338.  
  339.     /* initialize linked list */
  340.     bp->most = bp->bufcnt;
  341.     bp->least = 1;
  342.     for (i = 1; i <= bp->bufcnt; i++) {
  343.         b_block_p(bp, i)->bn = 0;
  344.         b_block_p(bp, i)->flags = 0;
  345.         b_block_p(bp, i)->more = i + 1;
  346.         b_block_p(bp, i)->less = i - 1;
  347.     }
  348.     b_block_p(bp, bp->most)->more = 0;
  349.     b_block_p(bp, bp->least)->less = 0;
  350.  
  351.     /* initialize block structure for header */
  352.     b_block_p(bp, (size_t)0)->bn = 0;
  353.     b_block_p(bp, (size_t)0)->flags = 0;
  354.     b_block_p(bp, (size_t)0)->more = 0;
  355.     b_block_p(bp, (size_t)0)->less = 0;
  356.  
  357.     /* scrub buffer storage area */
  358.     memset(bp->blkbuf, 0, bp->hdrsize + bp->bufcnt * bp->blksize);
  359.  
  360.     errno = 0;
  361.     return 0;
  362. }
  363.  
  364. /*man---------------------------------------------------------------------------
  365. NAME
  366.      b_mkmru - make most recently used block
  367.  
  368. SYNOPSIS
  369.      #include "blkio_.h"
  370.  
  371.      int b_mkmru(bp, i)
  372.      BLKFILE *bp;
  373.      size_t i;
  374.  
  375. DESCRIPTION
  376.      The b_mkmru function moves the ith block in the buffer list to the
  377.      most recently used end of the buffer list.
  378.  
  379.      b_mkmru will fail if one or more of the following is true:
  380.  
  381.      [EINVAL]       bp is not a valid block file.
  382.      [EINVAL]       i is not in the range [1..bp->bufcnt].
  383.      [BENBUF]       bp is not buffered.
  384.  
  385. DIAGNOSTICS
  386.      Upon successful completion, a value of 0 is returned.  Otherwise, a
  387.      value of -1 is returned, and errno set to indicate the error.
  388.  
  389. ------------------------------------------------------------------------------*/
  390. int b_mkmru(bp, i)
  391. BLKFILE *bp;
  392. size_t   i;
  393. {
  394.     size_t more = 0;
  395.     size_t less = 0;
  396.  
  397.     errno = 0;
  398.  
  399. #ifdef DEBUG
  400.     /* validate arguments */
  401.     if (!b_valid(bp)) {
  402.         BEPRINT;
  403.         errno = EINVAL;
  404.         return -1;
  405.     }
  406.  
  407.     /* check if not open */
  408.     if (!(bp->flags & BIOOPEN)) {
  409.         BEPRINT;
  410.         errno = BENOPEN;
  411.         return -1;
  412.     }
  413.  
  414.     /* check if file is not buffered */
  415.     if (bp->bufcnt == 0) {
  416.         BEPRINT;
  417.         errno = BENBUF;
  418.         return -1;
  419.     }
  420.  
  421.     /* validate arguments */
  422.     if ((i < 1) || (i > bp->bufcnt)) {
  423.         BEPRINT;
  424.         errno = EINVAL;
  425.         return -1;
  426.     }
  427. #endif
  428.  
  429.     /* check block addresses */
  430.     more = b_block_p(bp, i)->more;
  431.     less = b_block_p(bp, i)->less;
  432.     if ((more > bp->bufcnt) || (less > bp->bufcnt)) {
  433.         BEPRINT;
  434.         errno = BEPANIC;
  435.         return -1;
  436.     }
  437.  
  438.     /* check if already most recently used */
  439.     if (more == 0) {
  440.         errno = 0;
  441.         return 0;
  442.     }
  443.  
  444.     /* remove block i from linked list */
  445.     b_block_p(bp, more)->less = less;
  446.     if (less != 0) {
  447.         b_block_p(bp, less)->more = more;
  448.     } else {
  449.         bp->least = more;
  450.     }
  451.  
  452.     /* connect ith block as most recently used */
  453.     b_block_p(bp, i)->more = 0;
  454.     b_block_p(bp, i)->less = bp->most;
  455.     b_block_p(bp, bp->most)->more = i;
  456.     bp->most = i;
  457.  
  458.     errno = 0;
  459.     return 0;
  460. }
  461.  
  462. /*man---------------------------------------------------------------------------
  463. NAME
  464.      b_put - put block into block file
  465.  
  466. SYNOPSIS
  467.      #include "blkio_.h"
  468.  
  469.      int b_put(bp, i)
  470.      BLKFILE *bp;
  471.      size_t i;
  472.  
  473. DESCRIPTION
  474.      The b_put function writes the ith block in the buffer list to
  475.      the file.  The number of the block written is the value of the block
  476.      number field of the ith entry in the buffer list.  If i has a
  477.      value of 0, the header is written.  If the write flag is not set,
  478.      nothing is written.  After writing, the write flag is cleared.
  479.  
  480.      b_put will fail if one or more of the following is true:
  481.  
  482.      [EINVAL]       bp is not a valid block file.
  483.      [EINVAL]       i is not in the range [0..bp->bufcnt].
  484.      [BENBUF]       bp is not buffered.
  485.  
  486. SEE ALSO
  487.      b_get.
  488.  
  489. DIAGNOSTICS
  490.      Upon successful completion, a value of 0 is returned.  Otherwise, a
  491.      value of -1 is returned, and errno set to indicate the error.
  492.  
  493. ------------------------------------------------------------------------------*/
  494. int b_put(bp, i)
  495. BLKFILE * bp;
  496. size_t    i;
  497. {
  498.     int rs = 0;
  499.  
  500. #ifdef DEBUG
  501.     /* validate arguments */
  502.     if (!b_valid(bp)) {
  503.         BEPRINT;
  504.         errno = EINVAL;
  505.         return -1;
  506.     }
  507.  
  508.     /* check if not open */
  509.     if (!(bp->flags & BIOOPEN)) {
  510.         BEPRINT;
  511.         errno = BENOPEN;
  512.         return -1;
  513.     }
  514.  
  515.     /* check if file is not buffered */
  516.     if (bp->bufcnt == 0) {
  517.         BEPRINT;
  518.         errno = BENBUF;
  519.         return -1;
  520.     }
  521.  
  522.     /* validate arguments */
  523.     if (i > bp->bufcnt) {
  524.         BEPRINT;
  525.         errno = EINVAL;
  526.         return -1;
  527.     }
  528. #endif
  529.  
  530.     /* check if block doesn't need to be written to disk */
  531.     if (!(b_block_p(bp, i)->flags & BLKWRITE)) {
  532.         errno = 0;
  533.         return 0;
  534.     }
  535.  
  536.     /* check for inconsistent read flag setting */
  537.     if (!(b_block_p(bp, i)->flags & BLKREAD)) {
  538.         BEPRINT;
  539.         errno = BEPANIC;
  540.         return 0;
  541.     }
  542.  
  543.     /* write block to disk */
  544.     if (i == 0) {
  545.         rs = b_uputf(bp, (bpos_t)0, (size_t)0, b_blkbuf(bp, (size_t)0), bp->hdrsize);
  546.     } else {
  547.         rs = b_uputf(bp, b_block_p(bp, i)->bn, (size_t)0, b_blkbuf(bp, i), bp->blksize);
  548.     }
  549.     if (rs == -1) {
  550.         BEPRINT;
  551.         return -1;
  552.     }
  553.  
  554.     /* clear all but read flag */
  555.     b_block_p(bp, i)->flags = BLKREAD;
  556.  
  557.     errno = 0;
  558.     return 0;
  559. }
  560.  
  561. /*man---------------------------------------------------------------------------
  562. NAME
  563.      b_valid - validate block file
  564.  
  565. SYNOPSIS
  566.      #include "blkio_.h"
  567.  
  568.      bool b_valid(bp)
  569.      BLKFILE *bp;
  570.  
  571. DESCRIPTION
  572.      The b_valid function determines if bp points to a valid block file
  573.      control structure.  If it is valid, TRUE is returned.  If not,
  574.      then FALSE is returned.
  575.  
  576. ------------------------------------------------------------------------------*/
  577. bool b_valid(bp)
  578. BLKFILE *bp;
  579. {
  580.     if ((bp < biob) || (bp > (biob + BOPEN_MAX - 1))) {
  581.         return FALSE;
  582.     }
  583.     if (((size_t)((char *)bp - (char *)biob)) % sizeof(biob[0]) != 0) {
  584.         return FALSE;
  585.     }
  586.  
  587.     return TRUE;
  588. }
  589.