diff options
| -rw-r--r-- | libc/stdio/_READ.c | 2 | ||||
| -rw-r--r-- | libc/stdio/_WRITE.c | 2 | ||||
| -rw-r--r-- | libc/stdio/_cs_funcs.c | 42 | ||||
| -rw-r--r-- | libc/stdio/_fopen.c | 2 | ||||
| -rw-r--r-- | libc/stdio/_rfill.c | 2 | ||||
| -rw-r--r-- | libc/stdio/_scanf.c | 27 | ||||
| -rw-r--r-- | libc/stdio/_stdio.c | 23 | ||||
| -rw-r--r-- | libc/stdio/_stdio.h | 102 | ||||
| -rw-r--r-- | libc/stdio/fclose.c | 2 | ||||
| -rw-r--r-- | libc/stdio/fopencookie.c | 29 | ||||
| -rw-r--r-- | libc/stdio/fread.c | 2 | ||||
| -rw-r--r-- | libc/stdio/vdprintf.c | 9 | ||||
| -rw-r--r-- | libc/stdio/vsnprintf.c | 46 | ||||
| -rw-r--r-- | libc/stdio/vswprintf.c | 9 | ||||
| -rw-r--r-- | libc/sysdeps/linux/common/bits/uClibc_stdio.h | 4 | ||||
| -rw-r--r-- | test/stdio/Makefile.in | 4 | ||||
| -rw-r--r-- | test/stdio/tst-fmemopen.c | 53 | 
17 files changed, 155 insertions, 205 deletions
| diff --git a/libc/stdio/_READ.c b/libc/stdio/_READ.c index 02601c090..a548dbb3f 100644 --- a/libc/stdio/_READ.c +++ b/libc/stdio/_READ.c @@ -27,7 +27,7 @@ size_t attribute_hidden __stdio_READ(register FILE *stream,  	ssize_t rv = 0;  	__STDIO_STREAM_VALIDATE(stream); -	assert(stream->__filedes >= -1); +	assert(stream->__filedes >= -2);  	assert(__STDIO_STREAM_IS_READING(stream));  	assert(!__STDIO_STREAM_BUFFER_RAVAIL(stream)); /* Buffer must be empty. */  	assert(!(stream->__modeflags & __FLAG_UNGOT)); diff --git a/libc/stdio/_WRITE.c b/libc/stdio/_WRITE.c index 6af5da8e4..712236f8f 100644 --- a/libc/stdio/_WRITE.c +++ b/libc/stdio/_WRITE.c @@ -36,7 +36,7 @@ size_t attribute_hidden __stdio_WRITE(register FILE *stream,  	ssize_t rv, stodo;  	__STDIO_STREAM_VALIDATE(stream); -	assert(stream->__filedes >= -1); +	assert(stream->__filedes >= -2);  	assert(__STDIO_STREAM_IS_WRITING(stream));  	assert(!__STDIO_STREAM_BUFFER_WUSED(stream)); /* Buffer must be empty. */ diff --git a/libc/stdio/_cs_funcs.c b/libc/stdio/_cs_funcs.c index 9df93f227..be416a450 100644 --- a/libc/stdio/_cs_funcs.c +++ b/libc/stdio/_cs_funcs.c @@ -8,46 +8,6 @@  #include "_stdio.h"  /**********************************************************************/ -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -/**********************************************************************/ - -ssize_t attribute_hidden _cs_read(void *cookie, char *buf, size_t bufsize) -{ -	return read(*((int *) cookie), buf, bufsize); -} - -/**********************************************************************/ - -ssize_t attribute_hidden _cs_write(void *cookie, const char *buf, size_t bufsize) -{ -	return write(*((int *) cookie), (char *) buf, bufsize); -} - -/**********************************************************************/ - -int attribute_hidden _cs_seek(void *cookie, register __offmax_t *pos, int whence) -{ -	__offmax_t res; - -#ifdef __UCLIBC_HAS_LFS__ -	res = lseek64(*((int *) cookie), *pos, whence); -#else -	res = lseek(*((int *) cookie), *pos, whence); -#endif - -	return (res >= 0) ? ((*pos = res), 0) : ((int) res); -} - -/**********************************************************************/ - -int attribute_hidden _cs_close(void *cookie) -{ -	return close(*((int *) cookie)); -} - -/**********************************************************************/ -#else -/**********************************************************************/  int attribute_hidden __stdio_seek(FILE *stream, register __offmax_t *pos, int whence)  { @@ -63,5 +23,3 @@ int attribute_hidden __stdio_seek(FILE *stream, register __offmax_t *pos, int wh  }  /**********************************************************************/ -#endif -/**********************************************************************/ diff --git a/libc/stdio/_fopen.c b/libc/stdio/_fopen.c index 5bc61cf39..be05c48a5 100644 --- a/libc/stdio/_fopen.c +++ b/libc/stdio/_fopen.c @@ -192,8 +192,6 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,  	__STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream);  #endif -	__STDIO_STREAM_RESET_GCS(stream); -  #ifdef __UCLIBC_HAS_WCHAR__  	stream->__ungot_width[0] = 0;  #endif diff --git a/libc/stdio/_rfill.c b/libc/stdio/_rfill.c index d61b1a9f9..e9d2fa698 100644 --- a/libc/stdio/_rfill.c +++ b/libc/stdio/_rfill.c @@ -24,7 +24,7 @@ size_t attribute_hidden __stdio_rfill(register FILE *__restrict stream)  	size_t rv;  	__STDIO_STREAM_VALIDATE(stream); -	assert(stream->__filedes >= -1); +	assert(stream->__filedes >= -2);  	assert(__STDIO_STREAM_IS_READING(stream));  	assert(!__STDIO_STREAM_BUFFER_RAVAIL(stream)); /* Buffer must be empty. */  	assert(__STDIO_STREAM_BUFFER_SIZE(stream));	/* Must have a buffer. */ diff --git a/libc/stdio/_scanf.c b/libc/stdio/_scanf.c index f2a96700b..80e49567f 100644 --- a/libc/stdio/_scanf.c +++ b/libc/stdio/_scanf.c @@ -202,15 +202,6 @@ int vsscanf(const char *sp, const char *fmt, va_list ap)  {  	FILE f; -/* 	__STDIO_STREAM_RESET_GCS(&f); */ -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -	f.__cookie = &(f.__filedes); -	f.__gcs.read = NULL; -	f.__gcs.write = NULL; -	f.__gcs.seek = NULL; -	f.__gcs.close = NULL; -#endif -  	f.__filedes = __STDIO_STREAM_FAKE_VSSCANF_FILEDES;  	f.__modeflags = (__FLAG_NARROW|__FLAG_READONLY|__FLAG_READING); @@ -249,15 +240,6 @@ int vsscanf(const char *sp, const char *fmt, va_list ap)  	f.bufpos = (unsigned char *) ((void *) sp);  	f.bufread = f.bufpos + strlen(sp); -/* 	__STDIO_STREAM_RESET_GCS(&f.f); */ -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -	f.f.__cookie = &(f.f.__filedes); -	f.f.__gcs.read = NULL; -	f.f.__gcs.write = NULL; -	f.f.__gcs.seek = NULL; -	f.f.__gcs.close = NULL; -#endif -  	f.f.__filedes = __STDIO_STREAM_FAKE_VSSCANF_FILEDES_NB;  	f.f.__modeflags = (__FLAG_NARROW|__FLAG_READONLY|__FLAG_READING); @@ -383,15 +365,6 @@ int vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict format,  	__STDIO_STREAM_DISABLE_GETC(&f);  	__STDIO_STREAM_DISABLE_PUTC(&f); -/* 	__STDIO_STREAM_RESET_GCS(&f); */ -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -	f.__cookie = &(f.__filedes); -	f.__gcs.read = NULL; -	f.__gcs.write = NULL; -	f.__gcs.seek = NULL; -	f.__gcs.close = NULL; -#endif -  	f.__filedes = __STDIO_STREAM_FAKE_VSWSCANF_FILEDES;  	f.__modeflags = (__FLAG_WIDE|__FLAG_READONLY|__FLAG_READING); diff --git a/libc/stdio/_stdio.c b/libc/stdio/_stdio.c index ee247a5fd..2a1054618 100644 --- a/libc/stdio/_stdio.c +++ b/libc/stdio/_stdio.c @@ -51,13 +51,6 @@  #define __STDIO_FILE_INIT_BUFFERS(buf,bufsize)  #endif -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -#define __STDIO_FILE_INIT_CUSTOM_STREAM(stream) \ -	&((stream).__filedes), { _cs_read, _cs_write, _cs_seek, _cs_close }, -#else -#define __STDIO_FILE_INIT_CUSTOM_STREAM(stream) -#endif -  #ifdef __STDIO_MBSTATE  #define __STDIO_FILE_INIT_MBSTATE \  	{ 0, 0 }, @@ -92,7 +85,6 @@  	__STDIO_FILE_INIT_BUFGETC((buf)) \  	__STDIO_FILE_INIT_BUFPUTC((buf)) \  	__STDIO_FILE_INIT_NEXT(next) \ -	__STDIO_FILE_INIT_CUSTOM_STREAM(stream) \  	__STDIO_FILE_INIT_WUNGOT \  	__STDIO_FILE_INIT_MBSTATE \  	__STDIO_FILE_INIT_UNUSED \ @@ -240,7 +232,7 @@ void _stdio_term(void)  #endif  #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__  		/* Actually close all custom streams to perform any special cleanup. */ -		if (ptr->__cookie != &ptr->__filedes) { +		if (__STDIO_STREAM_IS_CUSTOM(ptr)) {  			__CLOSE(ptr);  		}  #endif @@ -284,14 +276,9 @@ void attribute_hidden _stdio_validate_FILE(const FILE *stream)  #endif  #warning Define a constant for minimum possible valid __filedes? -	assert(stream->__filedes >= -3); +	assert(stream->__filedes >= -4);  	if (stream->__filedes < 0) { -/* 		assert((stream->__filedes != -1) */ -/* #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */ -/* 			   || (stream->__cookie == &stream->__filedes) /\* custom *\/ */ -/* #endif */ -/* 			   ); */  /* 		assert((stream->__filedes == -1) || __STDIO_STREAM_IS_FBF(stream)); */  		assert(!__STDIO_STREAM_IS_FAKE_VSNPRINTF(stream) @@ -308,12 +295,6 @@ void attribute_hidden _stdio_validate_FILE(const FILE *stream)  #endif  	} -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -	if (stream->__cookie != &stream->__filedes) { /* custom */ -		assert(stream->__filedes == -1); -	} -#endif -  	/* Can not be both narrow and wide oriented at the same time. */  	assert(!(__STDIO_STREAM_IS_NARROW(stream)  			 && __STDIO_STREAM_IS_WIDE(stream))); diff --git a/libc/stdio/_stdio.h b/libc/stdio/_stdio.h index 94557c257..310510d66 100644 --- a/libc/stdio/_stdio.h +++ b/libc/stdio/_stdio.h @@ -4,6 +4,8 @@   *   * Dedicated to Toni.  See uClibc/DEDICATION.mjn3 for details.   */ +#ifndef __STDIO_H_I +#define __STDIO_H_I 1  #include <features.h>  #include <assert.h> @@ -96,48 +98,61 @@ do { \  /**********************************************************************/  #ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -extern __ssize_t _cs_read(void *cookie, char *buf, size_t bufsize) attribute_hidden; -extern __ssize_t _cs_write(void *cookie, const char *buf, size_t bufsize) attribute_hidden; -extern int _cs_seek(void *cookie, __offmax_t *pos, int whence) attribute_hidden; -extern int _cs_close(void *cookie) attribute_hidden; - -#define __STDIO_STREAM_RESET_GCS(S) \ -	(S)->__cookie = &((S)->__filedes); \ -	(S)->__gcs.read = _cs_read; \ -	(S)->__gcs.write = _cs_write; \ -	(S)->__gcs.seek = _cs_seek; \ -	(S)->__gcs.close = _cs_close - - -#define __READ(STREAMPTR,BUF,SIZE) \ -	((((STREAMPTR)->__gcs.read) == NULL) ? -1 : \ -	(((STREAMPTR)->__gcs.read)((STREAMPTR)->__cookie,(BUF),(SIZE)))) -#define __WRITE(STREAMPTR,BUF,SIZE) \ -	((((STREAMPTR)->__gcs.write) == NULL) ? -1 : \ -	(((STREAMPTR)->__gcs.write)((STREAMPTR)->__cookie,(BUF),(SIZE)))) -#define __SEEK(STREAMPTR,PPOS,WHENCE) \ -	((((STREAMPTR)->__gcs.seek) == NULL) ? -1 : \ -	(((STREAMPTR)->__gcs.seek)((STREAMPTR)->__cookie,(PPOS),(WHENCE)))) -#define __CLOSE(STREAMPTR) \ -	((((STREAMPTR)->__gcs.close) == NULL) ? 0 : \ -	(((STREAMPTR)->__gcs.close)((STREAMPTR)->__cookie))) +#define __STDIO_STREAM_GLIBC_CUSTOM_FILEDES		(-2) + +#define __STDIO_STREAM_IS_CUSTOM(S) \ +	((S)->__filedes == __STDIO_STREAM_GLIBC_CUSTOM_FILEDES) + +#define __STDIO_STREAM_CUSTOM_IO_FUNC(S, NAME, RC, ARGS...) \ + if (__STDIO_STREAM_IS_CUSTOM((S))) { \ +	_IO_cookie_file_t *cfile = (_IO_cookie_file_t *) (S); \ +	return (cfile->__gcs.NAME == NULL) ? (RC) : \ +		cfile->__gcs.NAME(cfile->__cookie, ##ARGS); \ + } + +typedef struct { +  struct __STDIO_FILE_STRUCT __fp; +  void *__cookie; +  _IO_cookie_io_functions_t __gcs; +} _IO_cookie_file_t;  #else  /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */ +#undef __STDIO_STREAM_GLIBC_CUSTOM_FILEDES +#define __STDIO_STREAM_IS_CUSTOM(S)	(0) +#define __STDIO_STREAM_CUSTOM_IO_FUNC(S, NAME, RC, ARGS...) + +#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */ +  extern int __stdio_seek(FILE *stream, register __offmax_t *pos, int whence) attribute_hidden; -#define __STDIO_STREAM_RESET_GCS(S) ((void)0) +static inline ssize_t __READ(FILE *stream, char *buf, size_t bufsize) +{ +	__STDIO_STREAM_CUSTOM_IO_FUNC(stream, read, -1, buf, bufsize); -#define __READ(STREAMPTR,BUF,SIZE) \ -	(read((STREAMPTR)->__filedes,(BUF),(SIZE))) -#define __WRITE(STREAMPTR,BUF,SIZE) \ -	(write((STREAMPTR)->__filedes,(BUF),(SIZE))) -#define __SEEK(STREAMPTR,PPOS,WHENCE) \ -	(__stdio_seek((STREAMPTR),(PPOS),(WHENCE))) -#define __CLOSE(STREAMPTR) \ -	(close((STREAMPTR)->__filedes)) +	return read(stream->__filedes, buf, bufsize); +} -#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */ +static inline ssize_t __WRITE(FILE *stream, const char *buf, size_t bufsize) +{ +	__STDIO_STREAM_CUSTOM_IO_FUNC(stream, write, -1, buf, bufsize); + +	return write(stream->__filedes, buf, bufsize); +} + +static inline int __SEEK(FILE *stream, register __offmax_t *pos, int whence) +{ +	__STDIO_STREAM_CUSTOM_IO_FUNC(stream, seek, -1, pos, whence); + +	return __stdio_seek(stream, pos, whence); +} + +static inline int __CLOSE(FILE *stream) +{ +	__STDIO_STREAM_CUSTOM_IO_FUNC(stream, close, 0); + +	return close(stream->__filedes); +}  /**********************************************************************/  #ifdef __UCLIBC_HAS_WCHAR__ @@ -254,12 +269,6 @@ extern int __stdio_seek(FILE *stream, register __offmax_t *pos, int whence) attr  # define __STDIO_STREAM_CAN_USE_BUFFER_ADD(S)		(0)  #endif -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -#define __STDIO_STREAM_IS_CUSTOM(S)		((S)->__cookie != &((S)->__filedes)) -#else -#define __STDIO_STREAM_IS_CUSTOM(S)			(0) -#endif -  /**********************************************************************/  #ifdef __STDIO_BUFFERS @@ -346,10 +355,10 @@ extern void _store_inttype(void *dest, int desttype, uintmax_t val) attribute_hi  	(S)->__bufread = (S)->__bufpos = (S)->__bufstart -#define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES		(-2) -#define __STDIO_STREAM_FAKE_VSSCANF_FILEDES		(-2) -#define __STDIO_STREAM_FAKE_VSWPRINTF_FILEDES		(-3) -#define __STDIO_STREAM_FAKE_VSWSCANF_FILEDES		(-3) +#define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES		(-3) +#define __STDIO_STREAM_FAKE_VSSCANF_FILEDES		(-3) +#define __STDIO_STREAM_FAKE_VSWPRINTF_FILEDES		(-4) +#define __STDIO_STREAM_FAKE_VSWSCANF_FILEDES		(-4)  #define __STDIO_STREAM_IS_FAKE_VSNPRINTF(S) \  	((S)->__filedes == __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES) @@ -386,6 +395,7 @@ extern void _store_inttype(void *dest, int desttype, uintmax_t val) attribute_hi  #define __STDIO_STREAM_IS_FAKE_VSNPRINTF(S)			(0)  #define __STDIO_STREAM_IS_FAKE_VSSCANF(S)			(0)  #undef __STDIO_STREAM_IS_FAKE_VSWPRINTF +#undef __STDIO_STREAM_IS_FAKE_VSWSCANF  # ifdef __USE_OLD_VFPRINTF__  #  define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES_NB		(-2) @@ -461,3 +471,5 @@ extern int _vfwprintf_internal (FILE * __restrict stream,  #if defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__) || defined(__UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__)  #define __STDIO_HAS_VSNPRINTF 1  #endif + +#endif /* __STDIO_H_I */ diff --git a/libc/stdio/fclose.c b/libc/stdio/fclose.c index 3417b2678..7e7bc3b5b 100644 --- a/libc/stdio/fclose.c +++ b/libc/stdio/fclose.c @@ -69,8 +69,6 @@ int fclose(register FILE *stream)  	stream->__modeflags |= (__FLAG_READONLY|__FLAG_WRITEONLY);  #ifndef NDEBUG -	__STDIO_STREAM_RESET_GCS(stream); -  	/* Reinitialize everything (including putc since fflush could fail). */  	__STDIO_STREAM_DISABLE_GETC(stream);  	__STDIO_STREAM_DISABLE_PUTC(stream); diff --git a/libc/stdio/fopencookie.c b/libc/stdio/fopencookie.c index c4927e0bd..216dac39d 100644 --- a/libc/stdio/fopencookie.c +++ b/libc/stdio/fopencookie.c @@ -39,21 +39,34 @@ FILE *_fopencookie(void * __restrict cookie, const char * __restrict mode,  #endif  {  	FILE *stream; +	_IO_cookie_file_t *new_f; +	new_f = malloc(sizeof(_IO_cookie_file_t)); +	if (new_f == NULL) { +		return NULL; +	} +	new_f->__fp.__modeflags = __FLAG_FREEFILE; +#ifdef __STDIO_BUFFERS +	new_f->__fp.__bufstart = NULL; /* We allocate a buffer below. */ +#endif +#ifdef __UCLIBC_HAS_THREADS__ +	/* We only initialize the mutex in the non-freopen case. */ +	STDIO_INIT_MUTEX(new_f->__fp.__lock); +#endif  	/* Fake an fdopen guaranteed to pass the _stdio_fopen basic agreement  	 * check without an fcntl call. */ -	stream = _stdio_fopen(((intptr_t)(INT_MAX-1)), mode, NULL, INT_MAX); +	stream = _stdio_fopen(((intptr_t)(INT_MAX-1)), mode, &new_f->__fp, INT_MAX);  	if (stream) { -		stream->__filedes = -1; +		stream->__filedes = __STDIO_STREAM_GLIBC_CUSTOM_FILEDES;  #ifndef __BCC__ -		stream->__gcs = io_functions; +		new_f->__gcs = io_functions;  #else -		stream->__gcs.read  = io_functions->read; -		stream->__gcs.write = io_functions->write; -		stream->__gcs.seek  = io_functions->seek; -		stream->__gcs.close = io_functions->close; +		new_f->__gcs.read  = io_functions->read; +		new_f->__gcs.write = io_functions->write; +		new_f->__gcs.seek  = io_functions->seek; +		new_f->__gcs.close = io_functions->close;  #endif -		stream->__cookie = cookie; +		new_f->__cookie = cookie;  		__STDIO_STREAM_VALIDATE(stream);  	} diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c index d2fcc70d5..5df33b468 100644 --- a/libc/stdio/fread.c +++ b/libc/stdio/fread.c @@ -15,7 +15,7 @@ size_t fread_unlocked(void * __restrict ptr, size_t size, size_t nmemb,  						FILE * __restrict stream)  {  	__STDIO_STREAM_VALIDATE(stream); -	assert(stream->__filedes >= -1); +	assert(stream->__filedes >= -2);  	/* Note: If nmbem * size > SIZE_MAX then there is an application  	 * bug since no array can be larger than SIZE_MAX in size. */ diff --git a/libc/stdio/vdprintf.c b/libc/stdio/vdprintf.c index 457018bcf..46b8dfe39 100644 --- a/libc/stdio/vdprintf.c +++ b/libc/stdio/vdprintf.c @@ -26,15 +26,6 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg)  	__STDIO_STREAM_INIT_BUFREAD_BUFPOS(&f);  #endif -/* 	__STDIO_STREAM_RESET_GCS(&f); */ -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -	f.__cookie = &(f.__filedes); -	f.__gcs.read = NULL; -	f.__gcs.write = _cs_write; -	f.__gcs.seek = NULL; -	f.__gcs.close = NULL; -#endif -  	f.__filedes = filedes;  	f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING); diff --git a/libc/stdio/vsnprintf.c b/libc/stdio/vsnprintf.c index 31adc52b6..3a4c60794 100644 --- a/libc/stdio/vsnprintf.c +++ b/libc/stdio/vsnprintf.c @@ -22,15 +22,6 @@ int vsnprintf(char *__restrict buf, size_t size,  	FILE f;  	int rv; -/* 	__STDIO_STREAM_RESET_GCS(&f); */ -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -	f.__cookie = &(f.__filedes); -	f.__gcs.read = NULL; -	f.__gcs.write = NULL; -	f.__gcs.seek = NULL; -	f.__gcs.close = NULL; -#endif -  	f.__filedes = __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES;  	f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING); @@ -96,15 +87,6 @@ int vsnprintf(char *__restrict buf, size_t size,  	}  	f.bufend = buf + size; -/* 	__STDIO_STREAM_RESET_GCS(&f.f); */ -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -	f.f.__cookie = &(f.f.__filedes); -	f.f.__gcs.read = NULL; -	f.f.__gcs.write = NULL; -	f.f.__gcs.seek = NULL; -	f.f.__gcs.close = NULL; -#endif -  	f.f.__filedes = __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES_NB;  	f.f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING); @@ -137,7 +119,7 @@ libc_hidden_def(vsnprintf)  typedef struct {  	size_t pos;  	size_t len; -	unsigned char *buf; +	char *buf;  	FILE *fp;  } __snpf_cookie; @@ -175,34 +157,34 @@ static ssize_t snpf_write(register void *cookie, const char *buf,  int vsnprintf(char *__restrict buf, size_t size,  			  const char * __restrict format, va_list arg)  { -	FILE f; +	_IO_cookie_file_t cf;  	__snpf_cookie cookie;  	int rv;  	cookie.buf = buf;  	cookie.len = size;  	cookie.pos = 0; -	cookie.fp = &f; +	cookie.fp = &cf.__fp; -	f.__cookie = &cookie; -	f.__gcs.write = snpf_write; -	f.__gcs.read = NULL; -	f.__gcs.seek = NULL; -	f.__gcs.close = NULL; +	cf.__cookie = &cookie; +	cf.__gcs.write = snpf_write; +	cf.__gcs.read = NULL; +	cf.__gcs.seek = NULL; +	cf.__gcs.close = NULL; -	f.__filedes = -1;			/* For debugging. */ -	f.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING); +	cf.__fp.__filedes = __STDIO_STREAM_GLIBC_CUSTOM_FILEDES; +	cf.__fp.__modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING);  #ifdef __UCLIBC_HAS_WCHAR__ -	f.__ungot_width[0] = 0; +	cf.__fp.__ungot_width[0] = 0;  #endif /* __UCLIBC_HAS_WCHAR__ */  #ifdef __STDIO_MBSTATE -	__INIT_MBSTATE(&(f.__state)); +	__INIT_MBSTATE(&(cf.__fp.__state));  #endif /* __STDIO_MBSTATE */ -	f.__nextopen = NULL; +	cf.__fp.__nextopen = NULL; -	rv = _vfprintf_internal(&f, format, arg); +	rv = _vfprintf_internal(&cf.__fp, format, arg);  	return rv;  } diff --git a/libc/stdio/vswprintf.c b/libc/stdio/vswprintf.c index 219524830..58a06a763 100644 --- a/libc/stdio/vswprintf.c +++ b/libc/stdio/vswprintf.c @@ -22,15 +22,6 @@ int vswprintf(wchar_t *__restrict buf, size_t size,  	FILE f;  	int rv; -/* 	__STDIO_STREAM_RESET_GCS(&f); */ -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -	f.__cookie = &(f.__filedes); -	f.__gcs.read = NULL; -	f.__gcs.write = NULL; -	f.__gcs.seek = NULL; -	f.__gcs.close = NULL; -#endif -  	f.__filedes = __STDIO_STREAM_FAKE_VSWPRINTF_FILEDES;  	f.__modeflags = (__FLAG_WIDE|__FLAG_WRITEONLY|__FLAG_WRITING); diff --git a/libc/sysdeps/linux/common/bits/uClibc_stdio.h b/libc/sysdeps/linux/common/bits/uClibc_stdio.h index 5b3a1b310..efd8a6c89 100644 --- a/libc/sysdeps/linux/common/bits/uClibc_stdio.h +++ b/libc/sysdeps/linux/common/bits/uClibc_stdio.h @@ -245,10 +245,6 @@ struct __STDIO_FILE_STRUCT {  #ifdef __STDIO_HAS_OPENLIST  	struct __STDIO_FILE_STRUCT *__nextopen;  #endif -#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ -	void *__cookie; -	_IO_cookie_io_functions_t __gcs; -#endif  #ifdef __UCLIBC_HAS_WCHAR__  	wchar_t __ungot[2];  #endif diff --git a/test/stdio/Makefile.in b/test/stdio/Makefile.in index 0bfbd1362..14b5f19b9 100644 --- a/test/stdio/Makefile.in +++ b/test/stdio/Makefile.in @@ -2,3 +2,7 @@  # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.  DODIFF_64bit := 1 + +ifeq ($(UCLIBC_HAS_GLIBC_CUSTOM_STREAMS),) +TESTS_DISABLED += tst-fmemopen +endif diff --git a/test/stdio/tst-fmemopen.c b/test/stdio/tst-fmemopen.c new file mode 100644 index 000000000..384faa1c9 --- /dev/null +++ b/test/stdio/tst-fmemopen.c @@ -0,0 +1,53 @@ +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +static char *text_input = "1 23 43"; + +static const char *good_answer = "1 529 1849 "; + + +static int +do_test (void) +{ +    FILE *out, *in; +    int v, s; +    size_t size; +    char *ptr; + +    in = fmemopen(text_input, strlen(text_input), "r"); +    if (in == NULL) { +        perror("fmemopen"); +	return 1; +    } + +    out = open_memstream(&ptr, &size); +    if (out == NULL) { +        perror("open_memstream"); +	return 1; +    } + +    for (;;) { +        s = fscanf(in, "%d", &v); +        if (s <= 0) +            break; + +        s = fprintf(out, "%d ", v * v); +        if (s == -1) { +            puts("fprintf failed"); +	    exit(1); +	} +    } +    fclose(in); +    fclose(out); + +    if (size != strlen(good_answer) || strcmp(good_answer, ptr) != 0) { +	printf("failed: size=%zu; ptr=%s\n", size, ptr); +	exit(1); +    } +    free(ptr); +    exit(0); +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" | 
