From: John Hodge (sonata) Date: Sat, 19 Jan 2013 15:52:40 +0000 (+0800) Subject: Usermode/libc - scanf/stdio fixes X-Git-Tag: rel0.15~598^2~35 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=375362e388e5bc180ee867cb7dde21a9430c14cf;p=tpg%2Facess2.git Usermode/libc - scanf/stdio fixes --- diff --git a/Usermode/Libraries/libc.so_src/scanf.c b/Usermode/Libraries/libc.so_src/scanf.c index 6a1d584f..3d45ed13 100644 --- a/Usermode/Libraries/libc.so_src/scanf.c +++ b/Usermode/Libraries/libc.so_src/scanf.c @@ -152,6 +152,8 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char // int offset = -1; enum e_vcscanf_sizes size = _VCSCANF_UNDEF; enum e_vcscanf_types valtype; + int fail = 0; + int nnewch; const char *set_start; int set_len; @@ -161,6 +163,7 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char { while( (ich = __getc(h)) && isspace(ich) ) nch ++; + if(ich) __rewind(h); continue ; } @@ -262,22 +265,30 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char { // Decimal integer case 'd': - nch += _vcscanf_int(__getc, __rewind, h, 10, maxlen, &ival); + nnewch = _vcscanf_int(__getc, __rewind, h, 10, maxlen, &ival); + if(nnewch==0) fail=1; + nch += nnewch; valtype = _VCSCANF_INT; break; // variable-base integer case 'i': - nch += _vcscanf_int(__getc, __rewind, h, 0, maxlen, &ival); + nnewch = _vcscanf_int(__getc, __rewind, h, 0, maxlen, &ival); + if(nnewch==0) fail=1; + nch += nnewch; valtype = _VCSCANF_INT; break; // Octal integer case 'o': - nch += _vcscanf_int(__getc, __rewind, h, 8, maxlen, &ival); + nnewch = _vcscanf_int(__getc, __rewind, h, 8, maxlen, &ival); + if(nnewch==0) fail=1; + nch += nnewch; valtype = _VCSCANF_INT; break; // Hexadecimal integer case 'x': case 'X': - nch += _vcscanf_int(__getc, __rewind, h, 16, maxlen, &ival); + nnewch = _vcscanf_int(__getc, __rewind, h, 16, maxlen, &ival); + if(nnewch==0) fail=1; + nch += nnewch; valtype = _VCSCANF_INT; break; // strtod format float @@ -304,13 +315,14 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char maxlen = -1; ich = 0; - while( maxlen -- && (ich = __getc(h)) && !isblank(ich) ) + while( maxlen -- && (ich = __getc(h)) && !isspace(ich) ) { if(ptr._char) *ptr._char++ = ich; nch ++; } if( maxlen >= 0 && ich ) __rewind(h); + if(ptr._char) *ptr._char++ = 0; valtype = _VCSCANF_NOTYPE; break; // match a set of characters @@ -329,6 +341,8 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char fch = *format++; } while( fch && fch != ']' ); + if( maxlen == 0 ) + maxlen = -1; ich = 0; while( maxlen -- && (ich = __getc(h)) && memchr(set_start, set_len, ich) ) { @@ -337,6 +351,7 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char } if( maxlen >= 0 && ich ) __rewind(h); + if(ptr._char) *ptr._char++ = 0; valtype = _VCSCANF_NOTYPE; break; case 'p': // read back printf("%p") @@ -354,7 +369,10 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char valtype = _VCSCANF_NOTYPE; break; } - + + if(fail) + break; + switch(valtype) { case _VCSCANF_NOTYPE: @@ -406,7 +424,8 @@ int vsscanf(const char *str, const char *format, va_list ap) int _vfscanf_getc(void *h) { - return fgetc(h); // TODO: Handle -1 -> 0 + int ch = fgetc(h); + return ch == -1 ? 0 : ch; } void _vfscanf_rewind(void *h) { diff --git a/Usermode/Libraries/libc.so_src/stdio.c b/Usermode/Libraries/libc.so_src/stdio.c index 840e24d4..17bdf49e 100644 --- a/Usermode/Libraries/libc.so_src/stdio.c +++ b/Usermode/Libraries/libc.so_src/stdio.c @@ -348,6 +348,12 @@ EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp) } else { ret = _SysRead(fp->FD, ptr, size*num); + if( ret == (size_t)-1) + return -1; + if( ret == 0 && size*num > 0 ) { + fp->Flags |= FILE_FLAG_EOF; + return 0; + } ret /= size; } @@ -403,7 +409,7 @@ EXPORT int putchar(int c) EXPORT int fgetc(FILE *fp) { char ret = 0; - if( fread(&ret, 1, 1, fp) == (size_t)-1 ) + if( fread(&ret, 1, 1, fp) != 1 ) return -1; return ret; }