summaryrefslogtreecommitdiff
path: root/src/user
diff options
context:
space:
mode:
authordzwdz2022-08-05 19:54:22 +0200
committerdzwdz2022-08-05 19:54:22 +0200
commit4fcff0ecc6f94dbc079f29b9636d810a16ef2ed7 (patch)
tree1ae354131b7bffd2b3f7a671f78cd31371b261c8 /src/user
parent99e15199ef24d4f262683b47a529f1b239c4dcd9 (diff)
user/libc: fseek + ftell for getting a file's size
Diffstat (limited to 'src/user')
-rw-r--r--src/user/app/vterm/font.c17
-rw-r--r--src/user/lib/elfload.c14
-rw-r--r--src/user/lib/file.c27
-rw-r--r--src/user/lib/include/stdio.h1
4 files changed, 45 insertions, 14 deletions
diff --git a/src/user/app/vterm/font.c b/src/user/app/vterm/font.c
index d9a4e3c..5a9dd24 100644
--- a/src/user/app/vterm/font.c
+++ b/src/user/app/vterm/font.c
@@ -13,13 +13,24 @@ void font_load(const char *path) {
exit(1);
}
- const size_t cap = 8 * 1024; // TODO get file size
- void *buf = malloc(cap);
+ void *buf;
+ long buflen;
+
+ fseek(f, 0, SEEK_END);
+ buflen = ftell(f);
+ if (buflen < 0) {
+ eprintf("can't get the size of \"%s\"", path);
+ exit(1);
+ }
+
+ buf = malloc(buflen);
if (!buf) {
eprintf("out of memory");
exit(1);
}
- fread(buf, 1, cap, f);
+
+ fseek(f, 0, SEEK_SET);
+ fread(buf, 1, buflen, f);
if (ferror(f)) {
eprintf("error reading file");
exit(1);
diff --git a/src/user/lib/elfload.c b/src/user/lib/elfload.c
index e3853ba..7c84f45 100644
--- a/src/user/lib/elfload.c
+++ b/src/user/lib/elfload.c
@@ -9,11 +9,17 @@
#include <user/lib/elfload.h>
void elf_execf(FILE *f, char **argv, char **envp) {
- const size_t cap = 0x60000;
- size_t pos = 0;
- void *buf = malloc(cap); // TODO a way to get file size
+ void *buf;
+ long buflen;
- if (buf && fread(buf, 1, cap - pos, f))
+ fseek(f, 0, SEEK_END);
+ buflen = ftell(f);
+ if (buflen < 0) return; /* errno set by fseek */
+ buf = malloc(buflen);
+
+ // TODO don't read the entire file into memory
+ fseek(f, 0, SEEK_SET);
+ if (buf && fread(buf, 1, buflen, f))
elf_exec(buf, argv, envp);
free(buf);
}
diff --git a/src/user/lib/file.c b/src/user/lib/file.c
index 84242b2..942b522 100644
--- a/src/user/lib/file.c
+++ b/src/user/lib/file.c
@@ -175,31 +175,44 @@ int fseek(FILE *f, long offset, int whence) {
if (fflush(f))
return -1;
+ long base;
switch (whence) {
case SEEK_SET:
- f->pos = 0;
+ base = 0;
break;
case SEEK_CUR:
+ base = f->pos;
break;
case SEEK_END:
- f->pos = -1;
+ base = _syscall_getsize(f->fd);
+ if (base < 0)
+ base = -1;
break;
default:
errno = EINVAL;
return -1;
}
- bool pos_neg = f->pos < 0;
- f->pos += offset;
- if (pos_neg && f->pos >= 0) {
- // TODO getting the file size
- errno = ENOSYS;
+ if (base >= 0 && base + offset < 0) {
+ /* underflow */
+ errno = EINVAL;
+ return -1;
+ } else if (base < 0 && base + offset >= 0) {
+ /* overflow - went from a negative offset (relative to EOF)
+ * to a positive offset (from start of file).
+ * can only happen when getsize() is unsupported */
+ errno = EINVAL;
return -1;
}
+ f->pos = base + offset;
f->eof = false;
return 0;
}
+long ftell(FILE *f) {
+ return f->pos;
+}
+
int fclose(FILE *f) {
fflush(f);
if (f->fd > 0) close(f->fd);
diff --git a/src/user/lib/include/stdio.h b/src/user/lib/include/stdio.h
index 74c5230..063c81f 100644
--- a/src/user/lib/include/stdio.h
+++ b/src/user/lib/include/stdio.h
@@ -33,6 +33,7 @@ size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict);
size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict);
char *fgets(char *buf, int size, FILE *f);
int fseek(FILE *f, long offset, int whence);
+long ftell(FILE *f);
int feof(FILE *);
int ferror(FILE *);