Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/waterbox/libc/functions/stdio/setvbuf.c
2 views
1
/* setvbuf( FILE *, char *, int, size_t )
2
3
This file is part of the Public Domain C Library (PDCLib).
4
Permission is granted to use, modify, and / or redistribute at will.
5
*/
6
7
#include <stdio.h>
8
#include <stdlib.h>
9
#include <limits.h>
10
11
#ifndef REGTEST
12
#include "_PDCLIB_io.h"
13
14
int setvbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf, int mode, size_t size )
15
{
16
_PDCLIB_flockfile( stream );
17
switch ( mode )
18
{
19
case _IONBF:
20
/* When unbuffered I/O is requested, we keep the buffer anyway, as
21
we don't want to e.g. flush the stream for every character of a
22
stream being printed.
23
*/
24
break;
25
case _IOFBF:
26
case _IOLBF:
27
if ( size > INT_MAX || size == 0 )
28
{
29
/* PDCLib only supports buffers up to INT_MAX in size. A size
30
of zero doesn't make sense.
31
*/
32
_PDCLIB_funlockfile( stream );
33
return -1;
34
}
35
if ( buf == NULL )
36
{
37
/* User requested buffer size, but leaves it to library to
38
allocate the buffer.
39
*/
40
/* If current buffer is big enough for requested size, but not
41
over twice as big (and wasting memory space), we use the
42
current buffer (i.e., do nothing), to save the malloc() /
43
free() overhead.
44
*/
45
if ( ( stream->bufsize < size ) || ( stream->bufsize > ( size << 1 ) ) )
46
{
47
/* Buffer too small, or much too large - allocate. */
48
if ( ( buf = (char *) malloc( size ) ) == NULL )
49
{
50
/* Out of memory error. */
51
_PDCLIB_funlockfile( stream );
52
return -1;
53
}
54
/* This buffer must be free()d on fclose() */
55
stream->status |= _PDCLIB_FREEBUFFER;
56
}
57
}
58
stream->buffer = buf;
59
stream->bufsize = size;
60
break;
61
default:
62
/* If mode is something else than _IOFBF, _IOLBF or _IONBF -> exit */
63
_PDCLIB_funlockfile( stream );
64
return -1;
65
}
66
/* Deleting current buffer mode */
67
stream->status &= ~( _IOFBF | _IOLBF | _IONBF );
68
/* Set user-defined mode */
69
stream->status |= mode;
70
_PDCLIB_funlockfile( stream );
71
return 0;
72
}
73
74
#endif
75
76
#ifdef TEST
77
#include "_PDCLIB_test.h"
78
#include <errno.h>
79
#ifndef REGTEST
80
#include "_PDCLIB_io.h"
81
#endif
82
#define BUFFERSIZE 500
83
84
int main( void )
85
{
86
#ifndef REGTEST
87
char buffer[ BUFFERSIZE ];
88
FILE * fh;
89
/* full buffered, user-supplied buffer */
90
TESTCASE( ( fh = tmpfile() ) != NULL );
91
TESTCASE( setvbuf( fh, buffer, _IOFBF, BUFFERSIZE ) == 0 );
92
TESTCASE( fh->buffer == buffer );
93
TESTCASE( fh->bufsize == BUFFERSIZE );
94
TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IOFBF );
95
TESTCASE( fclose( fh ) == 0 );
96
/* line buffered, lib-supplied buffer */
97
TESTCASE( ( fh = tmpfile() ) != NULL );
98
TESTCASE( setvbuf( fh, NULL, _IOLBF, BUFFERSIZE ) == 0 );
99
TESTCASE( fh->buffer != NULL );
100
TESTCASE( fh->bufsize == BUFFERSIZE );
101
TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IOLBF );
102
TESTCASE( fclose( fh ) == 0 );
103
/* not buffered, user-supplied buffer */
104
TESTCASE( ( fh = tmpfile() ) != NULL );
105
TESTCASE( setvbuf( fh, buffer, _IONBF, BUFFERSIZE ) == 0 );
106
TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IONBF );
107
TESTCASE( fclose( fh ) == 0 );
108
#else
109
puts( " NOTEST setvbuf() test driver is PDCLib-specific." );
110
#endif
111
return TEST_RESULTS;
112
}
113
114
#endif
115
116
117