Path: blob/master/waterbox/libc/functions/stdio/setvbuf.c
2 views
/* setvbuf( FILE *, char *, int, size_t )12This file is part of the Public Domain C Library (PDCLib).3Permission is granted to use, modify, and / or redistribute at will.4*/56#include <stdio.h>7#include <stdlib.h>8#include <limits.h>910#ifndef REGTEST11#include "_PDCLIB_io.h"1213int setvbuf( FILE * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf, int mode, size_t size )14{15_PDCLIB_flockfile( stream );16switch ( mode )17{18case _IONBF:19/* When unbuffered I/O is requested, we keep the buffer anyway, as20we don't want to e.g. flush the stream for every character of a21stream being printed.22*/23break;24case _IOFBF:25case _IOLBF:26if ( size > INT_MAX || size == 0 )27{28/* PDCLib only supports buffers up to INT_MAX in size. A size29of zero doesn't make sense.30*/31_PDCLIB_funlockfile( stream );32return -1;33}34if ( buf == NULL )35{36/* User requested buffer size, but leaves it to library to37allocate the buffer.38*/39/* If current buffer is big enough for requested size, but not40over twice as big (and wasting memory space), we use the41current buffer (i.e., do nothing), to save the malloc() /42free() overhead.43*/44if ( ( stream->bufsize < size ) || ( stream->bufsize > ( size << 1 ) ) )45{46/* Buffer too small, or much too large - allocate. */47if ( ( buf = (char *) malloc( size ) ) == NULL )48{49/* Out of memory error. */50_PDCLIB_funlockfile( stream );51return -1;52}53/* This buffer must be free()d on fclose() */54stream->status |= _PDCLIB_FREEBUFFER;55}56}57stream->buffer = buf;58stream->bufsize = size;59break;60default:61/* If mode is something else than _IOFBF, _IOLBF or _IONBF -> exit */62_PDCLIB_funlockfile( stream );63return -1;64}65/* Deleting current buffer mode */66stream->status &= ~( _IOFBF | _IOLBF | _IONBF );67/* Set user-defined mode */68stream->status |= mode;69_PDCLIB_funlockfile( stream );70return 0;71}7273#endif7475#ifdef TEST76#include "_PDCLIB_test.h"77#include <errno.h>78#ifndef REGTEST79#include "_PDCLIB_io.h"80#endif81#define BUFFERSIZE 5008283int main( void )84{85#ifndef REGTEST86char buffer[ BUFFERSIZE ];87FILE * fh;88/* full buffered, user-supplied buffer */89TESTCASE( ( fh = tmpfile() ) != NULL );90TESTCASE( setvbuf( fh, buffer, _IOFBF, BUFFERSIZE ) == 0 );91TESTCASE( fh->buffer == buffer );92TESTCASE( fh->bufsize == BUFFERSIZE );93TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IOFBF );94TESTCASE( fclose( fh ) == 0 );95/* line buffered, lib-supplied buffer */96TESTCASE( ( fh = tmpfile() ) != NULL );97TESTCASE( setvbuf( fh, NULL, _IOLBF, BUFFERSIZE ) == 0 );98TESTCASE( fh->buffer != NULL );99TESTCASE( fh->bufsize == BUFFERSIZE );100TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IOLBF );101TESTCASE( fclose( fh ) == 0 );102/* not buffered, user-supplied buffer */103TESTCASE( ( fh = tmpfile() ) != NULL );104TESTCASE( setvbuf( fh, buffer, _IONBF, BUFFERSIZE ) == 0 );105TESTCASE( ( fh->status & ( _IOFBF | _IONBF | _IOLBF ) ) == _IONBF );106TESTCASE( fclose( fh ) == 0 );107#else108puts( " NOTEST setvbuf() test driver is PDCLib-specific." );109#endif110return TEST_RESULTS;111}112113#endif114115116117