home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c065 / 2.ddi / CLIB2.ZIP / CHSIZE.CAS < prev    next >
Encoding:
Text File  |  1990-06-07  |  4.0 KB  |  178 lines

  1. /*---------------------------------------------------------------------------
  2.  * filename - chsize.cas
  3.  *
  4.  * function(s)
  5.  *      chsize - change file size
  6.  *--------------------------------------------------------------------------*/
  7.  
  8. /*[]------------------------------------------------------------[]*/
  9. /*|                                                              |*/
  10. /*|     Turbo C Run Time Library - Version 3.0                   |*/
  11. /*|                                                              |*/
  12. /*|                                                              |*/
  13. /*|     Copyright (c) 1987,1988,1990 by Borland International    |*/
  14. /*|     All Rights Reserved.                                     |*/
  15. /*|                                                              |*/
  16. /*[]------------------------------------------------------------[]*/
  17.  
  18.  
  19. #pragma inline
  20. #include <asmrules.h>
  21. #include <io.h>
  22. #include <fcntl.h>
  23. #include <_io.h>
  24.  
  25. #define ZEROBUFSIZ    128        /* size of padding buffer */
  26.  
  27.  
  28. /*--------------------------------------------------------------------------*
  29.  
  30. Name        chsize - change file size
  31.  
  32. Usage        int chsize(int fildes, long newSize);
  33.  
  34. Prototype in    io.h
  35.  
  36. Description    forces the file's size to be newSize, either by
  37.         extending or by truncating.
  38.  
  39. Return value    success :  0
  40.         failure : -1 and errno is set.
  41.  
  42. *---------------------------------------------------------------------------*/
  43. int chsize (register int fildes, long newSize)
  44. {
  45.     char    zerobuf[ZEROBUFSIZ];
  46.     long    posn;
  47.  
  48. asm    mov    ax, 4201h        /* LSeek to current position    */
  49. asm    mov    bx, fildes
  50. asm    sub    cx, cx
  51. asm    mov    dx, cx
  52. asm    int    21h
  53. asm    jc    chsizeFailed
  54.  
  55. asm    mov    W0 (posn), ax
  56. asm    mov    W1 (posn), dx        /* save current position    */
  57.  
  58. asm    mov    ax, 4202h        /* seek to end of file        */
  59. asm    sub    cx, cx
  60. asm    mov    dx, cx
  61. asm    int    21h
  62. asm    jc    chsizeFailed
  63.  
  64. /*
  65.   See whether we need to extend or truncate.
  66. */
  67.  
  68. asm    cmp    dx, W1 (newSize)
  69. asm    ja    chsizeTruncate
  70. asm    jb    chsizePad
  71. asm    cmp    ax, W0 (newSize)
  72. asm    jae    chsizeTruncate
  73.  
  74. /*
  75.   Here we seek to the original end-of-file, and pad the file with zeros.
  76. */
  77. chsizePad:
  78.  
  79. asm    sub    W0 (newSize), ax    /* compute # of bytes to pad    */
  80. asm    sbb    W1 (newSize), dx
  81. asm    mov    cx, dx
  82. asm     xchg    dx, ax
  83. asm    mov    ax, 4200h        /* seek to old end-of-file    */
  84. asm    int    21h
  85. asm    jc    chsizeFailed
  86.  
  87. /*
  88.   Fill our temp buffer with (ZEROBUFSIZ) zeros.
  89. */
  90.  
  91. asm    push    ss
  92. asm    pop    es
  93. asm    lea    di, zerobuf
  94. asm    xor    ax, ax
  95. asm    mov    cx, ZEROBUFSIZ / 2
  96. asm    cld
  97. asm    rep  stosw
  98.  
  99. /*
  100.   Now write our "zero" buffer repeatedly to the file, until (newSize)
  101.   bytes have been written.
  102. */
  103.  
  104. writeLoop:
  105.  
  106. asm    mov    cx, ZEROBUFSIZ        /* need more then full buffer ? */
  107. asm    cmp    W1(newSize), 0
  108. asm    jnz    writeChunk
  109. asm    cmp    cx, W0(newSize)
  110. asm    jbe    writeChunk
  111. asm    mov    cx, W0(newSize)
  112. writeChunk:
  113. asm    sub    W0(newSize), cx     /* update byte count        */
  114. asm    sbb    W1(newSize), 0
  115. asm    lea    dx, zerobuf
  116. #if    LDATA
  117. asm    push    ds
  118. asm    push    ss
  119. asm    pop    ds            /* DS = segment of buffer    */
  120. #endif
  121. asm    push    cx
  122. asm    mov    ah, 40h
  123. asm    int    21h            /* write zeros to file        */
  124. asm    pop    cx
  125. #if    LDATA
  126. asm    pop    ds
  127. #endif
  128. asm    jc    chsizeFailed
  129. asm    cmp    ax, cx            /* make sure everything written */
  130. asm    jne    chsizeFailed
  131.  
  132. /*
  133.   See if need to write more.
  134. */
  135.  
  136. asm    mov    ax, W0(newSize)
  137. asm    or    ax, W1(newSize)
  138. asm    jnz    writeLoop
  139.  
  140.     goto    chsizeSeekback;     /* done --> restore file pos    */
  141.  
  142. /*
  143.   Jump here if an error occurs (AX = DOS error code).
  144. */
  145.  
  146. chsizeFailed:
  147.     return __IOerror (_AX);
  148.  
  149. /*
  150.   MSDOS truncates a file as a side-effect to function 40 when
  151.   a zero-length write is requested.
  152. */
  153. chsizeTruncate:
  154.  
  155. asm    mov    ax, 4200h        /* seek to new end-of-file    */
  156. asm    mov    bx, fildes
  157. asm    mov    dx, W0 (newSize)
  158. asm    mov    cx, W1 (newSize)
  159. asm    int    21h
  160. asm    jc    chsizeFailed
  161.  
  162. asm    mov    ah, 40h         /* truncate at desired position */
  163. asm    sub    cx, cx
  164. asm    int    21h
  165. asm    jc    chsizeFailed
  166.  
  167. chsizeSeekback:
  168. asm    mov    dx, W0 (posn)
  169. asm    mov    cx, W1 (posn)
  170. asm    xchg    si, ax
  171. asm    mov    ax, 4200h        /* seek to original place    */
  172. asm    int    21h
  173. asm    jc    chsizeFailed
  174.  
  175.     _openfd [fildes] |= O_CHANGED;
  176.     return    0;
  177. }
  178.