diff options
Diffstat (limited to 'src/stdio')
-rw-r--r-- | src/stdio/pclose.c | 2 | ||||
-rw-r--r-- | src/stdio/vfprintf.c | 45 | ||||
-rw-r--r-- | src/stdio/vfwprintf.c | 43 | ||||
-rw-r--r-- | src/stdio/vsnprintf.c | 5 | ||||
-rw-r--r-- | src/stdio/vswprintf.c | 4 |
5 files changed, 50 insertions, 49 deletions
diff --git a/src/stdio/pclose.c b/src/stdio/pclose.c index 080a4262..c64da405 100644 --- a/src/stdio/pclose.c +++ b/src/stdio/pclose.c @@ -7,7 +7,7 @@ int pclose(FILE *f) int status, r; pid_t pid = f->pipe_pid; fclose(f); - while ((r=__syscall(SYS_wait4, pid, &status, 0, 0)) == -EINTR); + while ((r=__sys_wait4(pid, &status, 0, 0)) == -EINTR); if (r<0) return __syscall_ret(r); return status; } diff --git a/src/stdio/vfprintf.c b/src/stdio/vfprintf.c index 9b961e7f..360d723a 100644 --- a/src/stdio/vfprintf.c +++ b/src/stdio/vfprintf.c @@ -52,7 +52,7 @@ static const unsigned char states[]['z'-'A'+1] = { S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT, S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL, S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL, - S('c') = CHAR, S('C') = INT, + S('c') = INT, S('C') = UINT, S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR, S('m') = NOARG, S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE, @@ -62,7 +62,7 @@ static const unsigned char states[]['z'-'A'+1] = { S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG, S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL, S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL, - S('c') = INT, S('s') = PTR, S('n') = PTR, + S('c') = UINT, S('s') = PTR, S('n') = PTR, S('l') = LLPRE, }, { /* 2: ll-prefixed */ S('d') = LLONG, S('i') = LLONG, @@ -132,7 +132,7 @@ static void pop_arg(union arg *arg, int type, va_list *ap) static void out(FILE *f, const char *s, size_t l) { - if (!(f->flags & F_ERR)) __fwritex((void *)s, l, f); + if (!ferror(f)) __fwritex((void *)s, l, f); } static void pad(FILE *f, char c, int w, int l, int fl) @@ -166,7 +166,8 @@ static char *fmt_u(uintmax_t x, char *s) { unsigned long y; for ( ; x>ULONG_MAX; x/=10) *--s = '0' + x%10; - for (y=x; y; y/=10) *--s = '0' + y%10; + for (y=x; y>=10; y/=10) *--s = '0' + y%10; + if (y) *--s = '0' + y; return s; } @@ -211,18 +212,11 @@ static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t) if (y) e2--; if ((t|32)=='a') { - long double round = 8.0; - int re; - if (t&32) prefix += 9; pl += 2; - if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0; - else re=LDBL_MANT_DIG/4-1-p; - - if (re) { - round *= 1<<(LDBL_MANT_DIG%4); - while (re--) round*=16; + if (p>=0 && p<(LDBL_MANT_DIG-1+3)/4) { + double round = scalbn(1, LDBL_MANT_DIG-1-(p*4)); if (*prefix=='-') { y=-y; y-=round; @@ -437,7 +431,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, unsigned st, ps; int cnt=0, l=0; size_t i; - char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4]; + char buf[sizeof(uintmax_t)*3]; const char *prefix; int t, pl; wchar_t wc[2], *ws; @@ -478,8 +472,8 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, if (*s=='*') { if (isdigit(s[1]) && s[2]=='$') { l10n=1; - nl_type[s[1]-'0'] = INT; - w = nl_arg[s[1]-'0'].i; + if (!f) nl_type[s[1]-'0'] = INT, w = 0; + else w = nl_arg[s[1]-'0'].i; s+=3; } else if (!l10n) { w = f ? va_arg(*ap, int) : 0; @@ -491,8 +485,8 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, /* Read precision */ if (*s=='.' && s[1]=='*') { if (isdigit(s[2]) && s[3]=='$') { - nl_type[s[2]-'0'] = INT; - p = nl_arg[s[2]-'0'].i; + if (!f) nl_type[s[2]-'0'] = INT, p = 0; + else p = nl_arg[s[2]-'0'].i; s+=4; } else if (!l10n) { p = f ? va_arg(*ap, int) : 0; @@ -521,13 +515,18 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, if (st==NOARG) { if (argpos>=0) goto inval; } else { - if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos]; - else if (f) pop_arg(&arg, st, ap); + if (argpos>=0) { + if (!f) nl_type[argpos]=st; + else arg=nl_arg[argpos]; + } else if (f) pop_arg(&arg, st, ap); else return 0; } if (!f) continue; + /* Do not process any new directives once in error state. */ + if (ferror(f)) return -1; + z = buf + sizeof(buf); prefix = "-+ 0X0x"; pl = 0; @@ -583,6 +582,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, } p = MAX(p, z-a + !arg.i); break; + narrow_c: case 'c': *(a=z-(p=1))=arg.i; fl &= ~ZERO_PAD; @@ -597,6 +597,7 @@ static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, fl &= ~ZERO_PAD; break; case 'C': + if (!arg.i) goto narrow_c; wc[0] = arg.i; wc[1] = 0; arg.p = wc; @@ -672,7 +673,7 @@ int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) FLOCK(f); olderr = f->flags & F_ERR; - if (f->mode < 1) f->flags &= ~F_ERR; + f->flags &= ~F_ERR; if (!f->buf_size) { saved_buf = f->buf; f->buf = internal_buf; @@ -688,7 +689,7 @@ int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap) f->buf_size = 0; f->wpos = f->wbase = f->wend = 0; } - if (f->flags & F_ERR) ret = -1; + if (ferror(f)) ret = -1; f->flags |= olderr; FUNLOCK(f); va_end(ap2); diff --git a/src/stdio/vfwprintf.c b/src/stdio/vfwprintf.c index 85b036c3..59d5471b 100644 --- a/src/stdio/vfwprintf.c +++ b/src/stdio/vfwprintf.c @@ -45,7 +45,7 @@ static const unsigned char states[]['z'-'A'+1] = { S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT, S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL, S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL, - S('c') = CHAR, S('C') = INT, + S('c') = INT, S('C') = UINT, S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR, S('m') = NOARG, S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE, @@ -55,7 +55,7 @@ static const unsigned char states[]['z'-'A'+1] = { S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG, S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL, S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL, - S('c') = INT, S('s') = PTR, S('n') = PTR, + S('c') = UINT, S('s') = PTR, S('n') = PTR, S('l') = LLPRE, }, { /* 2: ll-prefixed */ S('d') = LLONG, S('i') = LLONG, @@ -125,7 +125,13 @@ static void pop_arg(union arg *arg, int type, va_list *ap) static void out(FILE *f, const wchar_t *s, size_t l) { - while (l-- && !(f->flags & F_ERR)) fputwc(*s++, f); + while (l-- && !ferror(f)) fputwc(*s++, f); +} + +static void pad(FILE *f, int n, int fl) +{ + if ((fl & LEFT_ADJ) || !n || ferror(f)) return; + fprintf(f, "%*s", n, ""); } static int getint(wchar_t **s) { @@ -242,6 +248,10 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_ } if (!f) continue; + + /* Do not process any new directives once in error state. */ + if (ferror(f)) return -1; + t = s[-1]; if (ps && (t&15)==3) t&=~32; @@ -258,25 +268,22 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_ } continue; case 'c': + case 'C': if (w<1) w=1; - if (w>1 && !(fl&LEFT_ADJ)) fprintf(f, "%*s", w-1, ""); - fputwc(btowc(arg.i), f); - if (w>1 && (fl&LEFT_ADJ)) fprintf(f, "%*s", w-1, ""); + pad(f, w-1, fl); + out(f, &(wchar_t){t=='C' ? arg.i : btowc(arg.i)}, 1); + pad(f, w-1, fl^LEFT_ADJ); l = w; continue; - case 'C': - fputwc(arg.i, f); - l = 1; - continue; case 'S': a = arg.p; z = a + wcsnlen(a, p<0 ? INT_MAX : p); if (p<0 && *z) goto overflow; p = z-a; if (w<p) w=p; - if (!(fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, ""); + pad(f, w-p, fl); out(f, a, p); - if ((fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, ""); + pad(f, w-p, fl^LEFT_ADJ); l=w; continue; case 'm': @@ -289,14 +296,14 @@ static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_ if (p<0 && *bs) goto overflow; p=l; if (w<p) w=p; - if (!(fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, ""); + pad(f, w-p, fl); bs = arg.p; while (l--) { i=mbtowc(&wc, bs, MB_LEN_MAX); bs+=i; - fputwc(wc, f); + out(f, &wc, 1); } - if ((fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, ""); + pad(f, w-p, fl^LEFT_ADJ); l=w; continue; } @@ -340,8 +347,8 @@ overflow: int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap) { va_list ap2; - int nl_type[NL_ARGMAX] = {0}; - union arg nl_arg[NL_ARGMAX]; + int nl_type[NL_ARGMAX+1] = {0}; + union arg nl_arg[NL_ARGMAX+1]; int olderr; int ret; @@ -357,7 +364,7 @@ int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap) olderr = f->flags & F_ERR; f->flags &= ~F_ERR; ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type); - if (f->flags & F_ERR) ret = -1; + if (ferror(f)) ret = -1; f->flags |= olderr; FUNLOCK(f); va_end(ap2); diff --git a/src/stdio/vsnprintf.c b/src/stdio/vsnprintf.c index b3510a63..409b9c85 100644 --- a/src/stdio/vsnprintf.c +++ b/src/stdio/vsnprintf.c @@ -45,11 +45,6 @@ int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap) .cookie = &c, }; - if (n > INT_MAX) { - errno = EOVERFLOW; - return -1; - } - *c.s = 0; return vfprintf(&f, fmt, ap); } diff --git a/src/stdio/vswprintf.c b/src/stdio/vswprintf.c index 7f98c5c9..5e9a4dad 100644 --- a/src/stdio/vswprintf.c +++ b/src/stdio/vswprintf.c @@ -18,6 +18,7 @@ static size_t sw_write(FILE *f, const unsigned char *s, size_t l) if (s!=f->wbase && sw_write(f, f->wbase, f->wpos-f->wbase)==-1) return -1; while (c->l && l && (i=mbtowc(c->ws, (void *)s, l))>=0) { + if (!i) i=1; s+=i; l-=i; c->l--; @@ -50,9 +51,6 @@ int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_lis if (!n) { return -1; - } else if (n > INT_MAX) { - errno = EOVERFLOW; - return -1; } r = vfwprintf(&f, fmt, ap); sw_write(&f, 0, 0); |