X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=functions%2Fstdio%2Fsetvbuf.c;h=c6329df9b6f07fe823a2570e3d0b3533f6fca49a;hb=17032bd4d730f9c2dbe91e9ec92248c922bebb28;hp=2f9b4c48bdef5e2565b5e6ce9e39bdb7c394079b;hpb=e5456e3c2697c4e17fc9aa3439f2e305517b4d96;p=pdclib.old diff --git a/functions/stdio/setvbuf.c b/functions/stdio/setvbuf.c index 2f9b4c4..c6329df 100644 --- a/functions/stdio/setvbuf.c +++ b/functions/stdio/setvbuf.c @@ -1,67 +1,78 @@ -// ---------------------------------------------------------------------------- -// $Id$ -// ---------------------------------------------------------------------------- -// Public Domain C Library - http://pdclib.sourceforge.net -// This code is Public Domain. Use, modify, and redistribute at will. -// ---------------------------------------------------------------------------- +/* $Id$ */ -int setvbuf( FILE * restrict stream, char * restrict buf, int mode, size_t size ) { /* TODO */ }; +/* setvbuf( FILE *, char *, int, size_t ) -/* PDPC code - unreviewed -/* -NULL + F = allocate, setup -NULL + L = allocate, setup -NULL + N = ignore, return success -buf + F = setup -buf + L = setup -buf + N = ignore, return success + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. */ -int setvbuf(FILE *stream, char *buf, int mode, size_t size) -{ - char *mybuf; +#include +#include + +#ifndef REGTEST - if (mode == _IONBF) +int setvbuf( struct _PDCLIB_file_t * _PDCLIB_restrict stream, char * _PDCLIB_restrict buf, int mode, size_t size ) +{ + /* Only allowed on "virgin" streams (i.e., before first I/O occurs), and + a valid value for mode. + */ + if ( ( ! stream->status & _PDCLIB_VIRGINSTR ) || + ( ( mode != _IOFBF ) && ( mode != _IOLBF ) && ( mode != _IONBF ) ) ) { - stream->bufTech = mode; - return (0); + return -1; } - if (buf == NULL) + /* If a buffer is provided by user... */ + if ( buf != NULL ) { - if (size < 2) - { - return (-1); - } - mybuf = malloc(size + 8); - if (mybuf == NULL) - { - return (-1); - } + /* ...do not free it in library functions like fclose(), freopen(). */ + stream->status &= ~_PDCLIB_LIBBUFFER; } - else + /* If no buffer is provided by user, but required... */ + else if ( mode != _IONBF ) { - if (size < 10) + /* Since setvbuf() may be called (successfully) on a stream only once, + the stream's buffer at this point should *always* be that allocated + by fopen(), but better make sure. + */ + if ( ! ( stream->status & _PDCLIB_LIBBUFFER ) ) { - return (-1); + return -1; + } + /* Drop old buffer, allocate new one of requested size (unless that is + equal to BUFSIZ, in which case we can use the one already allocated + by fopen().) + */ + if ( size != BUFSIZ ) + { + if ( ( buf = malloc( size ) ) == NULL ) + { + return -1; + } + free( stream->buffer ); } - mybuf = buf; - stream->theirBuffer = 1; - size -= 8; - } - free(stream->intBuffer); - stream->intBuffer = mybuf; - stream->fbuf = stream->intBuffer + 2; - *stream->fbuf++ = '\0'; - *stream->fbuf++ = '\0'; - stream->szfbuf = size; - stream->endbuf = stream->fbuf + stream->szfbuf; - *stream->endbuf = '\n'; - stream->upto = stream->endbuf; - stream->bufTech = mode; - if (!stream->textMode && (stream->bufTech == _IOLBF)) - { - stream->quickBin = 0; } - return (0); + /* Applying new settings to stream. */ + stream->status &= ~( _IOFBF | _IOLBF | _IONBF ); + stream->status |= mode; + stream->buffer = buf; + stream->bufsize = size; + stream->status &= ~_PDCLIB_VIRGINSTR; + return 0; } -*/ + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ +#ifndef REGTEST + TESTCASE( NO_TESTDRIVER ); +#else + puts( " NOTEST setvbuf() test driver is PDCLib-specific." ); +#endif + return TEST_RESULTS; +} + +#endif