3 /* setvbuf( FILE *, char *, int, size_t )
5 This file is part of the Public Domain C Library (PDCLib).
6 Permission is granted to use, modify, and / or redistribute at will.
14 #include <_PDCLIB_io.h>
16 int setvbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf, int mode, size_t size )
18 _PDCLIB_flockfile( stream );
22 /* When unbuffered I/O is requested, we keep the buffer anyway, as
23 we don't want to e.g. flush the stream for every character of a
29 if ( size > INT_MAX || size == 0 )
31 /* PDCLib only supports buffers up to INT_MAX in size. A size
32 of zero doesn't make sense.
34 _PDCLIB_funlockfile( stream );
39 /* User requested buffer size, but leaves it to library to
42 /* If current buffer is big enough for requested size, but not
43 over twice as big (and wasting memory space), we use the
44 current buffer (i.e., do nothing), to save the malloc() /
47 if ( ( stream->bufsize < size ) || ( stream->bufsize > ( size << 1 ) ) )
49 /* Buffer too small, or much too large - allocate. */
50 if ( ( buf = (char *) malloc( size ) ) == NULL )
52 /* Out of memory error. */
53 _PDCLIB_funlockfile( stream );
56 /* This buffer must be free()d on fclose() */
57 stream->status |= _PDCLIB_FREEBUFFER;
61 stream->bufsize = size;
64 /* If mode is something else than _IOFBF, _IOLBF or _IONBF -> exit */
65 _PDCLIB_funlockfile( stream );
68 /* Deleting current buffer mode */
69 stream->status &= ~( _IOFBF | _IOLBF | _IONBF );
70 /* Set user-defined mode */
71 stream->status |= mode;
72 _PDCLIB_funlockfile( stream );
79 #include <_PDCLIB_test.h>
82 #include <_PDCLIB_io.h>
84 #define BUFFERSIZE 500
89 char buffer[ BUFFERSIZE ];
91 /* full buffered, user-supplied buffer */
92 TESTCASE( ( fh = tmpfile() ) != NULL );
93 TESTCASE( setvbuf( fh, buffer, _IOFBF, BUFFERSIZE ) == 0 );
94 TESTCASE( fh->buffer == buffer );
95 TESTCASE( fh->bufsize == BUFFERSIZE );
96 TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IOFBF );
97 TESTCASE( fclose( fh ) == 0 );
98 /* line buffered, lib-supplied buffer */
99 TESTCASE( ( fh = tmpfile() ) != NULL );
100 TESTCASE( setvbuf( fh, NULL, _IOLBF, BUFFERSIZE ) == 0 );
101 TESTCASE( fh->buffer != NULL );
102 TESTCASE( fh->bufsize == BUFFERSIZE );
103 TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IOLBF );
104 TESTCASE( fclose( fh ) == 0 );
105 /* not buffered, user-supplied buffer */
106 TESTCASE( ( fh = tmpfile() ) != NULL );
107 TESTCASE( setvbuf( fh, buffer, _IONBF, BUFFERSIZE ) == 0 );
108 TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IONBF );
109 TESTCASE( fclose( fh ) == 0 );
111 puts( " NOTEST setvbuf() test driver is PDCLib-specific." );