home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 5.ddi / CLIBSRC2.ZIP / CHSIZE.CAS < prev    next >
Encoding:
Text File  |  1992-06-10  |  4.5 KB  |  177 lines

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