summaryrefslogtreecommitdiff
path: root/libc/stdio
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2002-07-03 17:24:17 +0000
committerManuel Novoa III <mjn3@codepoet.org>2002-07-03 17:24:17 +0000
commit599ad608ee3297bc1e2bb11656a97335e303877a (patch)
treec5b59cb5fa2c90f3b0c8b4d9831ae763f2825327 /libc/stdio
parentab579e469c6787df9bd2252b3de8b1700d5097d8 (diff)
Enable WCHAR support for C/POSIX stub locales.
Implemented unformatted wide i/o functions. (ungetwc still needs testing) Fix a few bugs in wchar.c. Modifications for bcc/elks support.
Diffstat (limited to 'libc/stdio')
-rw-r--r--libc/stdio/Makefile6
-rw-r--r--libc/stdio/old_vfprintf.c6
-rw-r--r--libc/stdio/printf.c72
-rw-r--r--libc/stdio/scanf.c38
-rw-r--r--libc/stdio/stdio.c378
5 files changed, 323 insertions, 177 deletions
diff --git a/libc/stdio/Makefile b/libc/stdio/Makefile
index 0145b9475..011f3a7f8 100644
--- a/libc/stdio/Makefile
+++ b/libc/stdio/Makefile
@@ -57,7 +57,8 @@ MOBJ = fclose.o fflush.o fopen.o freopen.o perror.o remove.o \
__fsetlocking.o flockfile.o ftrylockfile.o funlockfile.o \
_stdio_fopen.o _stdio_fread.o _stdio_fwrite.o _stdio_adjpos.o \
_stdio_lseek.o _stdio_init.o \
- _stdio_fsfopen.o _stdio_fdout.o _uintmaxtostr.o _stdio_strerror_r.o
+ _stdio_fsfopen.o _stdio_fdout.o _uintmaxtostr.o _stdio_strerror_r.o \
+ getdelim.o getline.o ctermid.o
# ifeq ($(DOLFS),true)
# MOBJ += fopen64.o freopen64.o ftello64.o fseeko64.o fsetpos64.o fgetpos64.o
@@ -83,8 +84,7 @@ endif
MSRC3=scanf.c
MOBJ3=scanf.o sscanf.o fscanf.o vscanf.o vsscanf.o vfscanf.o
-CSRC=popen.c getdelim.c getline.c tmpfile.c tmpnam.c \
- tmpnam_r.c tempnam.c ctermid.c
+CSRC=popen.c tmpfile.c tmpnam.c tmpnam_r.c tempnam.c
ifeq ($(USE_OLD_VFPRINTF),true)
CSRC += old_vfprintf.c
endif
diff --git a/libc/stdio/old_vfprintf.c b/libc/stdio/old_vfprintf.c
index 036c97c94..945f59a48 100644
--- a/libc/stdio/old_vfprintf.c
+++ b/libc/stdio/old_vfprintf.c
@@ -143,7 +143,9 @@
/* #define __isdigit(c) (((unsigned int)(c - '0')) < 10) */
+#if defined(__UCLIBC_HAS_FLOATS__)
extern size_t _dtostr(FILE * fp, long double x, struct printf_info *info);
+#endif
enum {
@@ -179,7 +181,7 @@ int vfprintf(FILE * __restrict op, register const char * __restrict fmt,
va_list ap)
{
int i, cnt, lval, len;
- char *p;
+ register char *p;
const char *fmt0;
int preci, width;
#define upcase i
@@ -325,7 +327,7 @@ int vfprintf(FILE * __restrict op, register const char * __restrict fmt,
p = _uintmaxtostr((tmp + sizeof(tmp) - 1),
((lval>1) /* TODO -- longlong/long/int/short/char */
? va_arg(ap, uintmax_t)
- : (uintmax_t) ((long long) /* sign-extend! */
+ : (uintmax_t) ((intmax_t) /* sign-extend! */
va_arg(ap, long))),
-radix, upcase);
diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c
index 2fac4c93f..fc6dd87bd 100644
--- a/libc/stdio/printf.c
+++ b/libc/stdio/printf.c
@@ -108,7 +108,7 @@
#define __PA_FLAG_INTMASK \
(__PA_FLAG_CHAR|PA_FLAG_SHORT|__PA_FLAG_INT|PA_FLAG_LONG|PA_FLAG_LONG_LONG)
-extern printf_function *_custom_printf_handler[MAX_USER_SPEC];
+extern printf_function _custom_printf_handler[MAX_USER_SPEC];
extern printf_arginfo_function *_custom_printf_arginfo[MAX_USER_SPEC];
extern char *_custom_printf_spec;
@@ -177,13 +177,13 @@ enum {
*/
/* TODO -- Fix the table below to take into account stdint.h. */
-#ifndef LLONG_MAX
-#error fix QUAL_CHARS for no long long! Affects 'L', 'j', 'q', 'll'.
-#else
-#if LLONG_MAX != INTMAX_MAX
-#error fix QUAL_CHARS intmax_t entry 'j'!
-#endif
-#endif
+/* #ifndef LLONG_MAX */
+/* #error fix QUAL_CHARS for no long long! Affects 'L', 'j', 'q', 'll'. */
+/* #else */
+/* #if LLONG_MAX != INTMAX_MAX */
+/* #error fix QUAL_CHARS intmax_t entry 'j'! */
+/* #endif */
+/* #endif */
#ifdef PDS
#error PDS already defined!
@@ -191,6 +191,9 @@ enum {
#ifdef SS
#error SS already defined!
#endif
+#ifdef IMS
+#error IMS already defined!
+#endif
#if PTRDIFF_MAX == INT_MAX
#define PDS 0
@@ -212,11 +215,21 @@ enum {
#error fix QUAL_CHARS size_t entries 'z', 'Z'!
#endif
+#if INTMAX_MAX == INT_MAX
+#define IMS 0
+#elif INTMAX_MAX == LONG_MAX
+#define IMS 4
+#elif defined(LLONG_MAX) && (INTMAX_MAX == LLONG_MAX)
+#define IMS 8
+#else
+#error fix QUAL_CHARS ptrdiff_t entry 't'!
+#endif
+
#define QUAL_CHARS { \
/* j:(u)intmax_t z:(s)size_t t:ptrdiff_t \0:int */ \
/* q:long_long Z:(s)size_t */ \
'h', 'l', 'L', 'j', 'z', 't', 'q', 'Z', 0, \
- 2, 4, 8, 8, SS, PDS, 8, SS, 0, /* TODO -- fix!!! */\
+ 2, 4, 8, IMS, SS, PDS, 8, SS, 0, /* TODO -- fix!!! */\
1, 8 \
}
@@ -311,7 +324,7 @@ extern int _ppfs_parsespec(ppfs_t *ppfs); /* parses specifier */
*/
size_t parse_printf_format(register const char *template,
- size_t n, int *argtypes)
+ size_t n, register int *argtypes)
{
ppfs_t ppfs;
size_t i;
@@ -1021,7 +1034,7 @@ int register_printf_function(int spec, printf_function handler,
/**********************************************************************/
#ifdef L__do_one_spec
-printf_function *_custom_printf_handler[MAX_USER_SPEC];
+printf_function _custom_printf_handler[MAX_USER_SPEC];
extern void _store_inttype(void *dest, int desttype, uintmax_t val);
extern uintmax_t _load_inttype(int desttype, const void *src, int uflag);
@@ -1263,6 +1276,7 @@ int _do_one_spec(FILE * __restrict stream, register ppfs_t *ppfs, int *count)
#endif
/**********************************************************************/
#ifdef L_vsnprintf
+
#ifdef __STDIO_BUFFERS
int vsnprintf(char *__restrict buf, size_t size,
const char * __restrict format, va_list arg)
@@ -1273,7 +1287,7 @@ int vsnprintf(char *__restrict buf, size_t size,
#ifdef __STDIO_GETC_MACRO
f.bufgetc =
#endif
- f.bufrpos = f.bufwpos = f.bufstart = buf;
+ f.bufpos = f.bufread = f.bufstart = buf;
if (size > SIZE_MAX - (size_t) buf) {
size = SIZE_MAX - (size_t) buf;
@@ -1294,16 +1308,20 @@ int vsnprintf(char *__restrict buf, size_t size,
f.filedes = -2; /* for debugging */
f.modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING);
+#ifdef __STDIO_MBSTATE
+ __INIT_MBSTATE(&(f.state));
+#endif /* __STDIO_MBSTATE */
+
#ifdef __STDIO_THREADSAFE
__stdio_init_mutex(&f.lock);
#endif
rv = vfprintf(&f, format, arg);
if (size) {
- if (f.bufwpos == f.bufend) {
- --f.bufwpos;
+ if (f.bufpos == f.bufend) {
+ --f.bufpos;
}
- *f.bufwpos = 0;
+ *f.bufpos = 0;
}
return rv;
}
@@ -1319,10 +1337,11 @@ typedef struct {
#define COOKIE ((__snpf_cookie *) cookie)
-static ssize_t snpf_write(void *cookie, const char *buf, size_t bufsize)
+static ssize_t snpf_write(register void *cookie, const char *buf,
+ size_t bufsize)
{
size_t count;
- char *p;
+ register char *p;
/* Note: bufsize < SSIZE_MAX because of _stdio_WRITE. */
@@ -1368,6 +1387,10 @@ int vsnprintf(char *__restrict buf, size_t size,
f.filedes = -1; /* For debugging. */
f.modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING);
+#ifdef __STDIO_MBSTATE
+ __INIT_MBSTATE(&(f.state));
+#endif /* __STDIO_MBSTATE */
+
#ifdef __STDIO_THREADSAFE
__stdio_init_mutex(&f.lock);
#endif
@@ -1384,6 +1407,7 @@ int vsnprintf(char *__restrict buf, size_t size,
#endif
/**********************************************************************/
#ifdef L_vdprintf
+
int vdprintf(int filedes, const char * __restrict format, va_list arg)
{
FILE f;
@@ -1394,7 +1418,7 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg)
#ifdef __STDIO_GETC_MACRO
f.bufgetc =
#endif
- f.bufrpos = f.bufwpos = f.bufstart = buf;
+ f.bufpos = f.bufread = f.bufstart = buf;
#ifdef __STDIO_PUTC_MACRO
f.bufputc =
#endif
@@ -1410,6 +1434,10 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg)
f.filedes = filedes;
f.modeflags = (__FLAG_NARROW|__FLAG_WRITEONLY|__FLAG_WRITING);
+#ifdef __STDIO_MBSTATE
+ __INIT_MBSTATE(&(f.state));
+#endif /* __STDIO_MBSTATE */
+
#ifdef __STDIO_THREADSAFE
__stdio_init_mutex(&f.lock);
#endif
@@ -1418,6 +1446,7 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg)
return fflush(&f) ? -1 : rv;
}
+
#endif
/**********************************************************************/
#ifdef L_vasprintf
@@ -1486,6 +1515,7 @@ int vsprintf(char *__restrict buf, const char * __restrict format,
#endif
/**********************************************************************/
#ifdef L_fprintf
+
int fprintf(FILE * __restrict stream, const char * __restrict format, ...)
{
va_list arg;
@@ -1497,6 +1527,7 @@ int fprintf(FILE * __restrict stream, const char * __restrict format, ...)
return rv;
}
+
#endif
/**********************************************************************/
#ifdef L_snprintf
@@ -1521,6 +1552,7 @@ int snprintf(char *__restrict buf, size_t size,
#endif
/**********************************************************************/
#ifdef L_dprintf
+
int dprintf(int filedes, const char * __restrict format, ...)
{
va_list arg;
@@ -1532,6 +1564,7 @@ int dprintf(int filedes, const char * __restrict format, ...)
return rv;
}
+
#endif
/**********************************************************************/
#ifdef L_asprintf
@@ -2059,7 +2092,8 @@ void _store_inttype(register void *dest, int desttype, uintmax_t val)
/**********************************************************************/
#ifdef L__load_inttype
-extern uintmax_t _load_inttype(int desttype, const void *src, int uflag)
+extern uintmax_t _load_inttype(int desttype, register const void *src,
+ int uflag)
{
if (uflag >= 0) { /* unsigned */
#if LONG_MAX != INT_MAX
diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c
index 7506268b3..6d7a84e57 100644
--- a/libc/stdio/scanf.c
+++ b/libc/stdio/scanf.c
@@ -31,12 +31,8 @@
* implementation doesn't for the "100ergs" case mentioned above.
*/
+#define _ISOC99_SOURCE /* for LLONG_MAX primarily... */
#define _GNU_SOURCE
-#include <features.h>
-#if defined(__UCLIBC__) && !defined(__USE_ISOC99)
-#define __USE_ISOC99
-#endif
-
#define _STDIO_UTILITY
#include <stdio.h>
#include <stdlib.h>
@@ -124,9 +120,13 @@ int vsscanf(__const char *sp, __const char *fmt, va_list ap)
string->filedes = -2; /* for debugging */
string->modeflags = (__FLAG_NARROW|__FLAG_READONLY);
- string->bufstart = string->bufrpos = (unsigned char *) ((void *) sp);
+ string->bufstart = string->bufpos = (unsigned char *) ((void *) sp);
string->bufgetc = (char *) ((unsigned) -1);
+#ifdef __STDIO_MBSTATE
+ __INIT_MBSTATE(&(string->state));
+#endif /* __STDIO_MBSTATE */
+
#ifdef __STDIO_THREADSAFE
__stdio_init_mutex(&string->lock);
#endif
@@ -172,9 +172,11 @@ static int valid_digit(char c, char base)
extern unsigned long
_stdlib_strto_l(register const char * __restrict str,
char ** __restrict endptr, int base, int sflag);
+#ifdef LLONG_MAX
extern unsigned long long
_stdlib_strto_ll(register const char * __restrict str,
char ** __restrict endptr, int base, int sflag);
+#endif
struct scan_cookie {
FILE *fp;
@@ -205,7 +207,8 @@ static const char spec[] = "%n[csoupxXid";
/* radix[i] <-> spec[i+5] o u p x X i d */
static const char radix[] = { 8, 10, 16, 16, 16, 0, 10 };
-static void init_scan_cookie(struct scan_cookie *sc, FILE *fp)
+static void init_scan_cookie(register struct scan_cookie *sc,
+ register FILE *fp)
{
sc->fp = fp;
sc->nread = 0;
@@ -216,7 +219,7 @@ static void init_scan_cookie(struct scan_cookie *sc, FILE *fp)
/* TODO -- what about literal '\0' chars in a file??? */
-static int scan_getc_nw(struct scan_cookie *sc)
+static int scan_getc_nw(register struct scan_cookie *sc)
{
if (sc->ungot_flag == 0) {
sc->ungot_char = getc(sc->fp);
@@ -230,7 +233,7 @@ static int scan_getc_nw(struct scan_cookie *sc)
return sc->ungot_char;
}
-static int scan_getc(struct scan_cookie *sc)
+static int scan_getc(register struct scan_cookie *sc)
{
if (sc->ungot_flag == 0) {
sc->ungot_char = getc(sc->fp);
@@ -247,7 +250,7 @@ static int scan_getc(struct scan_cookie *sc)
return sc->ungot_char;
}
-static void scan_ungetc(struct scan_cookie *sc)
+static void scan_ungetc(register struct scan_cookie *sc)
{
if (sc->ungot_flag != 0) {
assert(sc->width < 0);
@@ -262,7 +265,7 @@ static void scan_ungetc(struct scan_cookie *sc)
}
}
-static void kill_scan_cookie(struct scan_cookie *sc)
+static void kill_scan_cookie(register struct scan_cookie *sc)
{
if (sc->ungot_flag) {
ungetc(sc->ungot_char,sc->fp);
@@ -273,10 +276,7 @@ static void kill_scan_cookie(struct scan_cookie *sc)
}
}
-int vfscanf(fp, format, ap)
-FILE *fp;
-const char *format;
-va_list ap;
+int vfscanf(FILE *fp, const char *format, va_list ap)
{
#ifdef __UCLIBC_HAS_LONG_LONG__
#define STRTO_L_(s,e,b,sf) _stdlib_strto_ll(s,e,b,sf)
@@ -294,9 +294,9 @@ va_list ap;
#endif
UV_TYPE uv;
struct scan_cookie sc;
- unsigned const char *fmt;
+ register unsigned const char *fmt;
const char *p;
- unsigned char *b;
+ register unsigned char *b;
void *vp;
int cc, i, cnt;
signed char lval;
@@ -523,7 +523,7 @@ va_list ap;
*((unsigned int *)vp) = (unsigned int)uv;
break;
#endif
- case -1:
+ case (signed char)(-1):
if (usflag) {
if (uv > USHRT_MAX) {
uv = USHRT_MAX;
@@ -535,7 +535,7 @@ va_list ap;
}
*((unsigned short *)vp) = (unsigned short)uv;
break;
- case -2:
+ case (signed char)(-2):
if (usflag) {
if (uv > UCHAR_MAX) {
uv = UCHAR_MAX;
diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c
index c84731675..a56eff777 100644
--- a/libc/stdio/stdio.c
+++ b/libc/stdio/stdio.c
@@ -25,6 +25,14 @@
*
* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */
+/* Before we include anything, convert L_ctermid to L_ctermid_function
+ * and undef L_ctermid if defined. This is necessary as L_ctermid is
+ * a SUSv3 standard macro defined in stdio.h. */
+#ifdef L_ctermid
+#define L_ctermid_function
+#undef L_ctermid
+#endif
+
#define _ISOC99_SOURCE /* for ULLONG primarily... */
#define _GNU_SOURCE
#define _STDIO_UTILITY /* for _stdio_fdout and _uintmaxtostr. */
@@ -72,27 +80,30 @@
/**********************************************************************/
-/* TODO -- make this the default except for bcc with it's broken preproc? */
-#ifdef __UCLIBC__
-#define _stdin stdin
-#define _stdout stdout
-#define _stderr stderr
-#endif /* __UCLIBC__ */
-
-/**********************************************************************/
-
#ifndef __STDIO_THREADSAFE
+#ifdef __BCC__
+#define UNLOCKED_STREAM(RETURNTYPE,NAME,PARAMS,ARGS,STREAM) \
+asm(".text\nexport _" "NAME" "_unlocked\n_" "NAME" "_unlocked = _" "NAME"); \
+RETURNTYPE NAME PARAMS
+#else
#define UNLOCKED_STREAM(RETURNTYPE,NAME,PARAMS,ARGS,STREAM) \
strong_alias(NAME,NAME##_unlocked) \
RETURNTYPE NAME PARAMS
+#endif
#define UNLOCKED(RETURNTYPE,NAME,PARAMS,ARGS) \
UNLOCKED_STREAM(RETURNTYPE,NAME,PARAMS,ARGS,stream)
+#ifdef __BCC__
+#define UNLOCKED_VOID_RETURN(NAME,PARAMS,ARGS) \
+asm(".text\nexport _" "NAME" "_unlocked\n_" "NAME" "_unlocked = _" "NAME"); \
+void NAME PARAMS
+#else
#define UNLOCKED_VOID_RETURN(NAME,PARAMS,ARGS) \
strong_alias(NAME,NAME##_unlocked) \
void NAME PARAMS
+#endif
#define __STDIO_THREADLOCK_OPENLIST
#define __STDIO_THREADUNLOCK_OPENLIST
@@ -175,6 +186,14 @@ void NAME##_unlocked PARAMS
#define __STDIO_FILE_INIT_CUSTOM_STREAM(stream)
#endif
+#ifdef __STDIO_MBSTATE
+#define __STDIO_FILE_INIT_MBSTATE \
+ { 0, 0 },
+#else
+#define __STDIO_FILE_INIT_MBSTATE
+#endif
+
+
#ifdef __STDIO_THREADSAFE
#define __STDIO_FILE_INIT_THREADSAFE \
0, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP,
@@ -191,21 +210,10 @@ void NAME##_unlocked PARAMS
__STDIO_FILE_INIT_BUFGETC((buf)) \
__STDIO_FILE_INIT_BUFPUTC((buf)) \
__STDIO_FILE_INIT_CUSTOM_STREAM(stream) \
+ __STDIO_FILE_INIT_MBSTATE \
__STDIO_FILE_INIT_THREADSAFE \
} /* TODO: mbstate and builtin buf */
-#ifdef __STDIO_MBSTATE_DATA
-extern void _init_mbstate(mbstate_t *dest);
-
-#define __COMMA_CLEAN_MBSTATE , 0
-#define __COPY_MBSTATE(dest,src) memcpy(dest, src, sizeof(mbstate_t))
-#define __INIT_MBSTATE(dest) _init_mbstate(dest)
-#else
-#define __COMMA_CLEAN_MBSTATE
-#define __COPY_MBSTATE(dest,src)
-#define __INIT_MBSTATE(dest)
-#endif
-
#ifdef __STDIO_GLIBC_CUSTOM_STREAMS
/* TODO -- what does glibc do for undefined funcs? errno set? */
@@ -237,7 +245,7 @@ extern void _init_mbstate(mbstate_t *dest);
/* SUSv2 Legacy function -- need not be reentrant. */
-int getw (register FILE *stream)
+int getw(FILE *stream)
{
int aw[1];
@@ -259,7 +267,7 @@ int getw (register FILE *stream)
/* SUSv2 Legacy function -- need not be reentrant. */
-int putw (int w, register FILE *stream)
+int putw(int w, FILE *stream)
{
int aw[1];
@@ -322,6 +330,30 @@ FILE *fopen64(const char * __restrict filename, const char * __restrict mode)
#endif
/**********************************************************************/
+#ifdef L_ctermid_function
+
+/* Not required to be reentrant. */
+
+char *ctermid(register char *s)
+{
+ static char sbuf[L_ctermid];
+
+#ifdef __BCC__
+ /* Currently elks doesn't support /dev/tty. */
+ if (!s) {
+ s = sbuf;
+ }
+ *s = 0;
+
+ return s;
+#else
+ /* glibc always returns /dev/tty for linux. */
+ return strcpy((s ? s : sbuf), "/dev/tty");
+#endif
+}
+
+#endif
+/**********************************************************************/
/* BSD functions */
/**********************************************************************/
#ifdef L_setbuffer
@@ -413,7 +445,7 @@ typedef struct {
#define COOKIE ((__fmo_cookie *) cookie)
-static ssize_t fmo_read(void *cookie, register char *buf, size_t bufsize)
+static ssize_t fmo_read(register void *cookie, char *buf, size_t bufsize)
{
size_t count = COOKIE->len - COOKIE->pos;
@@ -442,7 +474,7 @@ static ssize_t fmo_read(void *cookie, register char *buf, size_t bufsize)
return bufsize;
}
-static ssize_t fmo_write(void *cookie, register const char *buf, size_t bufsize)
+static ssize_t fmo_write(register void *cookie, const char *buf, size_t bufsize)
{
size_t count;
@@ -499,7 +531,7 @@ static ssize_t fmo_write(void *cookie, register const char *buf, size_t bufsize)
}
/* glibc doesn't allow seeking, but it has in-buffer seeks... we don't. */
-static int fmo_seek(void *cookie, __offmax_t *pos, int whence)
+static int fmo_seek(register void *cookie, __offmax_t *pos, int whence)
{
__offmax_t p = *pos;
@@ -522,7 +554,7 @@ static int fmo_seek(void *cookie, __offmax_t *pos, int whence)
return 0;
}
-static int fmo_close(void *cookie)
+static int fmo_close(register void *cookie)
{
if (COOKIE->dynbuf) {
free(COOKIE->buf);
@@ -545,7 +577,7 @@ static const cookie_io_functions_t _fmo_io_funcs = {
FILE *fmemopen(void *s, size_t len, const char *modes)
{
FILE *fp;
- __fmo_cookie *cookie;
+ register __fmo_cookie *cookie;
size_t i;
if ((cookie = malloc(sizeof(__fmo_cookie))) != NULL) {
@@ -614,9 +646,9 @@ typedef struct {
/* { */
/* } */
-static ssize_t oms_write(void *cookie, const char *buf, size_t bufsize)
+static ssize_t oms_write(register void *cookie, const char *buf, size_t bufsize)
{
- char *newbuf;
+ register char *newbuf;
size_t count;
/* Note: we already know bufsize < SSIZE_MAX... */
@@ -649,10 +681,10 @@ static ssize_t oms_write(void *cookie, const char *buf, size_t bufsize)
return bufsize;
}
-static int oms_seek(void *cookie, __offmax_t *pos, int whence)
+static int oms_seek(register void *cookie, __offmax_t *pos, int whence)
{
__offmax_t p = *pos;
- char *buf;
+ register char *buf;
size_t leastlen;
/* Note: fseek already checks that whence is legal, so don't check here
@@ -713,8 +745,8 @@ static const cookie_io_functions_t _oms_io_funcs = {
FILE *open_memstream(char **__restrict bufloc, size_t *__restrict sizeloc)
{
- __oms_cookie *cookie;
- FILE *fp;
+ register __oms_cookie *cookie;
+ register FILE *fp;
if ((cookie = malloc(sizeof(__oms_cookie))) != NULL) {
if ((cookie->buf = malloc(cookie->len = BUFSIZ)) == NULL) {
@@ -767,8 +799,8 @@ FILE *open_memstream(char **__restrict bufloc, size_t *__restrict sizeloc)
#ifndef __BCC__
-FILE *fopencookie (void * __restrict cookie, const char * __restrict mode,
- cookie_io_functions_t io_functions)
+FILE *fopencookie(void * __restrict cookie, const char * __restrict mode,
+ cookie_io_functions_t io_functions)
{
FILE *stream;
int fd;
@@ -804,10 +836,10 @@ FILE *fopencookie (void * __restrict cookie, const char * __restrict mode,
* instead.
*/
-FILE *_fopencookie (void * __restrict cookie, const char * __restrict mode,
- cookie_io_functions_t *io_functions)
+FILE *_fopencookie(void * __restrict cookie, const char * __restrict mode,
+ register cookie_io_functions_t *io_functions)
{
- FILE *stream;
+ register FILE *stream;
if ((stream = _stdio_fopen("/dev/null", mode, NULL, -1)) != NULL) {
int fd = stream->filedes;
@@ -929,7 +961,7 @@ void __fpurge(register FILE * __restrict stream)
#ifdef __STDIO_GETC_MACRO
stream->bufgetc = /* Must disable getc. */
#endif
- stream->bufwpos = stream->bufrpos = stream->bufstart; /* Reset pointers. */
+ stream->bufpos = stream->bufread = stream->bufstart; /* Reset pointers. */
#endif /* __STDIO_BUFFERS */
/* Reset r/w flags and clear ungots. */
stream->modeflags &= ~(__FLAG_READING|__FLAG_WRITING|__MASK_UNGOT);
@@ -942,19 +974,22 @@ void __fpurge(register FILE * __restrict stream)
/* Not reentrant. */
#ifdef __STDIO_WIDE
-#warning TODO -- implement __fpending for wide streams! */
-#else /* __STDIO_WIDE */
+#warning unlike the glibc version, this __fpending returns bytes in buffer for wide streams too!
+
+link_warning(__fpending, "This version of __fpending returns bytes remaining in buffer for both narrow and wide streams. glibc's version returns wide chars in buffer for the wide stream case.")
+
+#endif /* __STDIO_WIDE */
+
size_t __fpending(register FILE * __restrict stream)
{
#ifdef __STDIO_BUFFERS
/* TODO -- should we check this? should we set errno? just assert? */
return (stream->modeflags & (__FLAG_READING|__FLAG_READONLY))
- ? 0 : (stream->bufwpos - stream->bufstart);
+ ? 0 : (stream->bufpos - stream->bufstart);
#else /* __STDIO_BUFFERS */
return 0;
#endif /* __STDIO_BUFFERS */
}
-#endif /* __STDIO_WIDE */
#endif
/**********************************************************************/
@@ -1039,6 +1074,64 @@ void funlockfile(FILE *stream)
#endif
/**********************************************************************/
+#ifdef L_getline
+
+ssize_t getline(char **__restrict lineptr, size_t *__restrict n,
+ FILE *__restrict stream)
+{
+ return __getdelim(lineptr, n, '\n', stream);
+}
+
+#endif
+/**********************************************************************/
+#ifdef L_getdelim
+
+weak_alias(__getdelim,getdelim);
+
+#define GETDELIM_GROWBY 64
+
+ssize_t __getdelim(char **__restrict lineptr, size_t *__restrict n,
+ int delimiter, register FILE *__restrict stream)
+{
+ register char *buf;
+ size_t pos;
+ int c;
+
+ if (!lineptr || !n || !stream) { /* Be compatable with glibc... even */
+ __set_errno(EINVAL); /* though I think we should assert here */
+ return -1; /* if anything. */
+ }
+
+ if (!(buf = *lineptr)) { /* If passed NULL for buffer, */
+ *n = 0; /* ignore value passed and treat size as 0. */
+ }
+ pos = 1; /* Make sure we have space for terminating nul. */
+
+ __STDIO_THREADLOCK(stream);
+
+ do {
+ if (pos >= *n) {
+ if (!(buf = realloc(buf, *n + GETDELIM_GROWBY))) {
+ __set_errno(ENOMEM); /* Emulate old uClibc implementation. */
+ break;
+ }
+ *n += GETDELIM_GROWBY;
+ *lineptr = buf;
+ }
+ } while (((c = getc(stream)) != EOF) && ((buf[pos++ - 1] = c) != delimiter));
+
+ __STDIO_THREADUNLOCK(stream);
+
+ if (--pos) {
+ buf[pos] = 0;
+ return pos;
+ }
+
+ return -1; /* Either initial realloc failed or first read was EOF. */
+}
+
+#endif
+/**********************************************************************/
/* my extension functions */
/**********************************************************************/
#ifdef L__stdio_fsfopen
@@ -1079,11 +1172,9 @@ FILE *_stdio_fsfopen(const char * __restrict filename,
* then the file position is treated as unknown.
*/
-
/* Internal function -- not reentrant. */
-int _stdio_adjpos(register FILE * __restrict stream,
- register __offmax_t *pos)
+int _stdio_adjpos(register FILE * __restrict stream, register __offmax_t *pos)
{
__offmax_t r;
int cor = stream->modeflags & __MASK_UNGOT; /* handle ungots */
@@ -1092,18 +1183,18 @@ int _stdio_adjpos(register FILE * __restrict stream,
/* Assumed narrow stream so correct if wide. */
if (cor && (stream->modeflags & __FLAG_WIDE)) {
cor = cor - 1 + stream->ungot_width[0];
- if ((stream->ungot_width[0] == 0) /* don't know byte count or */
- || ((stream->modeflags & __MASK_UNGOT) > 1)) { /* app case */
- return -1;
+ if (((stream->modeflags & __MASK_UNGOT) > 1) || stream->ungot[1]) {
+ return -1; /* App did ungetwc, so position is indeterminate. */
}
+ assert(stream->ungot_width[0] > 0);
}
#endif /* __STDIO_WIDE */
#ifdef __STDIO_BUFFERS
if (stream->modeflags & __FLAG_WRITING) {
- cor -= (stream->bufwpos - stream->bufstart); /* pending writes */
+ cor -= (stream->bufpos - stream->bufstart); /* pending writes */
}
if (stream->modeflags & __FLAG_READING) {
- cor += (stream->bufwpos - stream->bufrpos); /* extra's read */
+ cor += (stream->bufread - stream->bufpos); /* extra's read */
}
#endif /* __STDIO_BUFFERS */
@@ -1122,7 +1213,7 @@ int _stdio_adjpos(register FILE * __restrict stream,
/* Internal function -- not reentrant. */
-int _stdio_lseek(FILE *stream, __offmax_t *pos, int whence)
+int _stdio_lseek(register FILE *stream, register __offmax_t *pos, int whence)
{
__offmax_t res;
@@ -1152,7 +1243,7 @@ int _stdio_lseek(FILE *stream, __offmax_t *pos, int whence)
/* Unlike write, it's ok for read to return fewer than bufsize, since
* we may not need all of them. */
-static ssize_t _stdio_READ(FILE *stream, void *buf, size_t bufsize)
+static ssize_t _stdio_READ(register FILE *stream, unsigned char *buf, size_t bufsize)
{
ssize_t rv;
@@ -1192,8 +1283,7 @@ static ssize_t _stdio_READ(FILE *stream, void *buf, size_t bufsize)
/* Internal function -- not reentrant. */
-size_t _stdio_fread(unsigned char *buffer, size_t bytes,
- register FILE *stream)
+size_t _stdio_fread(unsigned char *buffer, size_t bytes, register FILE *stream)
{
__stdio_validate_FILE(stream); /* debugging only */
@@ -1233,12 +1323,15 @@ size_t _stdio_fread(unsigned char *buffer, size_t bytes,
if (stream->modeflags & __MASK_BUFMODE) {
/* If the stream is readable and not fully buffered, we must first
* flush all line buffered output streams. Do this before the
- * error check as this may be a read/write line-buffered stream. */
- fflush((FILE *) &_stdio_openlist); /* Uses an implementation hack!!! */
+ * error check as this may be a read/write line-buffered stream.
+ * Note: Uses an implementation-specific hack!!! */
+ fflush_unlocked((FILE *) &_stdio_openlist);
}
#ifdef __STDIO_AUTO_RW_TRANSITION
- if ((stream->modeflags & __FLAG_WRITING) && (fflush(stream) == EOF)) {
+ if ((stream->modeflags & __FLAG_WRITING)
+ && (fflush_unlocked(stream) == EOF)
+ ) {
return 0; /* Fail if we need to fflush but can't. */
}
#endif /* __STDIO_AUTO_RW_TRANSITION */
@@ -1260,23 +1353,23 @@ size_t _stdio_fread(unsigned char *buffer, size_t bytes,
/* Now get any other needed chars from the buffer or the file. */
FROM_BUF:
- while (bytes && (stream->bufrpos < stream->bufwpos)) {
+ while (bytes && (stream->bufpos < stream->bufread)) {
--bytes;
- *p++ = *stream->bufrpos++;
+ *p++ = *stream->bufpos++;
}
if (bytes > 0) {
ssize_t len;
/* The buffer is exhausted, but we still need chars. */
- stream->bufrpos = stream->bufwpos = stream->bufstart;
+ stream->bufpos = stream->bufread = stream->bufstart;
- if (bytes <= stream->bufend - stream->bufwpos) {
+ if (bytes <= stream->bufend - stream->bufread) {
/* We have sufficient space in the buffer. */
- len = _stdio_READ(stream, stream->bufwpos,
- stream->bufend - stream->bufwpos);
+ len = _stdio_READ(stream, stream->bufread,
+ stream->bufend - stream->bufread);
if (len > 0) {
- stream->bufwpos += len;
+ stream->bufread += len;
goto FROM_BUF;
}
} else {
@@ -1293,7 +1386,7 @@ size_t _stdio_fread(unsigned char *buffer, size_t bytes,
#ifdef __STDIO_GETC_MACRO
if (!(stream->modeflags & (__FLAG_WIDE|__MASK_UNGOT|__MASK_BUFMODE))) {
- stream->bufgetc = stream->bufwpos; /* Enable getc macro. */
+ stream->bufgetc = stream->bufread; /* Enable getc macro. */
}
#endif
@@ -1377,7 +1470,8 @@ size_t _stdio_fread(unsigned char *buffer, size_t bytes,
*deals correctly with bufsize > SSIZE_MAX... not much on an issue on linux
* but definitly could be on Elks. Also on Elks, always loops for EINTR..
* Returns number of bytes written, so a short write indicates an error */
-static size_t _stdio_WRITE(FILE *stream, const void *buf, size_t bufsize)
+static size_t _stdio_WRITE(register FILE *stream,
+ register const unsigned char *buf, size_t bufsize)
{
size_t todo;
ssize_t rv, stodo;
@@ -1412,7 +1506,7 @@ static size_t _stdio_WRITE(FILE *stream, const void *buf, size_t bufsize)
/* Internal function -- not reentrant. */
size_t _stdio_fwrite(const unsigned char *buffer, size_t bytes,
- register FILE *stream)
+ register FILE *stream)
{
#ifdef __STDIO_BUFFERS
register const unsigned char *p;
@@ -1438,7 +1532,7 @@ size_t _stdio_fwrite(const unsigned char *buffer, size_t bytes,
#ifdef __STDIO_AUTO_RW_TRANSITION
/* If reading, deal with ungots and read-buffered chars. */
if (stream->modeflags & __FLAG_READING) {
- if (((stream->bufrpos < stream->bufwpos)
+ if (((stream->bufpos < stream->bufread)
|| (stream->modeflags & __MASK_UNGOT))
/* If appending, we might as well seek to end to save a seek. */
/* TODO: set EOF in fseek when appropriate? */
@@ -1456,7 +1550,7 @@ size_t _stdio_fwrite(const unsigned char *buffer, size_t bytes,
#ifdef __STDIO_GETC_MACRO
stream->bufgetc =
#endif /* __STDIO_GETC_MACRO */
- stream->bufrpos = stream->bufwpos = stream->bufstart;
+ stream->bufpos = stream->bufread = stream->bufstart;
}
#endif
@@ -1475,7 +1569,7 @@ size_t _stdio_fwrite(const unsigned char *buffer, size_t bytes,
if (!buffer) { /* fflush the stream */
FFLUSH:
{
- size_t count = stream->bufwpos - stream->bufstart;
+ size_t count = stream->bufpos - stream->bufstart;
p = stream->bufstart;
if (stream->filedes == -2) { /* TODO -- document this hack! */
@@ -1489,22 +1583,22 @@ size_t _stdio_fwrite(const unsigned char *buffer, size_t bytes,
count -= rv;
}
- stream->bufwpos = stream->bufstart;
+ stream->bufpos = stream->bufstart;
while (count) {
- *stream->bufwpos++ = *p++;
+ *stream->bufpos++ = *p++;
--count;
}
if (!buffer) { /* fflush case... */
__stdio_validate_FILE(stream); /* debugging only */
- return stream->bufwpos - stream->bufstart;
+ return stream->bufpos - stream->bufstart;
}
}
}
#if 1
/* TODO: If the stream is buffered, we may be able to omit. */
- if ((stream->bufwpos == stream->bufstart) /* buf empty */
+ if ((stream->bufpos == stream->bufstart) /* buf empty */
&& (stream->bufend - stream->bufstart <= bytes) /* fills */
&& (stream->filedes != -2)) { /* not strinf fake file */
/* so want to do a direct write of supplied buffer */
@@ -1517,7 +1611,7 @@ size_t _stdio_fwrite(const unsigned char *buffer, size_t bytes,
#endif
/* otherwise buffer not empty and/or data fits */
{
- size_t count = stream->bufend - stream->bufwpos;
+ size_t count = stream->bufend - stream->bufpos;
p = buffer;
if (count > bytes) {
@@ -1526,7 +1620,7 @@ size_t _stdio_fwrite(const unsigned char *buffer, size_t bytes,
bytes -= count;
while (count) {
- *stream->bufwpos++ = *buffer++;
+ *stream->bufpos++ = *buffer++;
--count;
}
@@ -1615,10 +1709,12 @@ void __stdio_validate_FILE(FILE *stream)
__STDIO_THREADLOCK(stream);
#ifdef __STDIO_BUFFERS
- assert(stream->bufstart <= stream->bufrpos);
- assert(stream->bufrpos <= stream->bufwpos);
- assert(stream->bufwpos <= stream->bufend);
- assert(stream->bufwpos <= stream->bufend);
+ assert(stream->bufstart <= stream->bufread);
+ if (stream->modeflags & (__FLAG_READING)) {
+ assert(stream->bufpos <= stream->bufread);
+ }
+ assert(stream->bufread <= stream->bufend);
+ assert(stream->bufpos <= stream->bufend);
if ((stream->modeflags & __MASK_BUFMODE) == __FLAG_NBF) {
assert(stream->bufstart == stream->bufend);
}
@@ -1637,7 +1733,7 @@ void __stdio_validate_FILE(FILE *stream)
#endif
#ifdef __STDIO_GETC_MACRO
assert(stream->bufstart <= stream->bufgetc);
- assert(stream->bufgetc <= stream->bufwpos);
+ assert(stream->bufgetc <= stream->bufread);
if (stream->bufstart < stream->bufgetc) {
assert(stream->modeflags & (__FLAG_READING));
assert(!(stream->modeflags
@@ -1693,9 +1789,9 @@ static FILE _stdio_streams[] = {
2, 0, 0, 0 )
};
-FILE *_stdin = _stdio_streams + 0;
-FILE *_stdout = _stdio_streams + 1;
-FILE *_stderr = _stdio_streams + 2;
+FILE *stdin = _stdio_streams + 0;
+FILE *stdout = _stdio_streams + 1;
+FILE *stderr = _stdio_streams + 2;
#if defined(__STDIO_BUFFERS) || defined(__STDIO_GLIBC_CUSTOM_STREAMS)
@@ -1725,7 +1821,7 @@ void __stdio_init_mutex(pthread_mutex_t *m)
void _stdio_term(void)
{
#if defined(__STDIO_GLIBC_CUSTOM_STREAMS) || defined(__STDIO_THREADSAFE)
- FILE *ptr;
+ register FILE *ptr;
#endif
/* TODO: if called via a signal handler for a signal mid _stdio_fwrite,
@@ -1746,7 +1842,7 @@ void _stdio_term(void)
/* TODO -- set an alarm and flush each file "by hand"? to avoid blocking? */
/* Now flush all streams. */
- fflush(NULL);
+ fflush_unlocked(NULL);
#endif /* __STDIO_BUFFERS */
/* Next close all custom streams in case of any special cleanup, but
@@ -1765,7 +1861,7 @@ void _stdio_term(void)
/* TODO: "unbuffer" files like glibc does? Inconsistent with
* custom stream handling above, but that's necessary to deal
* with special user-defined close behavior. */
- stream->bufwpos = stream->bufrpos = stream->bufend
+ stream->bufpos = stream->bufread = stream->bufend
#ifdef __STDIO_GETC_MACRO
= stream->bufgetc
#endif
@@ -1867,8 +1963,8 @@ int fclose(register FILE *stream)
#ifdef __STDIO_BUFFERS
if (stream->modeflags & __FLAG_WRITING) {
- rv = fflush(stream); /* Write any pending buffered chars. */
- } /* Also disables putc macro if used. */
+ rv = fflush_unlocked(stream); /* Write any pending buffered chars. */
+ } /* Also disables putc macro if used. */
#ifdef __STDIO_GETC_MACRO
/* Not necessary after fflush, but always do this to reduce size. */
@@ -2097,8 +2193,8 @@ FILE *fopen(const char * __restrict filename, const char * __restrict mode)
/* Internal function -- reentrant (locks open file list) */
FILE *_stdio_fopen(const char * __restrict filename,
- register const char * __restrict mode,
- register FILE * __restrict stream, int filedes)
+ register const char * __restrict mode,
+ register FILE * __restrict stream, int filedes)
{
__mode_t open_mode;
@@ -2230,7 +2326,7 @@ FILE *_stdio_fopen(const char * __restrict filename,
#ifdef __STDIO_PUTC_MACRO
stream->bufputc =
#endif
- stream->bufwpos = stream->bufrpos = stream->bufstart;
+ stream->bufpos = stream->bufread = stream->bufstart;
#endif /* __STDIO_BUFFERS */
#ifdef __STDIO_GLIBC_CUSTOM_STREAMS
@@ -2241,6 +2337,10 @@ FILE *_stdio_fopen(const char * __restrict filename,
stream->gcs.close = _cs_close;
#endif /* __STDIO_GLIBC_CUSTOM_STREAMS */
+#ifdef __STDIO_MBSTATE
+ __INIT_MBSTATE(&(stream->state));
+#endif /* __STDIO_MBSTATE */
+
#ifdef __STDIO_THREADSAFE
__stdio_init_mutex(&stream->lock);
#endif /* __STDIO_THREADSAFE */
@@ -2282,7 +2382,7 @@ FILE *freopen(const char * __restrict filename, const char * __restrict mode,
* TODO: Apparently linux allows setting append mode. Implement?
*/
unsigned short dynmode;
- FILE *fp;
+ register FILE *fp;
__STDIO_THREADLOCK(stream);
@@ -2290,7 +2390,7 @@ FILE *freopen(const char * __restrict filename, const char * __restrict mode,
/* This also removes the stream for the open file list. */
dynmode =
#ifdef __STDIO_BUFFERS
- // __MASK_BUFMODE | /* TODO: check */
+ /* __MASK_BUFMODE | */ /* TODO: check */
#endif /* __STDIO_BUFFERS */
(stream->modeflags & (__FLAG_FREEBUF|__FLAG_FREEFILE));
@@ -2310,12 +2410,12 @@ FILE *freopen(const char * __restrict filename, const char * __restrict mode,
/* Reentrant. */
-/* TODO -- is it collecting the common work (40 bytes) into a function? */
+/* TODO -- is it worth collecting the common work (40 bytes) in a function? */
FILE *freopen64(const char * __restrict filename, const char * __restrict mode,
register FILE * __restrict stream)
{
unsigned short dynmode;
- FILE *fp;
+ register FILE *fp;
__STDIO_THREADLOCK(stream);
@@ -2323,7 +2423,7 @@ FILE *freopen64(const char * __restrict filename, const char * __restrict mode,
/* This also removes the stream for the open file list. */
dynmode =
#ifdef __STDIO_BUFFERS
- // __MASK_BUFMODE | /* TODO: check */
+ /* __MASK_BUFMODE | */ /* TODO: check */
#endif /* __STDIO_BUFFERS */
(stream->modeflags & (__FLAG_FREEBUF|__FLAG_FREEFILE));
@@ -2448,7 +2548,7 @@ int setvbuf(register FILE * __restrict stream, register char * __restrict buf,
#ifdef __STDIO_PUTC_MACRO
stream->bufputc =
#endif
- stream->bufwpos = stream->bufrpos = stream->bufstart = buf;
+ stream->bufpos = stream->bufread = stream->bufstart = buf;
stream->bufend = buf + size;
}
@@ -2603,9 +2703,9 @@ UNLOCKED(int,getc,(register FILE *stream),(stream))
/* Reentrancy handled by UNLOCKED() macro. */
-UNLOCKED_STREAM(int,getchar,(void),(),_stdin)
+UNLOCKED_STREAM(int,getchar,(void),(),stdin)
{
- register FILE *stream = _stdin; /* This helps bcc optimize. */
+ register FILE *stream = stdin; /* This helps bcc optimize. */
return __GETC(stream);
}
@@ -2620,7 +2720,7 @@ link_warning(gets, "the 'gets' function is dangerous and should not be used.")
char *gets(char *s) /* WARNING!!! UNSAFE FUNCTION!!! */
{
- register FILE *stream = _stdin; /* This helps bcc optimize. */
+ register FILE *stream = stdin; /* This helps bcc optimize. */
register char *p = s;
int c;
@@ -2628,7 +2728,7 @@ char *gets(char *s) /* WARNING!!! UNSAFE FUNCTION!!! */
/* Note: don't worry about performance here... this shouldn't be used!
* Therefore, force actual function call. */
- while (((c = (*getc)(stream)) != EOF) && ((*p = c) != '\n')) {
+ while (((c = (getc_unlocked)(stream)) != EOF) && ((*p = c) != '\n')) {
++p;
}
if ((c == EOF) || (s == p)) {
@@ -2661,9 +2761,9 @@ UNLOCKED(int,putc,(int c, register FILE *stream),(c,stream))
/* Reentrancy handled by UNLOCKED() macro. */
-UNLOCKED_STREAM(int,putchar,(int c),(c),_stdout)
+UNLOCKED_STREAM(int,putchar,(int c),(c),stdout)
{
- register FILE *stream = _stdout; /* This helps bcc optimize. */
+ register FILE *stream = stdout; /* This helps bcc optimize. */
return __PUTC(c, stream);
}
@@ -2676,17 +2776,17 @@ UNLOCKED_STREAM(int,putchar,(int c),(c),_stdout)
int puts(register const char *s)
{
- register FILE *stream = _stdout; /* This helps bcc optimize. */
+ register FILE *stream = stdout; /* This helps bcc optimize. */
int n;
__STDIO_THREADLOCK(stream);
- n = fputs(s,stream) + 1;
+ n = fputs_unlocked(s,stream) + 1;
if (
#if 1
- fputc('\n',stream)
+ fputc_unlocked('\n',stream)
#else
- fputs("\n",stream)
+ fputs_unlocked("\n",stream)
#endif
== EOF) {
n = EOF;
@@ -2739,7 +2839,7 @@ int ungetc(int c, register FILE *stream)
#ifdef __STDIO_BUFFERS
/* TODO: shouldn't allow writing??? */
if (stream->modeflags & __FLAG_WRITING) {
- fflush(stream); /* Commit any write-buffered chars. */
+ fflush_unlocked(stream); /* Commit any write-buffered chars. */
}
#endif /* __STDIO_BUFFERS */
@@ -2838,21 +2938,22 @@ UNLOCKED(size_t,fwrite,
int fgetpos64(FILE * __restrict stream, register fpos64_t * __restrict pos)
{
+#ifdef __STDIO_MBSTATE
int retval;
__STDIO_THREADLOCK(stream);
retval = ((pos != NULL) && ((pos->__pos = ftello64(stream)) >= 0))
- ? (
-#ifdef __STDIO_MBSTATE_DATA
- __COPY_MBSTATE(&(pos->__mbstate), &(stream->mbstate)),
-#endif /* __STDIO_MBSTATE_DATA */
- 0)
+ ? (__COPY_MBSTATE(&(pos->__mbstate), &(stream->state)), 0)
: (__set_errno(EINVAL), -1);
__STDIO_THREADUNLOCK(stream);
return retval;
+#else
+ return ((pos != NULL) && ((pos->__pos = ftello64(stream)) >= 0))
+ ? 0 : (__set_errno(EINVAL), -1);
+#endif
}
#ifndef L_fgetpos64
@@ -2864,7 +2965,7 @@ int fgetpos64(FILE * __restrict stream, register fpos64_t * __restrict pos)
#endif
/**********************************************************************/
#ifdef L_fseek
-strong_alias(fseek, fseeko);
+strong_alias(fseek,fseeko);
#endif
#if defined(L_fseek) && defined(__STDIO_LARGE_FILES)
@@ -2907,7 +3008,7 @@ int fseeko64(register FILE *stream, __off64_t offset, int whence)
if (
#ifdef __STDIO_BUFFERS
/* First commit any pending buffered writes. */
- ((stream->modeflags & __FLAG_WRITING) && fflush(stream)) ||
+ ((stream->modeflags & __FLAG_WRITING) && fflush_unlocked(stream)) ||
#endif /* __STDIO_BUFFERS */
((whence == SEEK_CUR) && (_stdio_adjpos(stream, pos) < 0))
|| (_stdio_lseek(stream, pos, whence) < 0)
@@ -2921,16 +3022,16 @@ int fseeko64(register FILE *stream, __off64_t offset, int whence)
#ifdef __STDIO_GETC_MACRO
stream->bufgetc = /* Must disable getc. */
#endif
- stream->bufwpos = stream->bufrpos = stream->bufstart;
+ stream->bufpos = stream->bufread = stream->bufstart;
#endif /* __STDIO_BUFFERS */
stream->modeflags &=
~(__FLAG_READING|__FLAG_WRITING|__FLAG_EOF|__MASK_UNGOT);
-#ifdef __STDIO_MBSTATE_DATA
+#ifdef __STDIO_MBSTATE
/* TODO: don't clear state if don't move? */
- __INIT_MBSTATE(&(stream->mbstate));
-#endif /* __STDIO_MBSTATE_DATA */
+ __INIT_MBSTATE(&(stream->state));
+#endif /* __STDIO_MBSTATE */
__stdio_validate_FILE(stream); /* debugging only */
retval = 0;
@@ -2968,18 +3069,23 @@ int fsetpos64(FILE *stream, register const fpos64_t *pos)
__set_errno(EINVAL);
return EOF;
}
-#ifdef __STDIO_MBSTATE_DATA
-#error unimplemented and non-reentrant besides!
+#ifdef __STDIO_MBSTATE
{
int retval;
+
+ __STDIO_THREADLOCK(stream);
+
if ((retval = fseeko64(stream, pos->__pos, SEEK_SET)) == 0) {
- __COPY_MBSTATE(&(stream->mbstate), &(pos->__mbstate));
+ __COPY_MBSTATE(&(stream->state), &(pos->__mbstate));
}
+
+ __STDIO_THREADUNLOCK(stream);
+
return retval;
}
-#else /* __STDIO_MBSTATE_DATA */
+#else /* __STDIO_MBSTATE */
return fseeko64(stream, pos->__pos, SEEK_SET);
-#endif /* __STDIO_MBSTATE_DATA */
+#endif /* __STDIO_MBSTATE */
}
#ifndef L_fsetpos64
@@ -2991,7 +3097,7 @@ int fsetpos64(FILE *stream, register const fpos64_t *pos)
#endif
/**********************************************************************/
#ifdef L_ftell
-strong_alias(ftell, ftello);
+strong_alias(ftell,ftello);
#endif
#if defined(L_ftell) && defined(__STDIO_LARGE_FILES)
@@ -3042,6 +3148,10 @@ void rewind(register FILE *stream)
__CLEARERR(stream); /* Clear errors first and then seek */
fseek(stream, 0L, SEEK_SET); /* in case there is an error seeking. */
+#ifdef __STDIO_MBSTATE
+ /* TODO: Is it correct to re-init the stream's state? I think so... */
+ __INIT_MBSTATE(&(stream->state));
+#endif /* __STDIO_MBSTATE */
__STDIO_THREADUNLOCK(stream);
}
@@ -3103,11 +3213,11 @@ void perror(register const char *s)
#if 1
#ifdef __STDIO_PRINTF_M_SPEC
- fprintf(_stderr, "%s%s%m\n", s, sep); /* Use the gnu %m feature. */
+ fprintf(stderr, "%s%s%m\n", s, sep); /* Use the gnu %m feature. */
#else
{
char buf[64];
- fprintf(_stderr, "%s%s%s\n", s, sep,
+ fprintf(stderr, "%s%s%s\n", s, sep,
_stdio_strerror_r(errno, buf, sizeof(buf)));
}
#endif
@@ -3135,7 +3245,7 @@ void perror(register const char *s)
void _stdio_fdout(int fd, ...)
{
va_list arg;
- const char *p;
+ register const char *p;
va_start(arg, fd);
while ((p = va_arg(arg, const char *)) != NULL) {
@@ -3154,8 +3264,8 @@ void _stdio_fdout(int fd, ...)
#define INTERNAL_DIV_MOD
#endif
-char *_uintmaxtostr(char * __restrict bufend, uintmax_t uval,
- int base, __UIM_CASE alphacase)
+char *_uintmaxtostr(register char * __restrict bufend, uintmax_t uval,
+ int base, __UIM_CASE alphacase)
{
int negative;
unsigned int digit;
@@ -3231,7 +3341,7 @@ char *_uintmaxtostr(char * __restrict bufend, uintmax_t uval,
static const char unknown[] = "Unknown error";
-char *_stdio_strerror_r(int err, char *buf, size_t buflen)
+char *_stdio_strerror_r(int err, register char *buf, size_t buflen)
{
int errsave;