| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 | /* Copyright (C) 2004       Manuel Novoa III    <mjn3@codepoet.org> * * GNU Library General Public License (LGPL) version 2 or later. * * Dedicated to Toni.  See uClibc/DEDICATION.mjn3 for details. */#include "_stdio.h"#if (_IOFBF != 0) || (_IOLBF != 1) || (_IONBF != 2)#error Assumption violated -- values of _IOFBF, _IOLBF, _IONBF#endif#if (__FLAG_FBF != 0) || (__FLAG_NBF != (2*__FLAG_LBF))#error Assumption violated for buffering mode flags#endifint setvbuf(register FILE * __restrict stream, register char * __restrict buf,			int mode, size_t size){#ifdef __STDIO_BUFFERS	int retval = EOF;	int alloc_flag = 0;	__STDIO_AUTO_THREADLOCK_VAR;	__STDIO_AUTO_THREADLOCK(stream);	__STDIO_STREAM_VALIDATE(stream);	if (((unsigned int) mode) > 2) {		__set_errno(EINVAL);		goto ERROR;	}	/* C99 states that setvbuf may only be used between a successful	 * open of the stream and before any other operation other than	 * an unsuccessful call to setvbuf. */#ifdef __STDIO_FLEXIBLE_SETVBUF	/* If we aren't currently reading (including ungots) or writing,	 * then allow the request to proceed. */	if (stream->__modeflags & (__MASK_READING|__FLAG_WRITING)) {		goto ERROR;	}#else	/* The following test isn't quite as strict as C99, as it will	 * not detect file positioning operations. */	if (stream->__modeflags & (__MASK_READING|__FLAG_WRITING							 |__FLAG_NARROW|__FLAG_WIDE							 |__FLAG_ERROR|__FLAG_EOF)		) {		goto ERROR;	}#endif	stream->__modeflags &= ~(__MASK_BUFMODE);	/* Clear current mode */	stream->__modeflags |= mode * __FLAG_LBF;	/*   and set new one. */	if ((mode == _IONBF) || !size) {		size = 0;		buf = NULL;	} else if (!buf) {		if ((__STDIO_STREAM_BUFFER_SIZE(stream) == size) /* Same size or */			|| !(buf = malloc(size)) /* malloc failed, so don't change. */			) {			goto DONE;		}		alloc_flag = __FLAG_FREEBUF;	}	if (stream->__modeflags & __FLAG_FREEBUF) {		stream->__modeflags &= ~(__FLAG_FREEBUF);		free(stream->__bufstart);	}	stream->__modeflags |= alloc_flag;	stream->__bufstart = (unsigned char *) buf;	stream->__bufend = (unsigned char *) buf + size;	__STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream);	__STDIO_STREAM_DISABLE_GETC(stream);	__STDIO_STREAM_DISABLE_PUTC(stream); DONE:	retval = 0; ERROR:	__STDIO_STREAM_VALIDATE(stream);	__STDIO_AUTO_THREADUNLOCK(stream);	return retval;#else  /* __STDIO_BUFFERS  */	if (mode == _IONBF) {		return 0;	}	if (((unsigned int) mode) > 2) {		__set_errno(EINVAL);	}	return EOF;#endif}libc_hidden_def(setvbuf)
 |