Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
6.9 KiB

  1. /***
  2. *setvbuf.c - set buffer size for a stream
  3. *
  4. * Copyright (c) 1985-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines setvbuf() - set the buffering mode and size for a stream.
  8. *
  9. *Revision History:
  10. * 09-19-83 RN initial version
  11. * 06-26-85 TC modified to allow user defined buffers of various sizes
  12. * 06-24-86 DFW kludged to fix incompatability with Xenix values of
  13. * _IOFBF, _IOLBF
  14. * 02-09-87 JCR added "buffer=&(_iob2[fileno(stream)]._charbuf);"
  15. * to handle _IONBF case
  16. * 02-25-87 JCR added support for default buffer and IBMC20-condition
  17. * code
  18. * 04-13-87 JCR changed type of szie from int to size_t (unsigned int)
  19. * and changed a related comparison
  20. * 06-29-87 JCR Took out the _OLD_IOFBF/_OLD_IOLBF kludge for MSC.
  21. * Should be taken out for IBM too...
  22. * 09-28-87 JCR Corrected _iob2 indexing (now uses _iob_index() macro).
  23. * 11-02-87 JCR Multi-thread support
  24. * 12-11-87 JCR Added "_LOAD_DS" to declaration
  25. * 05-27-88 PHG Merged DLL and normal versions
  26. * 06-06-88 JCR Optimized _iob2 references
  27. * 06-14-88 JCR Use near pointer to reference _iob[] entries
  28. * 08-09-88 JCR Buffer size can't be greater than INT_MAX
  29. * 08-25-88 GJF Don't use FP_OFF() macro for the 386
  30. * 08-18-89 GJF Clean up, now specific to OS/2 2.0 (i.e., 386 flat
  31. * model). Also fixed copyright and indents.
  32. * 02-15-90 GJF _iob[], _iob2[] merge. Also, cleanup, a little tuning
  33. * and fixed copyright.
  34. * 03-19-90 GJF Made calling type _CALLTYPE1, added #include
  35. * <cruntime.h> and removed #include <register.h>.
  36. * 05-29-90 SBM Use _flush, not [_]fflush[_lk]
  37. * 07-23-90 SBM Replaced <assertm.h> by <assert.h>
  38. * 10-03-90 GJF New-style function declarator.
  39. * 04-06-93 SKS Replace _CRTAPI* with __cdecl
  40. * 04-27-93 CFW Change _IONBF size to 2 bytes to hold wide char.
  41. * 06-22-93 GJF Set _IOSETVBUF (new) to indicate user-specified
  42. * buffering (in addition to setting _IOYOURBUF or
  43. * _IOMYBUF).
  44. * 11-12-93 GJF Return failure if size == 1 (instead of putting
  45. * 0 into stream->_bufsiz, preventing any i/o)
  46. * 04-05-94 GJF #ifdef-ed out _cflush reference for msvcrt*.dll, it
  47. * is unnecessary.
  48. * 01-10-95 CFW Debug CRT allocs.
  49. * 02-06-94 CFW assert -> _ASSERTE.
  50. * 02-20-95 GJF Merged in Mac version.
  51. * 03-07-95 GJF _[un]lock_str macros now take FILE * arg.
  52. * 03-02-98 GJF Exception-safe locking.
  53. * 01-04-99 GJF Changes for 64-bit size_t.
  54. * 05-17-99 PML Remove all Macintosh support.
  55. *
  56. *******************************************************************************/
  57. #include <cruntime.h>
  58. #include <stdio.h>
  59. #include <file2.h>
  60. #include <malloc.h>
  61. #include <internal.h>
  62. #include <mtdll.h>
  63. #include <limits.h>
  64. #include <dbgint.h>
  65. /***
  66. *int setvbuf(stream, buffer, type, size) - set buffering for a file
  67. *
  68. *Purpose:
  69. * Controls buffering and buffer size for the specified stream. The
  70. * array pointed to by buf is used as a buffer, unless NULL, in which
  71. * case we'll allocate a buffer automatically. type specifies the type
  72. * of buffering: _IONBF = no buffer, _IOFBF = buffered, _IOLBF = same
  73. * as _IOFBF.
  74. *
  75. *Entry:
  76. * FILE *stream - stream to control buffer on
  77. * char *buffer - pointer to buffer to use (NULL means auto allocate)
  78. * int type - type of buffering (_IONBF, _IOFBF or _IOLBF)
  79. * size_t size - size of buffer
  80. *
  81. *Exit:
  82. * return 0 if successful
  83. * returns non-zero if fails
  84. *
  85. *Exceptions:
  86. *
  87. *******************************************************************************/
  88. int __cdecl setvbuf (
  89. FILE *str,
  90. char *buffer,
  91. int type,
  92. size_t size
  93. )
  94. {
  95. REG1 FILE *stream;
  96. int retval=0; /* assume good return */
  97. _ASSERTE(str != NULL);
  98. /*
  99. * (1) Make sure type is one of the three legal values.
  100. * (2) If we are buffering, make sure size is greater than 0.
  101. */
  102. if ( (type != _IONBF) && ((size < 2) || (size > INT_MAX) ||
  103. ((type != _IOFBF) && (type != _IOLBF))) )
  104. return(-1);
  105. /*
  106. * force size to be even by masking down to the nearest multiple
  107. * of 2
  108. */
  109. size &= (size_t)~1;
  110. /*
  111. * Init stream pointers
  112. */
  113. stream = str;
  114. #ifdef _MT
  115. /*
  116. * Lock the file
  117. */
  118. _lock_str(stream);
  119. __try {
  120. #endif
  121. /*
  122. * Flush the current buffer and free it, if it is ours.
  123. */
  124. _flush(stream);
  125. _freebuf(stream);
  126. /*
  127. * Clear a bunch of bits in stream->_flag (all bits related to
  128. * buffering and those which used to be in stream2->_flag2). Most
  129. * of these should never be set when setvbuf() is called, but it
  130. * doesn't cost anything to be safe.
  131. */
  132. stream->_flag &= ~(_IOMYBUF | _IOYOURBUF | _IONBF |
  133. _IOSETVBUF | _IOFEOF | _IOFLRTN | _IOCTRLZ);
  134. /*
  135. * CASE 1: No Buffering.
  136. */
  137. if (type & _IONBF) {
  138. stream->_flag |= _IONBF;
  139. buffer = (char *)&(stream->_charbuf);
  140. size = 2;
  141. }
  142. /*
  143. * NOTE: Cases 2 and 3 (below) cover type == _IOFBF or type == _IOLBF
  144. * Line buffering is treated as the same as full buffering, so the
  145. * _IOLBF bit in stream->_flag is never set. Finally, since _IOFBF is
  146. * defined to be 0, full buffering is simply assumed whenever _IONBF
  147. * is not set.
  148. */
  149. /*
  150. * CASE 2: Default Buffering -- Allocate a buffer for the user.
  151. */
  152. else if ( buffer == NULL ) {
  153. if ( (buffer = _malloc_crt(size)) == NULL ) {
  154. #ifndef CRTDLL
  155. /*
  156. * force library pre-termination procedure (placed here
  157. * because the code path should almost never be hit)
  158. */
  159. _cflush++;
  160. #endif /* CRTDLL */
  161. retval = -1;
  162. goto done;
  163. }
  164. stream->_flag |= _IOMYBUF | _IOSETVBUF;
  165. }
  166. /*
  167. * CASE 3: User Buffering -- Use the buffer supplied by the user.
  168. */
  169. else {
  170. stream->_flag |= _IOYOURBUF | _IOSETVBUF;
  171. }
  172. /*
  173. * Common return for all cases.
  174. */
  175. stream->_bufsiz = (int)size;
  176. stream->_ptr = stream->_base = buffer;
  177. stream->_cnt = 0;
  178. done:
  179. #ifdef _MT
  180. ; }
  181. __finally {
  182. _unlock_str(stream);
  183. }
  184. #endif
  185. return(retval);
  186. }