summaryrefslogtreecommitdiff
path: root/src/user/lib
diff options
context:
space:
mode:
authordzwdz2022-07-26 20:40:29 +0200
committerdzwdz2022-07-26 20:44:29 +0200
commit599c916d4cdd06765e0869b0a4d685820384f500 (patch)
tree7355c35189a4b6e92249f59c76e6d89d5b432f29 /src/user/lib
parent350124fb4cfefc90c8f4a60de3da3c5d7da44f01 (diff)
user: posix-compatible FILE* opening
Diffstat (limited to 'src/user/lib')
-rw-r--r--src/user/lib/elfload.c2
-rw-r--r--src/user/lib/elfload.h2
-rw-r--r--src/user/lib/include/bits/file.h4
-rw-r--r--src/user/lib/include/errno.h3
-rw-r--r--src/user/lib/include/stdio.h14
-rw-r--r--src/user/lib/malloc.c2
-rw-r--r--src/user/lib/stdlib.c52
7 files changed, 49 insertions, 30 deletions
diff --git a/src/user/lib/elfload.c b/src/user/lib/elfload.c
index a30fd7c..75c1162 100644
--- a/src/user/lib/elfload.c
+++ b/src/user/lib/elfload.c
@@ -7,7 +7,7 @@
#include <user/lib/elf.h>
#include <user/lib/elfload.h>
-void elf_execf(libc_file *f) {
+void elf_execf(FILE *f) {
const size_t cap = 0x60000;
size_t pos = 0;
void *buf = malloc(cap); // TODO a way to get file size
diff --git a/src/user/lib/elfload.h b/src/user/lib/elfload.h
index 8310b3f..d0fb29d 100644
--- a/src/user/lib/elfload.h
+++ b/src/user/lib/elfload.h
@@ -1,7 +1,7 @@
#pragma once
#include <bits/file.h>
-void elf_execf(libc_file *f);
+void elf_execf(FILE *f);
void elf_exec(void *elf);
void *elf_partialexec(void *elf); /* returns pointer to entry point */
diff --git a/src/user/lib/include/bits/file.h b/src/user/lib/include/bits/file.h
index d37b7de..74a8c17 100644
--- a/src/user/lib/include/bits/file.h
+++ b/src/user/lib/include/bits/file.h
@@ -1,9 +1,9 @@
#pragma once
#include <stdbool.h>
// TODO make opaque
-struct libc_file {
+struct FILE {
int fd;
int pos;
bool eof;
};
-typedef struct libc_file libc_file;
+typedef struct FILE FILE;
diff --git a/src/user/lib/include/errno.h b/src/user/lib/include/errno.h
new file mode 100644
index 0000000..6686a01
--- /dev/null
+++ b/src/user/lib/include/errno.h
@@ -0,0 +1,3 @@
+#pragma once
+#include <camellia/errno.h>
+extern int errno;
diff --git a/src/user/lib/include/stdio.h b/src/user/lib/include/stdio.h
index 291a194..2b1d8ed 100644
--- a/src/user/lib/include/stdio.h
+++ b/src/user/lib/include/stdio.h
@@ -8,11 +8,11 @@ int snprintf(char *str, size_t len, const char *fmt, ...);
int _klogf(const char *fmt, ...); // for kernel debugging only
-extern libc_file *const stdin, *const stdout;
+extern FILE *const stdin, *const stdout;
-libc_file *file_open(const char *path, int flags);
-libc_file *file_reopen(libc_file*, const char *path, int flags);
-libc_file *file_clone(const libc_file*);
-int file_read(libc_file*, char *buf, size_t len);
-int file_write(libc_file*, const char *buf, size_t len);
-void file_close(libc_file*);
+FILE *fopen(const char *path, const char *mode);
+FILE *freopen(const char *path, const char *mode, FILE*);
+FILE *file_clone(const FILE*);
+int file_read(FILE*, char *buf, size_t len);
+int file_write(FILE*, const char *buf, size_t len);
+void file_close(FILE*);
diff --git a/src/user/lib/malloc.c b/src/user/lib/malloc.c
index ea65d74..b732df9 100644
--- a/src/user/lib/malloc.c
+++ b/src/user/lib/malloc.c
@@ -26,7 +26,7 @@ void *malloc(size_t size) {
}
if (!iter) iter = expand(size);
- if (!iter) return NULL;
+ if (!iter) return NULL; // TODO set errno
iter->used = true;
// TODO truncate and split
diff --git a/src/user/lib/stdlib.c b/src/user/lib/stdlib.c
index c998de7..af653bb 100644
--- a/src/user/lib/stdlib.c
+++ b/src/user/lib/stdlib.c
@@ -1,4 +1,5 @@
#include <camellia/syscalls.h>
+#include <errno.h>
#include <shared/printf.h>
#include <stdio.h>
#include <stdlib.h>
@@ -6,13 +7,15 @@
#include <unistd.h>
// TODO oh god this garbage - malloc, actually open, [...]
-static libc_file _stdin_null = { .fd = 0 };
-static libc_file _stdout_null = { .fd = 1 };
+static FILE _stdin_null = { .fd = 0 };
+static FILE _stdout_null = { .fd = 1 };
-libc_file *const stdin = &_stdin_null, *const stdout = &_stdout_null;
+FILE *const stdin = &_stdin_null, *const stdout = &_stdout_null;
+
+int errno = 0;
static void backend_file(void *arg, const char *buf, size_t len) {
- file_write((libc_file*)arg, buf, len);
+ file_write((FILE*)arg, buf, len);
}
int printf(const char *fmt, ...) {
@@ -58,30 +61,38 @@ int _klogf(const char *fmt, ...) {
}
-libc_file *file_open(const char *path, int flags) {
- handle_t h = _syscall_open(path, strlen(path), flags);
- libc_file *f;
- if (h < 0) return NULL;
+FILE *fopen(const char *path, const char *mode) {
+ FILE *f;
+ handle_t h;
+ int flags = 0;
+ if (mode[0] == 'w' || mode[0] == 'a')
+ flags |= OPEN_CREATE;
+ // TODO truncate on w
+
+ h = _syscall_open(path, strlen(path), flags);
+ if (h < 0) {
+ errno = -h;
+ return NULL;
+ }
f = malloc(sizeof *f);
if (!f) {
close(h);
return NULL;
}
- f->pos = 0;
+ f->pos = mode[0] == 'a' ? -1 : 0;
f->eof = false;
f->fd = h;
return f;
}
-libc_file *file_reopen(libc_file *f, const char *path, int flags) {
+ FILE *freopen(const char *path, const char *mode, FILE *f) {
/* partially based on the musl implementation of freopen */
- libc_file *f2;
+ FILE *f2;
if (!path) goto fail;
- f2 = file_open(path, flags);
+ f2 = fopen(path, mode);
if (!f2) goto fail;
- /* shouldn't happen, but if it happens, let's roll with it. */
if (f->fd == f2->fd) f2->fd = -1;
if (_syscall_dup(f2->fd, f->fd, 0) < 0) goto fail2;
@@ -97,9 +108,9 @@ fail:
return NULL;
}
-libc_file *file_clone(const libc_file *f) {
+FILE *file_clone(const FILE *f) {
handle_t h = _syscall_dup(f->fd, -1, 0);
- libc_file *f2;
+ FILE *f2;
if (h < 0) return NULL;
// TODO file_wrapfd
@@ -114,17 +125,22 @@ libc_file *file_clone(const libc_file *f) {
return f2;
}
-int file_read(libc_file *f, char *buf, size_t len) {
+int file_read(FILE *f, char *buf, size_t len) {
if (f->fd < 0) return -1;
int res = _syscall_read(f->fd, buf, len, f->pos);
if (res < 0) return res;
if (res == 0 && len > 0) f->eof = true;
+
+ bool negative_pos = f->pos < 0;
f->pos += res;
+ if (negative_pos && f->pos >= 0)
+ f->pos = -1;
+
return res;
}
-int file_write(libc_file *f, const char *buf, size_t len) {
+int file_write(FILE *f, const char *buf, size_t len) {
if (f->fd < 0) return -1;
int res = _syscall_write(f->fd, buf, len, f->pos);
@@ -133,7 +149,7 @@ int file_write(libc_file *f, const char *buf, size_t len) {
return res;
}
-void file_close(libc_file *f) {
+void file_close(FILE *f) {
if (f->fd > 0) close(f->fd);
if (f != &_stdin_null && f != &_stdout_null)
free(f);