summaryrefslogtreecommitdiff
path: root/userland
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-06-22 21:41:46 +0200
committerAnton Kling <anton@kling.gg>2024-06-22 21:41:46 +0200
commit5fbd9b519e082fc235a8a57c6cf761e6cefbfb62 (patch)
treed9df62f8bf6ed6b17a7b61aa77f61da9d097c5ff /userland
parent5e10cdd5b4aa7486208dd14ebef4254ec5b5d03a (diff)
LibC: Fix bugs relating to fseek
Diffstat (limited to 'userland')
-rw-r--r--userland/libc/stdio/fgetc.c1
-rw-r--r--userland/libc/stdio/fseek.c21
-rw-r--r--userland/libc/stdio/ftell.c2
-rw-r--r--userland/libc/stdio/stdin.c3
-rw-r--r--userland/libc/stdio/ungetc.c1
-rw-r--r--userland/libc/string/sscanf.c36
6 files changed, 41 insertions, 23 deletions
diff --git a/userland/libc/stdio/fgetc.c b/userland/libc/stdio/fgetc.c
index c69211f..afa299f 100644
--- a/userland/libc/stdio/fgetc.c
+++ b/userland/libc/stdio/fgetc.c
@@ -4,6 +4,7 @@
int fgetc(FILE *stream) {
if (stream->has_buffered_char) {
stream->has_buffered_char = 0;
+ fseek(stream, 1, SEEK_CUR);
return stream->buffered_char;
}
char c;
diff --git a/userland/libc/stdio/fseek.c b/userland/libc/stdio/fseek.c
index fb891ec..cbccbb8 100644
--- a/userland/libc/stdio/fseek.c
+++ b/userland/libc/stdio/fseek.c
@@ -1,21 +1,8 @@
-#include <stdio.h>
#include <assert.h>
+#include <stdio.h>
int fseek(FILE *stream, long offset, int whence) {
- return stream->seek(stream, offset, whence);
- /*
- switch (whence) {
- case SEEK_SET:
- stream->offset_in_file = offset;
- break;
- case SEEK_CUR:
- stream->offset_in_file += offset;
- break;
- case SEEK_END:
- // FIXME
- assert(0);
- break;
- }
- // FIXME: Error checking
- return 0;*/
+ stream->read_buffer_stored = 0;
+ assert(stream->seek);
+ return stream->seek(stream, offset, whence);
}
diff --git a/userland/libc/stdio/ftell.c b/userland/libc/stdio/ftell.c
index 35076d0..1729d74 100644
--- a/userland/libc/stdio/ftell.c
+++ b/userland/libc/stdio/ftell.c
@@ -1,5 +1,5 @@
#include <stdio.h>
long ftell(FILE *stream) {
- return stream->offset_in_file;
+ return fseek(stream, 0, SEEK_CUR);
}
diff --git a/userland/libc/stdio/stdin.c b/userland/libc/stdio/stdin.c
index fcfc71e..e497167 100644
--- a/userland/libc/stdio/stdin.c
+++ b/userland/libc/stdio/stdin.c
@@ -71,10 +71,13 @@ size_t read_fd(FILE *f, unsigned char *s, size_t l) {
f->read_buffer_has_read += read_len;
s += read_len;
l -= read_len;
+ lseek(f->fd, read_len, SEEK_CUR);
return read_len + read_fd(f, s, l);
}
if (0 == f->read_buffer_stored) {
+ int offset = lseek(f->fd, 0, SEEK_CUR);
f->read_buffer_stored = non_cache_read_fd(f, f->read_buffer, 4096);
+ lseek(f->fd, offset, SEEK_SET);
f->read_buffer_has_read = 0;
if (0 == f->read_buffer_stored) {
return 0;
diff --git a/userland/libc/stdio/ungetc.c b/userland/libc/stdio/ungetc.c
index 8d649bc..3b93b70 100644
--- a/userland/libc/stdio/ungetc.c
+++ b/userland/libc/stdio/ungetc.c
@@ -5,5 +5,6 @@ int ungetc(int c, FILE *stream) {
return EOF;
stream->buffered_char = c;
stream->has_buffered_char = 1;
+ fseek(stream, -1, SEEK_CUR);
return c;
}
diff --git a/userland/libc/string/sscanf.c b/userland/libc/string/sscanf.c
index 28e1ce1..e1ede63 100644
--- a/userland/libc/string/sscanf.c
+++ b/userland/libc/string/sscanf.c
@@ -150,20 +150,21 @@ int vfscanf(FILE *stream, const char *format, va_list ap) {
struct sscanf_cookie {
const char *s;
+ unsigned long offset;
};
size_t sscanf_read(FILE *f, unsigned char *s, size_t l) {
struct sscanf_cookie *c = f->cookie;
- if (!*(c->s)) {
+ if (!*(c->s + c->offset)) {
return 0;
}
size_t r = 0;
- for (; l && *(c->s); l--, c->s += 1) {
- *s = *(c->s);
+ for (; l && *(c->s); l--, c->offset += 1) {
+ *s = *(c->s + c->offset);
s++;
r++;
}
- if (!(*(c->s)))
+ if (!(*(c->s + c->offset)))
f->is_eof = 1;
/*
memcpy(s, c->s, l);
@@ -171,10 +172,35 @@ size_t sscanf_read(FILE *f, unsigned char *s, size_t l) {
return r;
}
+int sscanf_seek(FILE *stream, long offset, int whence) {
+ struct sscanf_cookie *c = stream->cookie;
+ off_t ret_offset = c->offset;
+ switch (whence) {
+ case SEEK_SET:
+ // TODO: Avoid running past the pointer
+ // Should that even be checked?
+ ret_offset = offset;
+ break;
+ case SEEK_CUR:
+ ret_offset += offset;
+ break;
+ case SEEK_END:
+ for (; *(c->s + ret_offset); ret_offset++)
+ ;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ c->offset = ret_offset;
+ return ret_offset;
+}
+
int vsscanf(const char *s, const char *restrict format, va_list ap) {
- struct sscanf_cookie c = {.s = s};
+ struct sscanf_cookie c = {.s = s, .offset = 0};
FILE f = {
.read = sscanf_read,
+ .seek = sscanf_seek,
.cookie = &c,
.has_buffered_char = 0,
.is_eof = 0,