Fix EOF error in fgetc, fix ungetc=0 in stdin
This commit is contained in:
+44
-5
@@ -1,13 +1,52 @@
|
||||
#include <_libc/stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int __libc_vscanf(const char *format,
|
||||
void *ctx,
|
||||
int (*in)(void *ctx),
|
||||
va_list ap) {
|
||||
(void) format;
|
||||
(void) ctx;
|
||||
(void) in;
|
||||
(void) ap;
|
||||
return -1;
|
||||
size_t n_convert = 0;
|
||||
union {
|
||||
uint64_t value_unsigned;
|
||||
} pv;
|
||||
char ch;
|
||||
int ic;
|
||||
|
||||
while ((ch = *format)) {
|
||||
if (isspace(ch)) {
|
||||
// Skip whitespace
|
||||
} else if (ch == '%') {
|
||||
// Conversion spec
|
||||
ch = *++format;
|
||||
|
||||
switch (ch) {
|
||||
case 'u':
|
||||
pv.value_unsigned = 0;
|
||||
while ((ic = in(ctx)) != EOF && isdigit(ic)) {
|
||||
pv.value_unsigned *= 10;
|
||||
pv.value_unsigned += ic - '0';
|
||||
}
|
||||
*((unsigned int *) va_arg(ap, unsigned int *)) = pv.value_unsigned;
|
||||
++n_convert;
|
||||
++format;
|
||||
break;
|
||||
default:
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
ic = in(ctx);
|
||||
|
||||
if (ic == EOF) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
++format;
|
||||
}
|
||||
|
||||
err:
|
||||
if (!n_convert) {
|
||||
return -1;
|
||||
}
|
||||
return n_convert;
|
||||
}
|
||||
|
||||
@@ -12,12 +12,12 @@ int fgetc_unlocked(FILE *fp) {
|
||||
}
|
||||
|
||||
if (fp->flags & FILE_FLAG_EOF) {
|
||||
return 0;
|
||||
return EOF;
|
||||
}
|
||||
if (!(fp->flags & FILE_MODE_READ)) {
|
||||
errno = EBADF;
|
||||
fp->flags |= FILE_FLAG_ERROR;
|
||||
return 0;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
__libc_file_flush_write(fp);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <sys/debug.h>
|
||||
#include <stdio.h>
|
||||
|
||||
char *fgets_unlocked(char *buf, int len, FILE *fp) {
|
||||
@@ -23,7 +24,11 @@ char *fgets_unlocked(char *buf, int len, FILE *fp) {
|
||||
}
|
||||
|
||||
if (off) {
|
||||
ygg_debug_trace("fgets -> %d\n", off);
|
||||
buf[off] = 0;
|
||||
for (size_t i = 0; i < off; ++i) {
|
||||
ygg_debug_trace("buf[%d] = 0x%x\n", i, buf[i]);
|
||||
}
|
||||
return buf;
|
||||
} else {
|
||||
return NULL;
|
||||
|
||||
+2
-2
@@ -20,6 +20,7 @@ FILE *__libc_file_create(void) {
|
||||
|
||||
res->free = file_default_free;
|
||||
res->buf = ((void *) res) + sizeof(FILE);
|
||||
res->ungetc = -1;
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -43,9 +44,8 @@ int __libc_file_mode(const char *mode) {
|
||||
}
|
||||
|
||||
int __libc_file_flush_read(FILE *fp) {
|
||||
fp->ungetc = -1;
|
||||
if ((fp->flags & FILE_MODE_READ) && fp->seek) {
|
||||
// Flush ungetc buffer
|
||||
fp->ungetc = -1;
|
||||
// TODO: off_t
|
||||
long count = fp->rdbuf - fp->rdbufpos;
|
||||
if (count < 0) {
|
||||
|
||||
@@ -17,6 +17,7 @@ FILE _stdin = {
|
||||
.buf_mode = _IOLBF,
|
||||
.ctx = &_stdin,
|
||||
.fd = STDIN_FILENO,
|
||||
.ungetc = -1,
|
||||
.free = NULL,
|
||||
.read = file_read,
|
||||
.write = file_write,
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int puts(const char *s) {
|
||||
flockfile(stdout);
|
||||
if (fputs(s, stdout) != 0) {
|
||||
funlockfile(stdout);
|
||||
return EOF;
|
||||
}
|
||||
if (fputc('\n', stdout) == EOF) {
|
||||
funlockfile(stdout);
|
||||
return EOF;
|
||||
}
|
||||
funlockfile(stdout);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user