home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume8 / mdcopy / part02 / mdflush.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-11-02  |  2.5 KB  |  140 lines

  1. /*
  2.  * Created 1989 by greg yachuk.  Placed in the public domain.
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include "mdiskio.h"
  7.  
  8. #ifdef    DOS
  9. #define    BUFLIMIT    BUFSIZ
  10. #else
  11. #define    BUFLIMIT    1
  12. #endif
  13.  
  14. #ifdef    CATCH_XFSZ
  15. #include <signal.h>
  16. #include <setjmp.h>
  17. static jmp_buf _mdsigbuf;
  18. #endif
  19.  
  20. /*
  21.  * _mdflush -    flush an mdiskbuf out to the diskette.  write as many
  22.  *        bytes as possible
  23.  */
  24. _mdflush(c, mdp)
  25. int    c;
  26. MDFILE *mdp;
  27. {
  28.     if (_mdflsbf(mdp) == EOF)
  29.         return (EOF);
  30.     return (mdputc(c, mdp));
  31. }
  32.  
  33. /*
  34.  * _mdflsbf -    do the actual work of flushing the buffer.
  35.  */
  36. _mdflsbf(mdp)
  37. MDFILE *mdp;
  38. {
  39.     int    blen;        /* buffer length */
  40.     int    ret;        /* return code */
  41.     int    len;        /* length left to write out */
  42.     int    cumm;        /* cummulative number of bytes written */
  43.  
  44.     mdp->bufcnt = 0;        /* in case we forget, below */
  45.  
  46.     if (mdp->flags & (_MDREAD|_MDERR))
  47.     {
  48.         mdp->flags |= _MDERR;    /* can't write to a read stream */
  49.         return (EOF);
  50.     }
  51.  
  52.     if (mdp->fid == -1)
  53.         return (EOF);        /* got no business being here, anyway */
  54.  
  55.     /* record current buffer length */
  56.  
  57.     blen = mdp->bufptr - mdp->buffer;
  58.  
  59.     /* first flush when first char is `put', so allocate a buffer */
  60.  
  61.     if (mdp->buffer == NULL)
  62.         blen = _mdgetbuf(mdp, blen);
  63.  
  64.     if (!(mdp->flags & _MDEMPTY))
  65.     {
  66.         cumm = 0;        /* nothing written yet */
  67.         for(;;)
  68.         {
  69.             len = blen - cumm;
  70.             /*
  71.              * try to write the whole buffer.  if it fails,
  72.              * try half as many, until we cannot fit any more
  73.              * on the disk (len < BUFSIZE) or we've written
  74.              * them all.
  75.              */
  76.             do {
  77. #ifdef    CATCH_XFSZ
  78.                 ret = -1;
  79.                 if (setjmp(_mdsigbuf) == 0)
  80.                 {
  81.                     _mdsetsig(1);
  82. #endif
  83.                     ret = write(mdp->fid,
  84.                             &mdp->buffer[cumm],
  85.                             len);
  86. #ifdef    CATCH_XFSZ
  87.                 }
  88.                 _mdsetsig(0);
  89. #endif
  90.                 len >>= 1;
  91. #ifndef    NODEBUG
  92.                 if (ret == -1)
  93.                     perror(mdp->basename);
  94. #endif
  95.                 if (ret != -1)
  96.                     cumm += ret;    /* cumulative total */
  97.             } while (len >= BUFLIMIT && cumm < blen);
  98.  
  99.             if (cumm >= blen)
  100.                 break;        /* wrote them all */
  101.  
  102.             /* ran out of room on this diskette.  try next one */
  103.  
  104.             if (mdp->ateof(mdp, _MDWRITE))
  105.                 return (EOF);
  106.             _mdclose(mdp);
  107.             if (!mdp->prompt(mdp))
  108.                 return (EOF);
  109.             if (_mdopen(mdp) == -1)
  110.                 return (EOF);
  111.         }
  112.     }
  113.  
  114.     /* reset to empty buffer */
  115.  
  116.     mdp->bufcnt = blen;
  117.     mdp->bufptr = mdp->buffer;
  118.  
  119.     mdp->flags |= _MDWRITE;
  120.     mdp->flags &= ~_MDEMPTY;
  121.  
  122.     return (0);
  123. }
  124.  
  125. #ifdef    CATCH_XFSZ
  126. _mdsighdlr()
  127. {
  128.     signal(SIGXFSZ, _mdsighdlr);
  129.     longjmp(_mdsigbuf, 1);
  130. }
  131.  
  132. _mdsetsig(set)
  133. int    set;
  134. {
  135.     static int (*old_sighdlr)();
  136.  
  137.     old_sighdlr = signal(SIGXFSZ, (set)? _mdsighdlr : old_sighdlr);
  138. }
  139. #endif
  140.