summaryrefslogtreecommitdiffstats
path: root/libc/stdio
diff options
context:
space:
mode:
Diffstat (limited to 'libc/stdio')
-rw-r--r--libc/stdio/_READ.c2
-rw-r--r--libc/stdio/_WRITE.c2
-rw-r--r--libc/stdio/_fopen.c37
-rw-r--r--libc/stdio/_fpmaxtostr.c2
-rw-r--r--libc/stdio/_fwrite.c6
-rw-r--r--libc/stdio/_scanf.c59
-rw-r--r--libc/stdio/_stdio.c44
-rw-r--r--libc/stdio/_stdio.h174
-rw-r--r--libc/stdio/_store_inttype.c2
-rw-r--r--libc/stdio/_uintmaxtostr.c2
-rw-r--r--libc/stdio/_vfprintf.c157
-rw-r--r--libc/stdio/ctermid.c2
-rw-r--r--libc/stdio/fclose.c31
-rw-r--r--libc/stdio/fcloseall.c35
-rw-r--r--libc/stdio/fflush.c101
-rw-r--r--libc/stdio/flockfile.c2
-rw-r--r--libc/stdio/fmemopen.c2
-rw-r--r--libc/stdio/fputc.c6
-rw-r--r--libc/stdio/fputs.c2
-rw-r--r--libc/stdio/fread.c2
-rw-r--r--libc/stdio/freopen.c15
-rw-r--r--libc/stdio/ftello.c5
-rw-r--r--libc/stdio/ftrylockfile.c2
-rw-r--r--libc/stdio/funlockfile.c2
-rw-r--r--libc/stdio/getchar.c3
-rw-r--r--libc/stdio/gets.c6
-rw-r--r--libc/stdio/old_vfprintf.c12
-rw-r--r--libc/stdio/open_memstream.c8
-rw-r--r--libc/stdio/popen.c34
-rw-r--r--libc/stdio/setvbuf.c4
-rw-r--r--libc/stdio/tempnam.c2
-rw-r--r--libc/stdio/tmpnam.c2
-rw-r--r--libc/stdio/vasprintf.c2
-rw-r--r--libc/stdio/vdprintf.c20
-rw-r--r--libc/stdio/vsnprintf.c36
-rw-r--r--libc/stdio/vswprintf.c12
36 files changed, 506 insertions, 329 deletions
diff --git a/libc/stdio/_READ.c b/libc/stdio/_READ.c
index 0c7febb3c..bafa8dffe 100644
--- a/libc/stdio/_READ.c
+++ b/libc/stdio/_READ.c
@@ -44,7 +44,7 @@ size_t attribute_hidden __stdio_READ(register FILE *stream,
#warning EINTR?
#endif
/* RETRY: */
- if ((rv = __READ(stream, buf, bufsize)) <= 0) {
+ if ((rv = __READ(stream, (char *) buf, bufsize)) <= 0) {
if (rv == 0) {
__STDIO_STREAM_SET_EOF(stream);
} else {
diff --git a/libc/stdio/_WRITE.c b/libc/stdio/_WRITE.c
index 2bd0977fd..83714bd4c 100644
--- a/libc/stdio/_WRITE.c
+++ b/libc/stdio/_WRITE.c
@@ -49,7 +49,7 @@ size_t attribute_hidden __stdio_WRITE(register FILE *stream,
return bufsize;
}
stodo = (todo <= SSIZE_MAX) ? todo : SSIZE_MAX;
- if ((rv = __WRITE(stream, buf, stodo)) >= 0) {
+ if ((rv = __WRITE(stream, (char *) buf, stodo)) >= 0) {
#ifdef __UCLIBC_MJN3_ONLY__
#warning TODO: Make custom stream write return check optional.
#endif
diff --git a/libc/stdio/_fopen.c b/libc/stdio/_fopen.c
index 58066ea3f..d68f2ead1 100644
--- a/libc/stdio/_fopen.c
+++ b/libc/stdio/_fopen.c
@@ -76,13 +76,13 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,
while (*++mode) {
# ifdef __UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE__
- if (*mode == 'x') { /* Open exclusive (a glibc extension). */
+ if (*mode == 'x') { /* Open exclusive (a glibc extension). */
open_mode |= O_EXCL;
continue;
}
# endif
# ifdef __UCLIBC_HAS_FOPEN_LARGEFILE_MODE__
- if (*mode == 'F') { /* Open as large file (uClibc extension). */
+ if (*mode == 'F') { /* Open as large file (uClibc extension). */
open_mode |= O_LARGEFILE;
continue;
}
@@ -102,11 +102,7 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,
#ifdef __UCLIBC_HAS_THREADS__
/* We only initialize the mutex in the non-freopen case. */
/* stream->__user_locking = _stdio_user_locking; */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (stream->_lock);
-#else
- __stdio_init_mutex(&stream->__lock);
-#endif
+ STDIO_INIT_MUTEX(stream->__lock);
#endif
}
@@ -198,18 +194,27 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,
#ifdef __UCLIBC_HAS_THREADS__
/* Even in the freopen case, we reset the user locking flag. */
stream->__user_locking = _stdio_user_locking;
-#ifdef __USE_STDIO_FUTEXES__
- /* _IO_lock_init (stream->_lock); */
-#else
- /* __stdio_init_mutex(&stream->__lock); */
-#endif
+ /* STDIO_INIT_MUTEX(stream->__lock); */
#endif
#ifdef __STDIO_HAS_OPENLIST
- __STDIO_THREADLOCK_OPENLIST;
- stream->__nextopen = _stdio_openlist; /* New files are inserted at */
- _stdio_openlist = stream; /* the head of the list. */
- __STDIO_THREADUNLOCK_OPENLIST;
+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
+ if (!(stream->__modeflags & __FLAG_FREEFILE))
+ {
+ /* An freopen call so the file was never removed from the list. */
+ }
+ else
+#endif
+ {
+ /* We have to lock the del mutex in case another thread wants to fclose()
+ * the last file. */
+ __STDIO_THREADLOCK_OPENLIST_DEL;
+ __STDIO_THREADLOCK_OPENLIST_ADD;
+ stream->__nextopen = _stdio_openlist; /* New files are inserted at */
+ _stdio_openlist = stream; /* the head of the list. */
+ __STDIO_THREADUNLOCK_OPENLIST_ADD;
+ __STDIO_THREADUNLOCK_OPENLIST_DEL;
+ }
#endif
__STDIO_STREAM_VALIDATE(stream);
diff --git a/libc/stdio/_fpmaxtostr.c b/libc/stdio/_fpmaxtostr.c
index f5632337d..2a63fda9d 100644
--- a/libc/stdio/_fpmaxtostr.c
+++ b/libc/stdio/_fpmaxtostr.c
@@ -11,7 +11,7 @@
#include <locale.h>
#include <bits/uClibc_fpmax.h>
-libc_hidden_proto(memset)
+/* Experimentally off - libc_hidden_proto(memset) */
typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len,
intptr_t buf);
diff --git a/libc/stdio/_fwrite.c b/libc/stdio/_fwrite.c
index 1e0f7ceee..ba4b02fb1 100644
--- a/libc/stdio/_fwrite.c
+++ b/libc/stdio/_fwrite.c
@@ -7,9 +7,9 @@
#include "_stdio.h"
-libc_hidden_proto(memchr)
-libc_hidden_proto(memcpy)
-libc_hidden_proto(memrchr)
+/* Experimentally off - libc_hidden_proto(memchr) */
+/* Experimentally off - libc_hidden_proto(memcpy) */
+/* Experimentally off - libc_hidden_proto(memrchr) */
#ifdef __STDIO_BUFFERS
diff --git a/libc/stdio/_scanf.c b/libc/stdio/_scanf.c
index 2957d6748..cb768cffb 100644
--- a/libc/stdio/_scanf.c
+++ b/libc/stdio/_scanf.c
@@ -77,10 +77,10 @@
#include <bits/uClibc_fpmax.h>
#endif /* __UCLIBC_HAS_FLOATS__ */
-libc_hidden_proto(memcmp)
-libc_hidden_proto(memset)
-libc_hidden_proto(strcpy)
-libc_hidden_proto(strlen)
+/* Experimentally off - libc_hidden_proto(memcmp) */
+/* Experimentally off - libc_hidden_proto(memset) */
+/* Experimentally off - libc_hidden_proto(strcpy) */
+/* Experimentally off - libc_hidden_proto(strlen) */
libc_hidden_proto(ungetc)
libc_hidden_proto(vfscanf)
libc_hidden_proto(vsscanf)
@@ -100,7 +100,7 @@ libc_hidden_proto(fgetwc_unlocked)
#endif
#ifdef __UCLIBC_HAS_XLOCALE__
libc_hidden_proto(__ctype_b_loc)
-#elif __UCLIBC_HAS_CTYPE_TABLES__
+#elif defined __UCLIBC_HAS_CTYPE_TABLES__
libc_hidden_proto(__ctype_b)
#endif
@@ -265,17 +265,13 @@ int vsscanf(__const char *sp, __const char *fmt, va_list ap)
#ifdef __UCLIBC_HAS_THREADS__
f.__user_locking = 1; /* Set user locking. */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (f._lock);
-#else
- __stdio_init_mutex(&f.__lock);
-#endif
+ STDIO_INIT_MUTEX(f.__lock);
#endif
f.__nextopen = NULL;
/* Set these last since __bufgetc initialization depends on
* __user_locking and only gets set if user locking is on. */
- f.__bufstart =
+ f.__bufstart =
f.__bufpos = (unsigned char *) ((void *) sp);
f.__bufread =
f.__bufend = f.__bufstart + strlen(sp);
@@ -317,11 +313,7 @@ int vsscanf(__const char *sp, __const char *fmt, va_list ap)
#ifdef __UCLIBC_HAS_THREADS__
f.f.__user_locking = 1; /* Set user locking. */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (f.f._lock);
-#else
- __stdio_init_mutex(&f.f.__lock);
-#endif
+ STDIO_INIT_MUTEX(f.f.__lock);
#endif
f.f.__nextopen = NULL;
@@ -454,11 +446,7 @@ int vswscanf(const wchar_t * __restrict str, const wchar_t * __restrict format,
#ifdef __UCLIBC_HAS_THREADS__
f.__user_locking = 1; /* Set user locking. */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (f._lock);
-#else
- __stdio_init_mutex(&f.__lock);
-#endif
+ STDIO_INIT_MUTEX(f.__lock);
#endif
f.__nextopen = NULL;
@@ -518,7 +506,7 @@ enum {
FLAG_THOUSANDS = 0x20,
FLAG_I18N = 0x40, /* only works for d, i, u */
FLAG_MALLOC = 0x80, /* only works for s, S, and [ (and l[)*/
-};
+};
#define SPEC_RANGES { CONV_n, CONV_p, CONV_i, CONV_A, \
@@ -743,7 +731,7 @@ void attribute_hidden __init_scan_cookie(register struct scan_cookie *sc,
sc->decpt = __UCLIBC_CURLOCALE_DATA.decimal_point;
sc->decpt_len = __UCLIBC_CURLOCALE_DATA.decimal_point_len;
#else /* __UCLIBC_HAS_LOCALE__ */
- sc->fake_decpt = sc->decpt = decpt_str;
+ sc->fake_decpt = sc->decpt = (unsigned char *) decpt_str;
sc->decpt_len = 1;
#endif /* __UCLIBC_HAS_LOCALE__ */
#ifdef __UCLIBC_HAS_WCHAR__
@@ -1036,7 +1024,7 @@ static int scan_getwc(register struct scan_cookie *sc)
__set_errno(EILSEQ); /* In case of incomplete conversion. */
sc->mb_fail = 1;
}
-
+
SUCCESS:
sc->width = width; /* Restore width. */
@@ -1080,9 +1068,6 @@ static int sc_getc(register struct scan_cookie *sc)
wc = '.';
} else
#endif /* __UCLIBC_HAS_FLOATS__ */
- if (!__isascii(wc)) {
- wc = '?';
- }
sc->wc = sc->ungot_char = wc;
return (int) wc;
@@ -1378,7 +1363,7 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg)
if (psfs.conv_num == CONV_percent) {
goto MATCH_CHAR;
- }
+ }
if (psfs.conv_num == CONV_n) {
#ifdef __UCLIBC_MJN3_ONLY__
@@ -1422,7 +1407,6 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg)
{
b = (psfs.store ? ((unsigned char *) psfs.cur_ptr) : buf);
fail = 1;
-
if (psfs.conv_num == CONV_c) {
if (sc.width == INT_MAX) {
@@ -1463,7 +1447,7 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg)
if (*++fmt == '^') {
++fmt;
invert = 1;
- }
+ }
memset(scanset, invert, sizeof(scanset));
invert = 1-invert;
@@ -1531,7 +1515,7 @@ int VFSCANF (FILE *__restrict fp, const Wchar *__restrict format, va_list arg)
wb = (psfs.store ? ((wchar_t *) psfs.cur_ptr) : wbuf);
fail = 1;
-
+
if (psfs.conv_num == CONV_C) {
if (sc.width == INT_MAX) {
sc.width = 1;
@@ -1808,7 +1792,6 @@ int attribute_hidden __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc)
unsigned char usflag, base;
unsigned char nonzero = 0;
unsigned char seendigit = 0;
-
#ifdef __UCLIBC_MJN3_ONLY__
#warning CONSIDER: What should be returned for an invalid conversion specifier?
@@ -1840,7 +1823,7 @@ int attribute_hidden __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc)
if (psfs->store) {
++psfs->cnt;
_store_inttype(psfs->cur_ptr, psfs->dataargtype,
- (uintmax_t) NULL);
+ (uintmax_t)0);
}
return 0;
}
@@ -2101,7 +2084,7 @@ int attribute_hidden __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc)
}
++psfs->cnt;
_store_inttype(psfs->cur_ptr, psfs->dataargtype,
- (uintmax_t) STRTOUIM(buf, NULL, base, 1-usflag));
+ (uintmax_t) STRTOUIM((char *) buf, NULL, base, 1-usflag));
}
return 0;
}
@@ -2115,7 +2098,7 @@ int attribute_hidden __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc)
p = sc->fake_decpt;
do {
if (!*p) {
- strcpy(b, sc->decpt);
+ strcpy((char *) b, (char *) sc->decpt);
b += sc->decpt_len;
break;
}
@@ -2222,7 +2205,7 @@ int attribute_hidden __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc)
assert(seendigit);
seendigit = 0;
nonzero = 0;
-
+
if (sc->cc == '0') {
seendigit = 1;
*b++ = '0';
@@ -2238,7 +2221,7 @@ int attribute_hidden __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc)
}
__scan_getc(sc);
}
-
+
if (!seendigit) { /* No digits. Unrecoverable. */
goto DONE_DO_UNGET;
}
@@ -2250,7 +2233,7 @@ int attribute_hidden __psfs_do_numeric(psfs_t *psfs, struct scan_cookie *sc)
{
__fpmax_t x;
char *e;
- x = __strtofpmax(buf, &e, exp_adjust);
+ x = __strtofpmax((char *) buf, &e, exp_adjust);
assert(!*e);
if (psfs->store) {
if (psfs->dataargtype & PA_FLAG_LONG_LONG) {
diff --git a/libc/stdio/_stdio.c b/libc/stdio/_stdio.c
index 4975ef02e..6084abec9 100644
--- a/libc/stdio/_stdio.c
+++ b/libc/stdio/_stdio.c
@@ -7,7 +7,7 @@
#include "_stdio.h"
-libc_hidden_proto(memcpy)
+/* Experimentally off - libc_hidden_proto(memcpy) */
libc_hidden_proto(isatty)
/* This is pretty much straight from uClibc, but with one important
@@ -160,14 +160,18 @@ FILE *_stdio_openlist = _stdio_streams;
# ifdef __UCLIBC_HAS_THREADS__
# ifdef __USE_STDIO_FUTEXES__
-# include <bits/stdio-lock.h>
-_IO_lock_t _stdio_openlist_lock = _IO_lock_initializer;
+# define __UCLIBC_IO_MUTEX_INITIALIZER _IO_lock_initializer
# else
-pthread_mutex_t _stdio_openlist_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+# define __UCLIBC_IO_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
# endif
-int _stdio_openlist_delflag = 0;
-# endif
+__UCLIBC_IO_MUTEX_INIT(_stdio_openlist_add_lock, __UCLIBC_IO_MUTEX_INITIALIZER);
+# ifdef __STDIO_BUFFERS
+__UCLIBC_IO_MUTEX_INIT(_stdio_openlist_del_lock, __UCLIBC_IO_MUTEX_INITIALIZER);
+volatile int _stdio_openlist_use_count = 0;
+int _stdio_openlist_del_count = 0;
+# endif
+# endif
#endif
/**********************************************************************/
#ifdef __UCLIBC_HAS_THREADS__
@@ -175,15 +179,13 @@ int _stdio_openlist_delflag = 0;
/* 2 if threading not initialized and 0 otherwise; */
int _stdio_user_locking = 2;
-#ifndef __USE_STDIO_FUTEXES__
-void attribute_hidden __stdio_init_mutex(pthread_mutex_t *m)
+void attribute_hidden __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m)
{
- static const pthread_mutex_t __stdio_mutex_initializer
- = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+ const __UCLIBC_MUTEX_STATIC(__stdio_mutex_initializer,
+ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
memcpy(m, &__stdio_mutex_initializer, sizeof(__stdio_mutex_initializer));
}
-#endif
#endif
/**********************************************************************/
@@ -198,11 +200,11 @@ void attribute_hidden _stdio_term(void)
/* First, make sure the open file list is unlocked. If it was
* locked, then I suppose there is a chance that a pointer in the
* chain might be corrupt due to a partial store.
- */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (_stdio_openlist_lock);
-#else
- __stdio_init_mutex(&_stdio_openlist_lock);
+ */
+ STDIO_INIT_MUTEX(_stdio_openlist_add_lock);
+#warning check
+#ifdef __STDIO_BUFFERS
+ STDIO_INIT_MUTEX(_stdio_openlist_del_lock);
#endif
/* Next we need to worry about the streams themselves. If a stream
@@ -211,7 +213,7 @@ void attribute_hidden _stdio_term(void)
* Then we reinitialize the locks.
*/
for (ptr = _stdio_openlist ; ptr ; ptr = ptr->__nextopen ) {
- if (__STDIO_ALWAYS_THREADTRYLOCK(ptr)) {
+ if (__STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(ptr)) {
/* The stream is already locked, so we don't want to touch it.
* However, if we have custom streams, we can't just close it
* or leave it locked since a custom stream may be stacked
@@ -222,13 +224,9 @@ void attribute_hidden _stdio_term(void)
__STDIO_STREAM_DISABLE_PUTC(ptr);
__STDIO_STREAM_INIT_BUFREAD_BUFPOS(ptr);
}
-
+
ptr->__user_locking = 1; /* Set locking mode to "by caller". */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (ptr->_lock);
-#else
- __stdio_init_mutex(&ptr->__lock); /* Shouldn't be necessary, but... */
-#endif
+ STDIO_INIT_MUTEX(ptr->__lock); /* Shouldn't be necessary, but... */
}
#endif
diff --git a/libc/stdio/_stdio.h b/libc/stdio/_stdio.h
index 58b013dda..e8ef08983 100644
--- a/libc/stdio/_stdio.h
+++ b/libc/stdio/_stdio.h
@@ -15,39 +15,76 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
#include <unistd.h>
#ifdef __UCLIBC_HAS_WCHAR__
#include <wchar.h>
#endif
-#ifdef __UCLIBC_HAS_THREADS__
-#include <pthread.h>
+#include <bits/uClibc_mutex.h>
-#ifdef __USE_STDIO_FUTEXES__
-#define __STDIO_THREADLOCK_OPENLIST \
- _IO_lock_lock(_stdio_openlist_lock)
+#define __STDIO_THREADLOCK_OPENLIST_ADD \
+ __UCLIBC_IO_MUTEX_LOCK(_stdio_openlist_add_lock)
-#define __STDIO_THREADUNLOCK_OPENLIST \
- _IO_lock_unlock(_stdio_openlist_lock)
+#define __STDIO_THREADUNLOCK_OPENLIST_ADD \
+ __UCLIBC_IO_MUTEX_UNLOCK(_stdio_openlist_add_lock)
-#define __STDIO_THREADTRYLOCK_OPENLIST \
- _IO_lock_trylock(_stdio_openlist_lock)
-#else
-#define __STDIO_THREADLOCK_OPENLIST \
- __pthread_mutex_lock(&_stdio_openlist_lock)
+#ifdef __STDIO_BUFFERS
-#define __STDIO_THREADUNLOCK_OPENLIST \
- __pthread_mutex_unlock(&_stdio_openlist_lock)
+#define __STDIO_THREADLOCK_OPENLIST_DEL \
+ __UCLIBC_IO_MUTEX_LOCK(_stdio_openlist_del_lock)
-#define __STDIO_THREADTRYLOCK_OPENLIST \
- __pthread_mutex_trylock(&_stdio_openlist_lock)
-#endif
+#define __STDIO_THREADUNLOCK_OPENLIST_DEL \
+ __UCLIBC_IO_MUTEX_UNLOCK(_stdio_openlist_del_lock)
-#else
-#define __STDIO_THREADLOCK_OPENLIST ((void)0)
-#define __STDIO_THREADUNLOCK_OPENLIST ((void)0)
+#ifdef __UCLIBC_HAS_THREADS__
+#define __STDIO_OPENLIST_INC_USE \
+do { \
+ __STDIO_THREADLOCK_OPENLIST_DEL; \
+ ++_stdio_openlist_use_count; \
+ __STDIO_THREADUNLOCK_OPENLIST_DEL; \
+} while (0)
+
+extern void _stdio_openlist_dec_use(void);
+
+#define __STDIO_OPENLIST_DEC_USE \
+ _stdio_openlist_dec_use()
+
+#define __STDIO_OPENLIST_INC_DEL_CNT \
+do { \
+ __STDIO_THREADLOCK_OPENLIST_DEL; \
+ ++_stdio_openlist_del_count; \
+ __STDIO_THREADUNLOCK_OPENLIST_DEL; \
+} while (0)
+
+#define __STDIO_OPENLIST_DEC_DEL_CNT \
+do { \
+ __STDIO_THREADLOCK_OPENLIST_DEL; \
+ --_stdio_openlist_del_count; \
+ __STDIO_THREADUNLOCK_OPENLIST_DEL; \
+} while (0)
+
+#endif /* __UCLIBC_HAS_THREADS__ */
+#endif /* __STDIO_BUFFERS */
+#ifndef __STDIO_THREADLOCK_OPENLIST_DEL
+#define __STDIO_THREADLOCK_OPENLIST_DEL ((void)0)
+#endif
+#ifndef __STDIO_THREADUNLOCK_OPENLIST_DEL
+#define __STDIO_THREADUNLOCK_OPENLIST_DEL ((void)0)
+#endif
+#ifndef __STDIO_OPENLIST_INC_USE
+#define __STDIO_OPENLIST_INC_USE ((void)0)
+#endif
+#ifndef __STDIO_OPENLIST_DEC_USE
+#define __STDIO_OPENLIST_DEC_USE ((void)0)
+#endif
+#ifndef __STDIO_OPENLIST_INC_DEL_CNT
+#define __STDIO_OPENLIST_INC_DEL_CNT ((void)0)
+#endif
+#ifndef __STDIO_OPENLIST_DEC_DEL_CNT
+#define __STDIO_OPENLIST_DEC_DEL_CNT ((void)0)
#endif
#define __UNDEFINED_OR_NONPORTABLE ((void)0)
@@ -91,10 +128,10 @@ extern int __stdio_seek(FILE *stream, register __offmax_t *pos, int whence) attr
(read((STREAMPTR)->__filedes,(BUF),(SIZE)))
#define __WRITE(STREAMPTR,BUF,SIZE) \
(write((STREAMPTR)->__filedes,(BUF),(SIZE)))
-#define __CLOSE(STREAMPTR) \
- (close((STREAMPTR)->__filedes))
#define __SEEK(STREAMPTR,PPOS,WHENCE) \
(__stdio_seek((STREAMPTR),(PPOS),(WHENCE)))
+#define __CLOSE(STREAMPTR) \
+ (close((STREAMPTR)->__filedes))
#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */
@@ -131,30 +168,30 @@ extern int __stdio_seek(FILE *stream, register __offmax_t *pos, int whence) attr
/**********************************************************************/
#ifdef __UCLIBC_HAS_WCHAR__
-#define __STDIO_STREAM_IS_NARROW_WRITING(S) \
- (((S)->__modeflags & (__FLAG_WRITING|__FLAG_NARROW)) \
+#define __STDIO_STREAM_IS_NARROW_WRITING(S) \
+ (((S)->__modeflags & (__FLAG_WRITING|__FLAG_NARROW)) \
== (__FLAG_WRITING|__FLAG_NARROW))
-#define __STDIO_STREAM_IS_WIDE_WRITING(S) \
- (((S)->__modeflags & (__FLAG_WRITING|__FLAG_WIDE)) \
+#define __STDIO_STREAM_IS_WIDE_WRITING(S) \
+ (((S)->__modeflags & (__FLAG_WRITING|__FLAG_WIDE)) \
== (__FLAG_WRITING|__FLAG_WIDE))
#if (__FLAG_NARROW <= __MASK_READING)
#error assumption violated regarding __FLAG_NARROW
#endif
-#define __STDIO_STREAM_IS_NARROW_READING(S) \
+#define __STDIO_STREAM_IS_NARROW_READING(S) \
(((S)->__modeflags & (__MASK_READING|__FLAG_NARROW)) > __FLAG_NARROW)
-#define __STDIO_STREAM_IS_WIDE_READING(S) \
+#define __STDIO_STREAM_IS_WIDE_READING(S) \
(((S)->__modeflags & (__MASK_READING|__FLAG_WIDE)) > __FLAG_WIDE)
#define __STDIO_STREAM_IS_NARROW(S) ((S)->__modeflags & __FLAG_NARROW)
#define __STDIO_STREAM_IS_WIDE(S) ((S)->__modeflags & __FLAG_WIDE)
-#define __STDIO_STREAM_SET_NARROW(S) \
+#define __STDIO_STREAM_SET_NARROW(S) \
((void)((S)->__modeflags |= __FLAG_NARROW))
-#define __STDIO_STREAM_SET_WIDE(S) \
+#define __STDIO_STREAM_SET_WIDE(S) \
((void)((S)->__modeflags |= __FLAG_WIDE))
#else
@@ -163,11 +200,11 @@ extern int __stdio_seek(FILE *stream, register __offmax_t *pos, int whence) attr
#define __STDIO_STREAM_IS_NARROW_READING(S) __STDIO_STREAM_IS_READING(S)
-#define __STDIO_STREAM_IS_NARROW(S) (1)
-#define __STDIO_STREAM_IS_WIDE(S) (0)
+#define __STDIO_STREAM_IS_NARROW(S) (1)
+#define __STDIO_STREAM_IS_WIDE(S) (0)
-#define __STDIO_STREAM_SET_NARROW(S) ((void)0)
-#define __STDIO_STREAM_SET_WIDE(S) ((void)0)
+#define __STDIO_STREAM_SET_NARROW(S) ((void)0)
+#define __STDIO_STREAM_SET_WIDE(S) ((void)0)
#endif
/**********************************************************************/
@@ -197,7 +234,7 @@ extern int __stdio_seek(FILE *stream, register __offmax_t *pos, int whence) attr
#else
# define __STDIO_STREAM_DISABLE_GETC(S) ((void)0)
# define __STDIO_STREAM_ENABLE_GETC(S) ((void)0)
-# define __STDIO_STREAM_CAN_USE_BUFFER_GET(S) (0)
+# define __STDIO_STREAM_CAN_USE_BUFFER_GET(S) (0)
#endif
#ifdef __UCLIBC_HAS_STDIO_PUTC_MACRO__
@@ -210,26 +247,28 @@ extern int __stdio_seek(FILE *stream, register __offmax_t *pos, int whence) attr
#else
# define __STDIO_STREAM_DISABLE_PUTC(S) ((void)0)
# define __STDIO_STREAM_ENABLE_PUTC(S) ((void)0)
-# define __STDIO_STREAM_CAN_USE_BUFFER_ADD(S) (0)
+# 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)
+#define __STDIO_STREAM_IS_CUSTOM(S) (0)
#endif
/**********************************************************************/
#ifdef __STDIO_BUFFERS
-#define __STDIO_STREAM_FREE_BUFFER(S) \
- do { if ((S)->__modeflags & __FLAG_FREEBUF) free((S)->__bufstart); } while (0)
+#define __STDIO_STREAM_FREE_BUFFER(S) \
+ do { if ((S)->__modeflags & __FLAG_FREEBUF) \
+ free((S)->__bufstart); } while (0)
#else
#define __STDIO_STREAM_FREE_BUFFER(S) ((void)0)
#endif
#define __STDIO_STREAM_FREE_FILE(S) \
- do { if ((S)->__modeflags & __FLAG_FREEFILE) free((S)); } while (0)
+ do { if ((S)->__modeflags & __FLAG_FREEFILE) \
+ free((S)); } while (0)
#ifdef __UCLIBC_HAS_LFS__
@@ -251,7 +290,7 @@ extern size_t __stdio_wcommit(FILE *__restrict stream) attribute_hidden;
extern size_t __stdio_rfill(FILE *__restrict stream) attribute_hidden;
extern size_t __stdio_fwrite(const unsigned char *__restrict buffer,
- size_t bytes, FILE *__restrict stream) attribute_hidden;
+ size_t bytes, FILE *__restrict stream) attribute_hidden;
#else
#define __stdio_fwrite(B,N,S) __stdio_WRITE((S),(B),(N))
@@ -259,8 +298,9 @@ extern size_t __stdio_fwrite(const unsigned char *__restrict buffer,
#endif
extern size_t __stdio_WRITE(FILE *stream, const unsigned char *buf,
- size_t bufsize) attribute_hidden;
-extern size_t __stdio_READ(FILE *stream, unsigned char *buf, size_t bufsize) attribute_hidden;
+ size_t bufsize) attribute_hidden;
+extern size_t __stdio_READ(FILE *stream, unsigned char *buf,
+ size_t bufsize) attribute_hidden;
extern int __stdio_trans2r(FILE *__restrict stream) attribute_hidden;
extern int __stdio_trans2w(FILE *__restrict stream) attribute_hidden;
@@ -293,14 +333,14 @@ extern int __stdio_trans2w_o(FILE *__restrict stream, int oflag) attribute_hidde
/* Valid when reading... */
#define __STDIO_STREAM_BUFFER_RAVAIL(S) ((S)->__bufread - (S)->__bufpos)
#define __STDIO_STREAM_BUFFER_GET(S) (*(S)->__bufpos++)
-#define __STDIO_FILL_READ_BUFFER(S) __stdio_rfill((S))
+#define __STDIO_FILL_READ_BUFFER(S) __stdio_rfill((S))
-#define __STDIO_STREAM_INIT_BUFREAD_BUFPOS(S) \
+#define __STDIO_STREAM_INIT_BUFREAD_BUFPOS(S) \
(S)->__bufread = (S)->__bufpos = (S)->__bufstart
#define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES (-2)
-#define __STDIO_STREAM_FAKE_VSSCANF_FILEDES (-2)
+#define __STDIO_STREAM_FAKE_VSSCANF_FILEDES (-2)
#define __STDIO_STREAM_FAKE_VSWPRINTF_FILEDES (-3)
#define __STDIO_STREAM_FAKE_VSWSCANF_FILEDES (-3)
@@ -315,9 +355,9 @@ extern int __stdio_trans2w_o(FILE *__restrict stream, int oflag) attribute_hidde
#else /* __STDIO_BUFFERS */
-#define __STDIO_STREAM_IS_FBF(S) (0)
-#define __STDIO_STREAM_IS_LBF(S) (0)
-#define __STDIO_STREAM_IS_NBF(S) (1)
+#define __STDIO_STREAM_IS_FBF(S) (0)
+#define __STDIO_STREAM_IS_LBF(S) (0)
+#define __STDIO_STREAM_IS_NBF(S) (1)
#define __STDIO_STREAM_BUFFER_SIZE(S) (0)
#define __STDIO_STREAM_BUFFER_ADD(S,C) ((void)0)
@@ -329,8 +369,8 @@ extern int __stdio_trans2w_o(FILE *__restrict stream, int oflag) attribute_hidde
#define __STDIO_STREAM_BUFFER_RAVAIL(S) (0)
#define __STDIO_STREAM_BUFFER_GET(S) (EOF)
-#define __STDIO_FILL_READ_BUFFER(S) (0)
-#define __STDIO_STREAM_INIT_BUFREAD_BUFPOS(S) ((void)0)
+#define __STDIO_FILL_READ_BUFFER(S) (0)
+#define __STDIO_STREAM_INIT_BUFREAD_BUFPOS(S) ((void)0)
#undef __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES
#undef __STDIO_STREAM_FAKE_VSSCANF_FILEDES
@@ -341,14 +381,14 @@ extern int __stdio_trans2w_o(FILE *__restrict stream, int oflag) attribute_hidde
#undef __STDIO_STREAM_IS_FAKE_VSWPRINTF
# ifdef __USE_OLD_VFPRINTF__
-# define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES_NB (-2)
-# define __STDIO_STREAM_IS_FAKE_VSNPRINTF_NB(S) \
+# define __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES_NB (-2)
+# define __STDIO_STREAM_IS_FAKE_VSNPRINTF_NB(S) \
((S)->__filedes == __STDIO_STREAM_FAKE_VSNPRINTF_FILEDES_NB)
# endif
# ifndef __UCLIBC_HAS_WCHAR__
-# define __STDIO_STREAM_FAKE_VSSCANF_FILEDES_NB (-2)
-# define __STDIO_STREAM_IS_FAKE_VSSCANF_NB(S) \
+# define __STDIO_STREAM_FAKE_VSSCANF_FILEDES_NB (-2)
+# define __STDIO_STREAM_IS_FAKE_VSSCANF_NB(S) \
((S)->__filedes == __STDIO_STREAM_FAKE_VSSCANF_FILEDES_NB)
# endif
@@ -359,7 +399,8 @@ extern int __stdio_adjust_position(FILE *__restrict stream, __offmax_t *pos) att
#ifdef __STDIO_HAS_OPENLIST
/* Uses an implementation hack!!! */
-#define __STDIO_FLUSH_LBF_STREAMS fflush_unlocked((FILE *) &_stdio_openlist)
+#define __STDIO_FLUSH_LBF_STREAMS \
+ fflush_unlocked((FILE *) &_stdio_openlist)
#else
#define __STDIO_FLUSH_LBF_STREAMS ((void)0)
#endif
@@ -382,13 +423,24 @@ extern void _stdio_validate_FILE(const FILE *stream);
/**********************************************************************/
-extern FILE *_stdio_fopen(intptr_t fname_or_mode,
- const char *__restrict mode,
- FILE *__restrict stream, int filedes) attribute_hidden;
+extern FILE *_stdio_fopen(intptr_t fname_or_mode, const char *__restrict mode,
+ FILE *__restrict stream, int filedes) attribute_hidden;
+
+#ifdef __UCLIBC_HAS_WCHAR__
+extern size_t _wstdio_fwrite(const wchar_t *__restrict ws,
+ size_t n, FILE *__restrict stream) attribute_hidden;
+#endif
+
+/**********************************************************************/
+
+extern int _vfprintf_internal (FILE * __restrict stream,
+ const char * __restrict format,
+ va_list arg) attribute_hidden;
#ifdef __UCLIBC_HAS_WCHAR__
-extern size_t _wstdio_fwrite(const wchar_t *__restrict ws, size_t n,
- FILE *__restrict stream) attribute_hidden;
+extern int _vfwprintf_internal (FILE * __restrict stream,
+ const wchar_t * __restrict format,
+ va_list arg) attribute_hidden;
#endif
/**********************************************************************/
diff --git a/libc/stdio/_store_inttype.c b/libc/stdio/_store_inttype.c
index 6eb74fe86..fdd4dce05 100644
--- a/libc/stdio/_store_inttype.c
+++ b/libc/stdio/_store_inttype.c
@@ -35,7 +35,7 @@ void _store_inttype(register void *dest, int desttype, uintmax_t val)
*((unsigned char *) dest) = val;
return;
}
-#if defined(LLONG_MAX) && (LONG_MAX != LLONG_MAX)
+#if defined(LLONG_MAX) && (INT_MAX != LLONG_MAX)
if (desttype == PA_FLAG_LONG_LONG) {
*((unsigned long long int *) dest) = val;
return;
diff --git a/libc/stdio/_uintmaxtostr.c b/libc/stdio/_uintmaxtostr.c
index 4310d6458..7a80371b8 100644
--- a/libc/stdio/_uintmaxtostr.c
+++ b/libc/stdio/_uintmaxtostr.c
@@ -11,7 +11,7 @@
#include <locale.h>
#include <bits/uClibc_uintmaxtostr.h>
-libc_hidden_proto(memcpy)
+/* Experimentally off - libc_hidden_proto(memcpy) */
/* Avoid using long long / and % operations to cut down dependencies on
* libgcc.a. Definitely helps on i386 at least. */
diff --git a/libc/stdio/_vfprintf.c b/libc/stdio/_vfprintf.c
index f4bbb1c1e..947b5b077 100644
--- a/libc/stdio/_vfprintf.c
+++ b/libc/stdio/_vfprintf.c
@@ -101,8 +101,6 @@
#include <stdint.h>
#include <errno.h>
#include <locale.h>
-
-#define __PRINTF_INFO_NO_BITFIELD
#include <printf.h>
#ifdef __UCLIBC_HAS_THREADS__
@@ -117,10 +115,10 @@
#include <bits/uClibc_uintmaxtostr.h>
#include <bits/uClibc_va_copy.h>
-libc_hidden_proto(memcpy)
-libc_hidden_proto(memset)
-libc_hidden_proto(strlen)
-libc_hidden_proto(strnlen)
+/* Experimentally off - libc_hidden_proto(memcpy) */
+/* Experimentally off - libc_hidden_proto(memset) */
+/* Experimentally off - libc_hidden_proto(strlen) */
+/* Experimentally off - libc_hidden_proto(strnlen) */
libc_hidden_proto(__glibc_strerror_r)
libc_hidden_proto(fputs_unlocked)
libc_hidden_proto(abort)
@@ -732,7 +730,7 @@ void attribute_hidden _ppfs_setargs(register ppfs_t *ppfs)
#ifdef __UCLIBC_HAS_XLOCALE__
libc_hidden_proto(__ctype_b_loc)
-#elif __UCLIBC_HAS_CTYPE_TABLES__
+#elif defined __UCLIBC_HAS_CTYPE_TABLES__
libc_hidden_proto(__ctype_b)
#endif
@@ -898,7 +896,7 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs)
) {
return -1;
}
- } while (buf[i++]);
+ } while (buf[i++] && (i < sizeof(buf)));
buf[sizeof(buf)-1] = 0;
}
#else /* __UCLIBC_HAS_WCHAR__ */
@@ -1198,7 +1196,7 @@ int register_printf_function(int spec, printf_function handler,
#endif
/**********************************************************************/
-#if defined(L_vfprintf) || defined(L_vfwprintf)
+#if defined(L__vfprintf_internal) || defined(L__vfwprintf_internal)
/* We only support ascii digits (or their USC equivalent codes) in
* precision and width settings in *printf (wide) format strings.
@@ -1207,14 +1205,15 @@ int register_printf_function(int spec, printf_function handler,
static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad);
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
-#define VFPRINTF vfprintf
+#define VFPRINTF_internal _vfprintf_internal
#define FMT_TYPE char
#define OUTNSTR _outnstr
#define STRLEN strlen
#define _PPFS_init _ppfs_init
-#define OUTPUT(F,S) fputs_unlocked(S,F)
+/* Pulls in fseek: #define OUTPUT(F,S) fputs_unlocked(S,F) */
+#define OUTPUT(F,S) __stdio_fwrite((const unsigned char *)(S),strlen(S),(F))
/* #define _outnstr(stream, string, len) __stdio_fwrite(string, len, stream) */
#define _outnstr(stream, string, len) ((len > 0) ? __stdio_fwrite(string, len, stream) : 0)
#define FP_OUT _fp_out_narrow
@@ -1234,19 +1233,21 @@ static size_t _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf
}
len = buflen;
}
- return r + OUTNSTR(fp, (const char *) buf, len);
+ return r + OUTNSTR(fp, (const unsigned char *) buf, len);
}
#endif /* __STDIO_PRINTF_FLOAT */
-#else /* L_vfprintf */
+#else /* L__vfprintf_internal */
-#define VFPRINTF vfwprintf
+#define VFPRINTF_internal _vfwprintf_internal
#define FMT_TYPE wchar_t
#define OUTNSTR _outnwcs
#define STRLEN wcslen
#define _PPFS_init _ppwfs_init
+/* Pulls in fseek: */
#define OUTPUT(F,S) fputws(S,F)
+/* TODO: #define OUTPUT(F,S) _wstdio_fwrite((S),wcslen(S),(F)) */
#define _outnwcs(stream, wstring, len) _wstdio_fwrite(wstring, len, stream)
#define FP_OUT _fp_out_wide
@@ -1417,7 +1418,8 @@ static int _ppwfs_init(register ppfs_t *ppfs, const wchar_t *fmt0)
return 0;
}
-#endif /* L_vfprintf */
+#endif /* L__vfprintf_internal */
+
static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad)
{
@@ -1427,7 +1429,7 @@ static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad)
FMT_TYPE pad[1];
*pad = padchar;
- while (todo && (OUTNSTR(stream, pad, 1) == 1)) {
+ while (todo && (OUTNSTR(stream, (const unsigned char *) pad, 1) == 1)) {
--todo;
}
@@ -1439,12 +1441,12 @@ static int _do_one_spec(FILE * __restrict stream,
register ppfs_t *ppfs, int *count)
{
static const char spec_base[] = SPEC_BASE;
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
static const char prefix[] = "+\0-\0 \0000x\0000X";
/* 0 2 4 6 9 11*/
-#else /* L_vfprintf */
+#else /* L__vfprintf_internal */
static const wchar_t prefix[] = L"+\0-\0 \0000x\0000X";
-#endif /* L_vfprintf */
+#endif /* L__vfprintf_internal */
enum {
PREFIX_PLUS = 0,
PREFIX_MINUS = 2,
@@ -1465,7 +1467,7 @@ static int _do_one_spec(FILE * __restrict stream,
mbstate_t mbstate;
#endif /* __UCLIBC_HAS_WCHAR__ */
size_t slen;
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
#define SLEN slen
#else
size_t SLEN;
@@ -1532,7 +1534,7 @@ static int _do_one_spec(FILE * __restrict stream,
alphacase = __UIM_LOWER;
#ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
#warning CONSIDER: Should we ignore these flags if stub locale? What about custom specs?
#endif
#endif /* __UCLIBC_MJN3_ONLY__ */
@@ -1560,13 +1562,13 @@ static int _do_one_spec(FILE * __restrict stream,
padchar = ppfs->info.pad;
}
#ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
#warning CONSIDER: If using outdigits and/or grouping, how should we interpret precision?
#endif
#endif /* __UCLIBC_MJN3_ONLY__ */
s = _uintmaxtostr(buf + sizeof(buf) - 1,
(uintmax_t)
- _load_inttype(*argtype & __PA_INTMASK,
+ _load_inttype(ppfs->conv_num == CONV_p ? PA_FLAG_LONG : *argtype & __PA_INTMASK,
*argptr, base), base, alphacase);
if (ppfs->conv_num > CONV_u) { /* signed int */
if (*s == '-') {
@@ -1580,7 +1582,7 @@ static int _do_one_spec(FILE * __restrict stream,
}
}
slen = (char *)(buf + sizeof(buf) - 1) - s;
-#ifdef L_vfwprintf
+#ifdef L__vfwprintf_internal
{
const char *q = s;
mbstate.__mask = 0; /* Initialize the mbstate. */
@@ -1605,13 +1607,13 @@ static int _do_one_spec(FILE * __restrict stream,
}
if (ppfs->conv_num == CONV_p) {/* null pointer */
s = "(nil)";
-#ifdef L_vfwprintf
+#ifdef L__vfwprintf_internal
SLEN =
#endif
slen = 5;
numfill = 0;
} else if (numfill == 0) { /* if precision 0, no output */
-#ifdef L_vfwprintf
+#ifdef L__vfwprintf_internal
SLEN =
#endif
slen = 0;
@@ -1637,7 +1639,7 @@ static int _do_one_spec(FILE * __restrict stream,
return -1; /* TODO -- try to continue? */
#endif /* __STDIO_PRINTF_FLOAT */
} else if (ppfs->conv_num <= CONV_S) { /* wide char or string */
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
#ifdef __UCLIBC_HAS_WCHAR__
mbstate.__mask = 0; /* Initialize the mbstate. */
@@ -1692,7 +1694,7 @@ static int _do_one_spec(FILE * __restrict stream,
slen = 1;
}
-#else /* L_vfprintf */
+#else /* L__vfprintf_internal */
if (ppfs->conv_num == CONV_S) { /* wide string */
ws = *((wchar_t **) (*argptr));
@@ -1713,7 +1715,7 @@ static int _do_one_spec(FILE * __restrict stream,
if (ppfs->conv_num == CONV_s) { /* string */
#ifdef __UCLIBC_MJN3_ONLY__
-#warning TODO: Fix %s for vfwprintf... output upto illegal sequence?
+#warning TODO: Fix %s for _vfwprintf_internal... output upto illegal sequence?
#endif /* __UCLIBC_MJN3_ONLY__ */
s = *((char **) (*argptr));
if (s) {
@@ -1746,7 +1748,7 @@ static int _do_one_spec(FILE * __restrict stream,
goto CHAR_CASE;
}
-#endif /* L_vfprintf */
+#endif /* L__vfprintf_internal */
#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
} else if (ppfs->conv_num == CONV_m) {
@@ -1778,7 +1780,7 @@ static int _do_one_spec(FILE * __restrict stream,
}
#ifdef __UCLIBC_MJN3_ONLY__
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
#warning CONSIDER: If using outdigits and/or grouping, how should we pad?
#endif
#endif /* __UCLIBC_MJN3_ONLY__ */
@@ -1805,11 +1807,12 @@ static int _do_one_spec(FILE * __restrict stream,
numpad = 0;
}
OUTPUT(stream, prefix + prefix_num);
+
if (_charpad(stream, '0', numfill) != numfill) {
return -1;
}
-#ifdef L_vfprintf
+#ifdef L__vfprintf_internal
#ifdef __UCLIBC_HAS_WCHAR__
if (!ws) {
@@ -1831,12 +1834,12 @@ static int _do_one_spec(FILE * __restrict stream,
}
}
#else /* __UCLIBC_HAS_WCHAR__ */
- if (_outnstr(stream, s, slen) != slen) {
+ if (_outnstr(stream, (const unsigned char *) s, slen) != slen) {
return -1;
}
#endif /* __UCLIBC_HAS_WCHAR__ */
-#else /* L_vfprintf */
+#else /* L__vfprintf_internal */
if (!ws) {
assert(s);
@@ -1849,7 +1852,7 @@ static int _do_one_spec(FILE * __restrict stream,
}
}
-#endif /* L_vfprintf */
+#endif /* L__vfprintf_internal */
if (_charpad(stream, ' ', numpad) != numpad) {
return -1;
}
@@ -1860,35 +1863,21 @@ static int _do_one_spec(FILE * __restrict stream,
libc_hidden_proto(fprintf)
-libc_hidden_proto(VFPRINTF)
-int VFPRINTF (FILE * __restrict stream,
- register const FMT_TYPE * __restrict format,
+int VFPRINTF_internal (FILE * __restrict stream,
+ const FMT_TYPE * __restrict format,
va_list arg)
{
ppfs_t ppfs;
int count, r;
register const FMT_TYPE *s;
- __STDIO_AUTO_THREADLOCK_VAR;
-
- __STDIO_AUTO_THREADLOCK(stream);
count = 0;
s = format;
- if
-#ifdef L_vfprintf
- (!__STDIO_STREAM_IS_NARROW_WRITING(stream)
- && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_NARROW))
-#else
- (!__STDIO_STREAM_IS_WIDE_WRITING(stream)
- && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_WIDE))
-#endif
- {
- count = -1;
- } else if (_PPFS_init(&ppfs, format) < 0) { /* Bad format string. */
- OUTNSTR(stream, (const FMT_TYPE *) ppfs.fmtpos,
+ if (_PPFS_init(&ppfs, format) < 0) { /* Bad format string. */
+ OUTNSTR(stream, (const unsigned char *) ppfs.fmtpos,
STRLEN((const FMT_TYPE *)(ppfs.fmtpos)));
-#if defined(L_vfprintf) && !defined(NDEBUG)
+#if defined(L__vfprintf_internal) && !defined(NDEBUG)
fprintf(stderr,"\nIMbS: \"%s\"\n\n", format);
#endif
count = -1;
@@ -1901,7 +1890,7 @@ int VFPRINTF (FILE * __restrict stream,
}
if (format-s) { /* output any literal text in format string */
- if ( (r = OUTNSTR(stream, s, format-s)) != (format-s)) {
+ if ( (r = OUTNSTR(stream, (const unsigned char *) s, format-s)) != (format-s)) {
count = -1;
break;
}
@@ -1930,14 +1919,66 @@ int VFPRINTF (FILE * __restrict stream,
va_end(ppfs.arg); /* Need to clean up after va_copy! */
}
-/* #if defined(L_vfprintf) && defined(__UCLIBC_HAS_WCHAR__) */
+/* #if defined(L__vfprintf_internal) && defined(__UCLIBC_HAS_WCHAR__) */
/* DONE: */
/* #endif */
+ return count;
+}
+#endif /* defined(L__vfprintf_internal) || defined(L__vfwprintf_internal) */
+
+
+/**********************************************************************/
+#if defined(L_vfprintf) || defined(L_vfwprintf)
+
+/* This is just a wrapper around VFPRINTF_internal.
+ * Factoring out vfprintf internals allows:
+ * (1) vdprintf and vsnprintf don't need to setup fake locking,
+ * (2) __STDIO_STREAM_TRANS_TO_WRITE is not used in vfprintf internals,
+ * and thus fseek etc is not pulled in by vdprintf and vsnprintf.
+ *
+ * In order to not pull in fseek through fputs, OUTPUT() macro
+ * is using __stdio_fwrite (TODO: do the same for wide functions).
+ */
+#ifdef L_vfprintf
+#define VFPRINTF vfprintf
+#define VFPRINTF_internal _vfprintf_internal
+#define FMT_TYPE char
+#else
+#define VFPRINTF vfwprintf
+#define VFPRINTF_internal _vfwprintf_internal
+#define FMT_TYPE wchar_t
+#endif
+
+libc_hidden_proto(VFPRINTF)
+int VFPRINTF (FILE * __restrict stream,
+ const FMT_TYPE * __restrict format,
+ va_list arg)
+{
+ int count;
+ __STDIO_AUTO_THREADLOCK_VAR;
+
+ __STDIO_AUTO_THREADLOCK(stream);
+
+ if
+#ifdef L_vfprintf
+ (!__STDIO_STREAM_IS_NARROW_WRITING(stream)
+ && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_NARROW))
+#else
+ (!__STDIO_STREAM_IS_WIDE_WRITING(stream)
+ && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_WIDE))
+#endif
+ {
+ count = -1;
+ } else {
+ count = VFPRINTF_internal(stream, format, arg);
+ }
+
__STDIO_AUTO_THREADUNLOCK(stream);
return count;
}
libc_hidden_def(VFPRINTF)
-#endif
+#endif /* defined(L_vfprintf) || defined(L_vfwprintf) */
+
/**********************************************************************/
diff --git a/libc/stdio/ctermid.c b/libc/stdio/ctermid.c
index 1cb8a0845..26369d6f5 100644
--- a/libc/stdio/ctermid.c
+++ b/libc/stdio/ctermid.c
@@ -7,7 +7,7 @@
#include "_stdio.h"
-libc_hidden_proto(strcpy)
+/* Experimentally off - libc_hidden_proto(strcpy) */
char *ctermid(register char *s)
{
diff --git a/libc/stdio/fclose.c b/libc/stdio/fclose.c
index 843599c0f..27d3c7e96 100644
--- a/libc/stdio/fclose.c
+++ b/libc/stdio/fclose.c
@@ -16,12 +16,15 @@ int fclose(register FILE *stream)
int rv = 0;
__STDIO_AUTO_THREADLOCK_VAR;
- /* First, remove the file from the open file list. */
#ifdef __STDIO_HAS_OPENLIST
+#if !defined(__UCLIBC_HAS_THREADS__) || !defined(__STDIO_BUFFERS)
+ /* First, remove the file from the open file list. */
{
- register FILE *ptr;
+ FILE *ptr;
- __STDIO_THREADLOCK_OPENLIST;
+ __STDIO_THREADLOCK_OPENLIST_DEL;
+ __STDIO_THREADLOCK_OPENLIST_ADD;
+ ptr = _stdio_openlist;
if ((ptr = _stdio_openlist) == stream) {
_stdio_openlist = stream->__nextopen;
} else {
@@ -33,13 +36,11 @@ int fclose(register FILE *stream)
ptr = ptr->__nextopen;
}
}
- __STDIO_THREADUNLOCK_OPENLIST;
-
- if (!ptr) { /* Did not find stream in the open file list! */
- return EOF;
- }
+ __STDIO_THREADUNLOCK_OPENLIST_ADD;
+ __STDIO_THREADUNLOCK_OPENLIST_DEL;
}
#endif
+#endif
__STDIO_AUTO_THREADLOCK(stream);
@@ -62,6 +63,11 @@ int fclose(register FILE *stream)
* Since a file can't be both readonly and writeonly, that makes
* an effective signal. It also has the benefit of disabling
* transitions to either reading or writing. */
+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
+ /* Before we mark the file as closed, make sure we increment the openlist use count
+ * so it isn't freed under us while still cleaning up. */
+ __STDIO_OPENLIST_INC_USE;
+#endif
stream->__modeflags &= (__FLAG_FREEBUF|__FLAG_FREEFILE);
stream->__modeflags |= (__FLAG_READONLY|__FLAG_WRITEONLY);
@@ -84,7 +90,16 @@ int fclose(register FILE *stream)
__STDIO_AUTO_THREADUNLOCK(stream);
__STDIO_STREAM_FREE_BUFFER(stream);
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning REMINDER: inefficient - locks and unlocks twice and walks whole list
+#endif
+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
+ /* inefficient - locks/unlocks twice and walks whole list */
+ __STDIO_OPENLIST_INC_DEL_CNT;
+ __STDIO_OPENLIST_DEC_USE; /* This with free the file if necessary. */
+#else
__STDIO_STREAM_FREE_FILE(stream);
+#endif
return rv;
}
diff --git a/libc/stdio/fcloseall.c b/libc/stdio/fcloseall.c
index 7d2422562..d3cbb67f8 100644
--- a/libc/stdio/fcloseall.c
+++ b/libc/stdio/fcloseall.c
@@ -24,14 +24,39 @@ int fcloseall (void)
#ifdef __STDIO_HAS_OPENLIST
int retval = 0;
+ FILE *f;
- __STDIO_THREADLOCK_OPENLIST;
- while (_stdio_openlist) {
- if (fclose(_stdio_openlist)) {
- retval = EOF;
+ __STDIO_OPENLIST_INC_USE;
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning REMINDER: should probably have a get_head() operation
+#endif
+ __STDIO_THREADLOCK_OPENLIST_ADD;
+ f = _stdio_openlist;
+ __STDIO_THREADUNLOCK_OPENLIST_ADD;
+
+ while (f) {
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning REMINDER: should probably have a get_next() operation
+#endif
+ FILE *n = f->__nextopen;
+ __STDIO_AUTO_THREADLOCK_VAR;
+
+ __STDIO_AUTO_THREADLOCK(f);
+ /* Only call fclose on the stream if it is not already closed. */
+ if ((f->__modeflags & (__FLAG_READONLY|__FLAG_WRITEONLY))
+ != (__FLAG_READONLY|__FLAG_WRITEONLY)
+ ) {
+ if (fclose(f)) {
+ retval = EOF;
+ }
}
+ __STDIO_AUTO_THREADUNLOCK(f);
+
+ f = n;
}
- __STDIO_THREADUNLOCK_OPENLIST;
+
+ __STDIO_OPENLIST_DEC_USE;
return retval;
diff --git a/libc/stdio/fflush.c b/libc/stdio/fflush.c
index c0f58d8af..11b837dde 100644
--- a/libc/stdio/fflush.c
+++ b/libc/stdio/fflush.c
@@ -15,24 +15,57 @@ libc_hidden_proto(fflush_unlocked)
#warning WISHLIST: Add option to test for undefined behavior of fflush.
#endif /* __UCLIBC_MJN3_ONLY__ */
-#ifdef __UCLIBC_HAS_THREADS__
/* Even if the stream is set to user-locking, we still need to lock
* when all (lbf) writing streams are flushed. */
-#define MY_STDIO_THREADLOCK(STREAM) \
- if (_stdio_user_locking != 2) { \
- __STDIO_ALWAYS_THREADLOCK(STREAM); \
- }
-#define MY_STDIO_THREADUNLOCK(STREAM) \
- if (_stdio_user_locking != 2) { \
- __STDIO_ALWAYS_THREADUNLOCK(STREAM); \
+#define __MY_STDIO_THREADLOCK(__stream) \
+ __UCLIBC_IO_MUTEX_CONDITIONAL_LOCK((__stream)->__lock, \
+ (_stdio_user_locking != 2))
+
+#define __MY_STDIO_THREADUNLOCK(__stream) \
+ __UCLIBC_IO_MUTEX_CONDITIONAL_UNLOCK((__stream)->__lock, \
+ (_stdio_user_locking != 2))
+
+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
+void _stdio_openlist_dec_use(void)
+{
+ __STDIO_THREADLOCK_OPENLIST_DEL;
+ if ((_stdio_openlist_use_count == 1) && (_stdio_openlist_del_count > 0)) {
+ FILE *p = NULL;
+ FILE *n;
+ FILE *stream;
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning REMINDER: As an optimization, we could unlock after we move past the head.
+#endif
+ /* Grab the openlist add lock since we might change the head of the list. */
+ __STDIO_THREADLOCK_OPENLIST_ADD;
+ for (stream = _stdio_openlist; stream; stream = n) {
+ n = stream->__nextopen;
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning REMINDER: fix for nonatomic
+#endif
+ if ((stream->__modeflags & (__FLAG_READONLY|__FLAG_WRITEONLY|__FLAG_FAILED_FREOPEN))
+ == (__FLAG_READONLY|__FLAG_WRITEONLY)
+ ) { /* The file was closed and should be removed from the list. */
+ if (!p) {
+ _stdio_openlist = n;
+ } else {
+ p->__nextopen = n;
+ }
+ __STDIO_STREAM_FREE_FILE(stream);
+ } else {
+ p = stream;
+ }
+ }
+ __STDIO_THREADUNLOCK_OPENLIST_ADD;
+ _stdio_openlist_del_count = 0; /* Should be clean now. */
}
-#else
-#define MY_STDIO_THREADLOCK(STREAM) ((void)0)
-#define MY_STDIO_THREADUNLOCK(STREAM) ((void)0)
+ --_stdio_openlist_use_count;
+ __STDIO_THREADUNLOCK_OPENLIST_DEL;
+}
#endif
-
int fflush_unlocked(register FILE *stream)
{
#ifdef __STDIO_BUFFERS
@@ -55,23 +88,39 @@ int fflush_unlocked(register FILE *stream)
}
if (!stream) { /* Flush all (lbf) writing streams. */
- __STDIO_THREADLOCK_OPENLIST;
- for (stream = _stdio_openlist; stream ; stream = stream->__nextopen) {
- MY_STDIO_THREADLOCK(stream);
- if (!(((stream->__modeflags | bufmask)
- ^ (__FLAG_WRITING|__FLAG_LBF)
- ) & (__FLAG_WRITING|__MASK_BUFMODE))
- ) {
- if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) {
- __STDIO_STREAM_DISABLE_PUTC(stream);
- __STDIO_STREAM_CLEAR_WRITING(stream);
- } else {
- retval = EOF;
+
+ __STDIO_OPENLIST_INC_USE;
+
+ __STDIO_THREADLOCK_OPENLIST_ADD;
+ stream = _stdio_openlist;
+ __STDIO_THREADUNLOCK_OPENLIST_ADD;
+
+ while(stream) {
+ /* We only care about currently writing streams and do not want to
+ * block trying to obtain mutexes on non-writing streams. */
+#warning fix for nonatomic
+#warning unnecessary check if no threads
+ if (__STDIO_STREAM_IS_WRITING(stream)) { /* ONLY IF ATOMIC!!! */
+ __MY_STDIO_THREADLOCK(stream);
+ /* Need to check again once we have the lock. */
+ if (!(((stream->__modeflags | bufmask)
+ ^ (__FLAG_WRITING|__FLAG_LBF)
+ ) & (__FLAG_WRITING|__MASK_BUFMODE))
+ ) {
+ if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) {
+ __STDIO_STREAM_DISABLE_PUTC(stream);
+ __STDIO_STREAM_CLEAR_WRITING(stream);
+ } else {
+ retval = EOF;
+ }
}
+ __MY_STDIO_THREADUNLOCK(stream);
}
- MY_STDIO_THREADUNLOCK(stream);
+ stream = stream->__nextopen;
}
- __STDIO_THREADUNLOCK_OPENLIST;
+
+ __STDIO_OPENLIST_DEC_USE;
+
} else if (__STDIO_STREAM_IS_WRITING(stream)) {
if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) {
__STDIO_STREAM_DISABLE_PUTC(stream);
diff --git a/libc/stdio/flockfile.c b/libc/stdio/flockfile.c
index 0dcc7c266..3fad7118d 100644
--- a/libc/stdio/flockfile.c
+++ b/libc/stdio/flockfile.c
@@ -11,6 +11,6 @@ void flockfile(FILE *stream)
{
__STDIO_STREAM_VALIDATE(stream);
- __STDIO_ALWAYS_THREADLOCK(stream);
+ __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(stream);
}
diff --git a/libc/stdio/fmemopen.c b/libc/stdio/fmemopen.c
index a78d56efc..eb4fa736e 100644
--- a/libc/stdio/fmemopen.c
+++ b/libc/stdio/fmemopen.c
@@ -10,7 +10,7 @@
#ifdef __USE_GNU
#include "_stdio.h"
-libc_hidden_proto(memcpy)
+/* Experimentally off - libc_hidden_proto(memcpy) */
libc_hidden_proto(fopencookie)
#ifndef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
diff --git a/libc/stdio/fputc.c b/libc/stdio/fputc.c
index 8c80bff27..ac3b23ec5 100644
--- a/libc/stdio/fputc.c
+++ b/libc/stdio/fputc.c
@@ -72,13 +72,19 @@ int __fputc_unlocked(int c, register FILE *stream)
}
libc_hidden_def(__fputc_unlocked)
+/* exposing these would be fundamentally *wrong*! fix you, instead! */
+/* libc_hidden_proto(fputc_unlocked) */
strong_alias(__fputc_unlocked,fputc_unlocked)
+/* exposing these would be fundamentally *wrong*! fix you, instead! */
+/* libc_hidden_def(fputc_unlocked) */
libc_hidden_proto(putc_unlocked)
strong_alias(__fputc_unlocked,putc_unlocked)
libc_hidden_def(putc_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
+libc_hidden_proto(fputc)
strong_alias(__fputc_unlocked,fputc)
+libc_hidden_def(fputc)
libc_hidden_proto(putc)
strong_alias(__fputc_unlocked,putc)
diff --git a/libc/stdio/fputs.c b/libc/stdio/fputs.c
index 4111491d6..8a5fd4087 100644
--- a/libc/stdio/fputs.c
+++ b/libc/stdio/fputs.c
@@ -9,7 +9,7 @@
libc_hidden_proto(fputs_unlocked)
-libc_hidden_proto(strlen)
+/* Experimentally off - libc_hidden_proto(strlen) */
libc_hidden_proto(fwrite_unlocked)
/* Note: The standard says fputs returns a nonnegative number on
diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c
index c603a9d2e..d8b04f733 100644
--- a/libc/stdio/fread.c
+++ b/libc/stdio/fread.c
@@ -11,7 +11,7 @@ libc_hidden_proto(fread_unlocked)
#ifdef __DO_UNLOCKED
-libc_hidden_proto(memcpy)
+/* Experimentally off - libc_hidden_proto(memcpy) */
libc_hidden_proto(fflush_unlocked)
size_t fread_unlocked(void * __restrict ptr, size_t size, size_t nmemb,
diff --git a/libc/stdio/freopen.c b/libc/stdio/freopen.c
index 7314807d3..942a67991 100644
--- a/libc/stdio/freopen.c
+++ b/libc/stdio/freopen.c
@@ -37,6 +37,8 @@ FILE *freopen(const char * __restrict filename, const char * __restrict mode,
__STDIO_STREAM_VALIDATE(stream);
+ __STDIO_OPENLIST_INC_USE; /* Do not remove the file from the list. */
+
/* First, flush and close, but don't deallocate, the stream. */
/* This also removes the stream for the open file list. */
dynmode = (stream->__modeflags & (__FLAG_FREEBUF|__FLAG_FREEFILE));
@@ -48,13 +50,26 @@ FILE *freopen(const char * __restrict filename, const char * __restrict mode,
!= (__FLAG_READONLY|__FLAG_WRITEONLY)
) {
fclose(stream); /* Failures are ignored. */
+ /* NOTE: fclose always does __STDIO_OPENLIST_INC_DEL_CNT. But we don't
+ * want to remove this FILE from the open list, even if the freopen fails.
+ * Consider the case of a failed freopen() on stdin. You probably still
+ * want to be able to call freopen() again. Similarly for other "malloc'd"
+ * streams. */
+ __STDIO_OPENLIST_DEC_DEL_CNT;
}
fp = _stdio_fopen(((intptr_t) filename), mode, stream, FILEDES_ARG);
+ if (!fp) {
+ /* Don't remove stream from the open file list and (potentially) free it.
+ * See _stdio_openlist_dec_use() in fflush.c. */
+ stream->__modeflags = __FLAG_READONLY|__FLAG_WRITEONLY|__FLAG_FAILED_FREOPEN;
+ }
/* Reset the allocation flags. */
stream->__modeflags |= dynmode;
+ __STDIO_OPENLIST_DEC_USE;
+
__STDIO_AUTO_THREADUNLOCK(stream);
return fp;
diff --git a/libc/stdio/ftello.c b/libc/stdio/ftello.c
index 4445471a4..bae1d877c 100644
--- a/libc/stdio/ftello.c
+++ b/libc/stdio/ftello.c
@@ -39,7 +39,10 @@ OFFSET_TYPE FTELL(register FILE *stream)
__STDIO_STREAM_VALIDATE(stream);
- if ((__SEEK(stream, &pos, SEEK_CUR) < 0)
+ if ((__SEEK(stream, &pos,
+ ((__STDIO_STREAM_IS_WRITING(stream)
+ && (stream->__modeflags & __FLAG_APPEND))
+ ? SEEK_END : SEEK_CUR)) < 0)
|| (__stdio_adjust_position(stream, &pos) < 0)) {
pos = -1;
}
diff --git a/libc/stdio/ftrylockfile.c b/libc/stdio/ftrylockfile.c
index d85b8ff59..0d2e156af 100644
--- a/libc/stdio/ftrylockfile.c
+++ b/libc/stdio/ftrylockfile.c
@@ -15,5 +15,5 @@ int ftrylockfile(FILE *stream)
{
__STDIO_STREAM_VALIDATE(stream);
- return __STDIO_ALWAYS_THREADTRYLOCK(stream);
+ return __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(stream);
}
diff --git a/libc/stdio/funlockfile.c b/libc/stdio/funlockfile.c
index 048c093d5..2ddf09797 100644
--- a/libc/stdio/funlockfile.c
+++ b/libc/stdio/funlockfile.c
@@ -11,5 +11,5 @@ void funlockfile(FILE *stream)
{
__STDIO_STREAM_VALIDATE(stream);
- __STDIO_ALWAYS_THREADUNLOCK(stream);
+ __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(stream);
}
diff --git a/libc/stdio/getchar.c b/libc/stdio/getchar.c
index 6da8307b6..e29c426c8 100644
--- a/libc/stdio/getchar.c
+++ b/libc/stdio/getchar.c
@@ -12,13 +12,16 @@ libc_hidden_proto(__fgetc_unlocked)
#undef getchar
#ifdef __DO_UNLOCKED
+/* the only use of the hidden getchar_unlocked is in gets.c */
#undef getchar_unlocked
+libc_hidden_proto(getchar_unlocked)
int getchar_unlocked(void)
{
register FILE *stream = stdin;
return __GETC_UNLOCKED_MACRO(stream);
}
+libc_hidden_def(getchar_unlocked)
#ifndef __UCLIBC_HAS_THREADS__
strong_alias(getchar_unlocked,getchar)
diff --git a/libc/stdio/gets.c b/libc/stdio/gets.c
index dc541339b..85bb8475a 100644
--- a/libc/stdio/gets.c
+++ b/libc/stdio/gets.c
@@ -11,11 +11,9 @@ link_warning(gets, "the 'gets' function is dangerous and should not be used.")
/* UNSAFE FUNCTION -- do not bother optimizing */
+/* disable macro, force actual function call */
+#undef getchar_unlocked
libc_hidden_proto(getchar_unlocked)
-libc_hidden_proto(__fgetc_unlocked)
-#ifndef __STDIO_GETC_MACRO
-#define __stdin stdin
-#endif
char *gets(char *s)
{
diff --git a/libc/stdio/old_vfprintf.c b/libc/stdio/old_vfprintf.c
index f81ef8688..85a0967c1 100644
--- a/libc/stdio/old_vfprintf.c
+++ b/libc/stdio/old_vfprintf.c
@@ -137,17 +137,15 @@
#include <errno.h>
#include <ctype.h>
#include <bits/uClibc_uintmaxtostr.h>
-
-#define __PRINTF_INFO_NO_BITFIELD
#include <printf.h>
#ifdef __UCLIBC_HAS_THREADS__
#include <pthread.h>
#endif /* __UCLIBC_HAS_THREADS__ */
-libc_hidden_proto(strlen)
-libc_hidden_proto(strnlen)
-libc_hidden_proto(memcpy)
+/* Experimentally off - libc_hidden_proto(strlen) */
+/* Experimentally off - libc_hidden_proto(strnlen) */
+/* Experimentally off - libc_hidden_proto(memcpy) */
libc_hidden_proto(putc_unlocked)
libc_hidden_proto(__fputc_unlocked)
libc_hidden_proto(__glibc_strerror_r)
@@ -359,13 +357,13 @@ int vfprintf(FILE * __restrict op, register const char * __restrict fmt,
int i;
} intarg;
int i, cnt, dataargtype, len;
- const void *argptr; /* This does not need to be initialized. */
+ const void *argptr = argptr; /* ok to be initialized. */
register char *p;
const char *fmt0;
int preci, width;
#define upcase i
int radix, dpoint /*, upcase*/;
- char tmp[65]; /* TODO - determing needed size from headers */
+ char tmp[65]; /* TODO - determine needed size from headers */
char flag[sizeof(spec)];
__STDIO_AUTO_THREADLOCK_VAR;
diff --git a/libc/stdio/open_memstream.c b/libc/stdio/open_memstream.c
index 25c2f9f61..a9327608a 100644
--- a/libc/stdio/open_memstream.c
+++ b/libc/stdio/open_memstream.c
@@ -10,8 +10,8 @@
#ifdef __USE_GNU
#include "_stdio.h"
-libc_hidden_proto(memcpy)
-libc_hidden_proto(memset)
+/* Experimentally off - libc_hidden_proto(memcpy) */
+/* Experimentally off - libc_hidden_proto(memset) */
libc_hidden_proto(fopencookie)
#ifndef __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__
@@ -160,9 +160,7 @@ FILE *open_memstream(char **__restrict bufloc, size_t *__restrict sizeloc)
}
}
- if (cookie->buf != NULL) {
- free(cookie->buf);
- }
+ free(cookie->buf);
EXIT_cookie:
free(cookie);
diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c
index 044426abf..43d07fa0f 100644
--- a/libc/stdio/popen.c
+++ b/libc/stdio/popen.c
@@ -20,6 +20,11 @@
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
+#include <bits/uClibc_mutex.h>
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning "hmm... susv3 says Pipe streams are byte-oriented."
+#endif /* __UCLIBC_MJN3_ONLY__ */
libc_hidden_proto(close)
libc_hidden_proto(_exit)
@@ -34,23 +39,16 @@ libc_hidden_proto(fclose)
/* uClinux-2.0 has vfork, but Linux 2.0 doesn't */
#include <sys/syscall.h>
#if ! defined __NR_vfork
-# define vfork fork
+# define vfork fork
# define VFORK_LOCK ((void) 0)
-# define VFORK_UNLOCK ((void) 0)
+# define VFORK_UNLOCK ((void) 0)
libc_hidden_proto(fork)
#endif
-#ifdef __UCLIBC_HAS_THREADS__
-# include <pthread.h>
-# include <pthreadP.h>
-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
-#endif
-#define LOCK __pthread_mutex_lock(&mylock)
-#define UNLOCK __pthread_mutex_unlock(&mylock)
-
#ifndef VFORK_LOCK
-# define VFORK_LOCK LOCK
-# define VFORK_UNLOCK UNLOCK
+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+# define VFORK_LOCK __UCLIBC_MUTEX_LOCK(mylock)
+# define VFORK_UNLOCK __UCLIBC_MUTEX_UNLOCK(mylock)
#endif
struct popen_list_item {
@@ -127,11 +125,11 @@ FILE *popen(const char *command, const char *modes)
if (pid > 0) { /* Parent of vfork... */
pi->pid = pid;
pi->f = fp;
- LOCK;
+ VFORK_LOCK;
pi->next = popen_list;
popen_list = pi;
- UNLOCK;
-
+ VFORK_UNLOCK;
+
return fp;
}
@@ -145,6 +143,8 @@ FILE *popen(const char *command, const char *modes)
return NULL;
}
+#warning is pclose correct wrt the new mutex semantics?
+
int pclose(FILE *stream)
{
struct popen_list_item *p;
@@ -153,7 +153,7 @@ int pclose(FILE *stream)
/* First, find the list entry corresponding to stream and remove it
* from the list. Set p to the list item (NULL if not found). */
- LOCK;
+ VFORK_LOCK;
if ((p = popen_list) != NULL) {
if (p->f == stream) {
popen_list = p->next;
@@ -172,7 +172,7 @@ int pclose(FILE *stream)
} while (1);
}
}
- UNLOCK;
+ VFORK_UNLOCK;
if (p) {
pid = p->pid; /* Save the pid we need */
diff --git a/libc/stdio/setvbuf.c b/libc/stdio/setvbuf.c
index c1566504a..6dbb532db 100644
--- a/libc/stdio/setvbuf.c
+++ b/libc/stdio/setvbuf.c
@@ -76,8 +76,8 @@ int setvbuf(register FILE * __restrict stream, register char * __restrict buf,
}
stream->__modeflags |= alloc_flag;
- stream->__bufstart = buf;
- stream->__bufend = buf + size;
+ 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);
diff --git a/libc/stdio/tempnam.c b/libc/stdio/tempnam.c
index 43cbf781b..3673f4bda 100644
--- a/libc/stdio/tempnam.c
+++ b/libc/stdio/tempnam.c
@@ -20,7 +20,7 @@
#include <string.h>
#include "../misc/internals/tempname.h"
-libc_hidden_proto(strdup)
+/* Experimentally off - libc_hidden_proto(strdup) */
/* Generate a unique temporary filename using up to five characters of PFX
if it is not NULL. The directory to put this file in is searched for
diff --git a/libc/stdio/tmpnam.c b/libc/stdio/tmpnam.c
index bc4ffeb6a..8df6ff57f 100644
--- a/libc/stdio/tmpnam.c
+++ b/libc/stdio/tmpnam.c
@@ -20,7 +20,7 @@
#include <string.h>
#include "../misc/internals/tempname.h"
-libc_hidden_proto(memcpy)
+/* Experimentally off - libc_hidden_proto(memcpy) */
static char tmpnam_buffer[L_tmpnam];
diff --git a/libc/stdio/vasprintf.c b/libc/stdio/vasprintf.c
index 7a34f6870..b7e2e0852 100644
--- a/libc/stdio/vasprintf.c
+++ b/libc/stdio/vasprintf.c
@@ -57,7 +57,7 @@ int vasprintf(char **__restrict buf, const char * __restrict format,
#else /* __UCLIBC_HAS_GLIBC_CUSTOM_STREAMS__ */
- /* This implementation actually calls the printf machinery twice, but only
+ /* This implementation actually calls the printf machinery twice, but
* only does one malloc. This can be a problem though when custom printf
* specs or the %m specifier are involved because the results of the
* second call might be different from the first. */
diff --git a/libc/stdio/vdprintf.c b/libc/stdio/vdprintf.c
index 67adf47be..de54a5c7d 100644
--- a/libc/stdio/vdprintf.c
+++ b/libc/stdio/vdprintf.c
@@ -11,7 +11,9 @@
#include "_stdio.h"
#include <stdarg.h>
+#ifdef __USE_OLD_VFPRINTF__
libc_hidden_proto(vfprintf)
+#endif
libc_hidden_proto(fflush_unlocked)
libc_hidden_proto(vdprintf)
@@ -22,8 +24,8 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg)
#ifdef __STDIO_BUFFERS
char buf[64]; /* TODO: provide _optional_ buffering? */
- f.__bufend = buf + sizeof(buf);
- f.__bufstart = buf;
+ f.__bufend = (unsigned char *) buf + sizeof(buf);
+ f.__bufstart = (unsigned char *) buf;
__STDIO_STREAM_DISABLE_GETC(&f);
__STDIO_STREAM_DISABLE_PUTC(&f);
__STDIO_STREAM_INIT_BUFREAD_BUFPOS(&f);
@@ -48,17 +50,19 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg)
__INIT_MBSTATE(&(f.__state));
#endif /* __STDIO_MBSTATE */
-#ifdef __UCLIBC_HAS_THREADS__
+/* _vfprintf_internal doesn't do any locking, locking init is here
+ * only because of fflush_unlocked. TODO? */
+#if (defined(__STDIO_BUFFERS) || defined(__USE_OLD_VFPRINTF__)) && defined(__UCLIBC_HAS_THREADS__)
f.__user_locking = 1; /* Set user locking. */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (f._lock);
-#else
- __stdio_init_mutex(&f.__lock);
-#endif
+ STDIO_INIT_MUTEX(f.__lock);
#endif
f.__nextopen = NULL;
+#ifdef __USE_OLD_VFPRINTF__
rv = vfprintf(&f, format, arg);
+#else
+ rv = _vfprintf_internal(&f, format, arg);
+#endif
#ifdef __STDIO_BUFFERS
/* If not buffering, then fflush is unnecessary. */
diff --git a/libc/stdio/vsnprintf.c b/libc/stdio/vsnprintf.c
index ab6154848..8bc697a48 100644
--- a/libc/stdio/vsnprintf.c
+++ b/libc/stdio/vsnprintf.c
@@ -10,13 +10,16 @@
libc_hidden_proto(vsnprintf)
+#ifdef __USE_OLD_VFPRINTF__
libc_hidden_proto(vfprintf)
+#endif
#ifdef __UCLIBC_MJN3_ONLY__
#warning WISHLIST: Implement vsnprintf for non-buffered and no custom stream case.
#endif /* __UCLIBC_MJN3_ONLY__ */
#ifdef __STDIO_BUFFERS
+/* NB: we can still have __USE_OLD_VFPRINTF__ defined in this case! */
int vsnprintf(char *__restrict buf, size_t size,
const char * __restrict format, va_list arg)
@@ -43,13 +46,9 @@ int vsnprintf(char *__restrict buf, size_t size,
__INIT_MBSTATE(&(f.__state));
#endif /* __STDIO_MBSTATE */
-#ifdef __UCLIBC_HAS_THREADS__
+#if defined(__USE_OLD_VFPRINTF__) && defined(__UCLIBC_HAS_THREADS__)
f.__user_locking = 1; /* Set user locking. */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (f._lock);
-#else
- __stdio_init_mutex(&f.__lock);
-#endif
+ STDIO_INIT_MUTEX(f.__lock);
#endif
f.__nextopen = NULL;
@@ -57,15 +56,20 @@ int vsnprintf(char *__restrict buf, size_t size,
size = SIZE_MAX - (size_t) buf;
}
+/* TODO: this comment seems to be wrong */
/* Set these last since __bufputc initialization depends on
* __user_locking and only gets set if user locking is on. */
- f.__bufstart = buf;
- f.__bufend = buf + size;
+ f.__bufstart = (unsigned char *) buf;
+ f.__bufend = (unsigned char *) buf + size;
__STDIO_STREAM_INIT_BUFREAD_BUFPOS(&f);
__STDIO_STREAM_DISABLE_GETC(&f);
__STDIO_STREAM_ENABLE_PUTC(&f);
+#ifdef __USE_OLD_VFPRINTF__
rv = vfprintf(&f, format, arg);
+#else
+ rv = _vfprintf_internal(&f, format, arg);
+#endif
if (size) {
if (f.__bufpos == f.__bufend) {
--f.__bufpos;
@@ -118,11 +122,7 @@ int vsnprintf(char *__restrict buf, size_t size,
#ifdef __UCLIBC_HAS_THREADS__
f.f.__user_locking = 1; /* Set user locking. */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (f.f._lock);
-#else
- __stdio_init_mutex(&f.f.__lock);
-#endif
+ STDIO_INIT_MUTEX(f.f.__lock);
#endif
f.f.__nextopen = NULL;
@@ -205,17 +205,9 @@ int vsnprintf(char *__restrict buf, size_t size,
__INIT_MBSTATE(&(f.__state));
#endif /* __STDIO_MBSTATE */
-#ifdef __UCLIBC_HAS_THREADS__
- f.__user_locking = 1; /* Set user locking. */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (f._lock);
-#else
- __stdio_init_mutex(&f.__lock);
-#endif
-#endif
f.__nextopen = NULL;
- rv = vfprintf(&f, format, arg);
+ rv = _vfprintf_internal(&f, format, arg);
return rv;
}
diff --git a/libc/stdio/vswprintf.c b/libc/stdio/vswprintf.c
index d95de51a2..cddf1d5d9 100644
--- a/libc/stdio/vswprintf.c
+++ b/libc/stdio/vswprintf.c
@@ -11,7 +11,7 @@
libc_hidden_proto(vswprintf)
-libc_hidden_proto(vfwprintf)
+/* NB: this file is not used if __USE_OLD_VFPRINTF__ */
#ifndef __STDIO_BUFFERS
#warning Skipping vswprintf since no buffering!
@@ -40,14 +40,6 @@ int vswprintf(wchar_t *__restrict buf, size_t size,
__INIT_MBSTATE(&(f.__state));
#endif /* __STDIO_MBSTATE */
-#ifdef __UCLIBC_HAS_THREADS__
- f.__user_locking = 1; /* Set user locking. */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (f._lock);
-#else
- __stdio_init_mutex(&f.__lock);
-#endif
-#endif
f.__nextopen = NULL;
if (size > ((SIZE_MAX - (size_t) buf)/sizeof(wchar_t))) {
@@ -60,7 +52,7 @@ int vswprintf(wchar_t *__restrict buf, size_t size,
__STDIO_STREAM_DISABLE_GETC(&f);
__STDIO_STREAM_DISABLE_PUTC(&f);
- rv = vfwprintf(&f, format, arg);
+ rv = _vfwprintf_internal(&f, format, arg);
/* NOTE: Return behaviour differs from snprintf... */
if (f.__bufpos == f.__bufend) {