diff options
author | Anton Kling <anton@kling.gg> | 2024-11-23 14:59:26 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-11-23 16:31:25 +0100 |
commit | 934c30d35a3ca0e0bf6cd8709d779e060e27f6d2 (patch) | |
tree | b2d5df8919b7bf721b9901b56cccad3f3d1644e0 /userland/libc/stdio/fopen.c | |
parent | 2dce92236b9fe0a9398287ac7c62f2f4e67d53b6 (diff) |
libc: Add append to f(d)open and other fixes
Diffstat (limited to 'userland/libc/stdio/fopen.c')
-rw-r--r-- | userland/libc/stdio/fopen.c | 49 |
1 files changed, 16 insertions, 33 deletions
diff --git a/userland/libc/stdio/fopen.c b/userland/libc/stdio/fopen.c index 52e78d1..fe0b5cf 100644 --- a/userland/libc/stdio/fopen.c +++ b/userland/libc/stdio/fopen.c @@ -1,16 +1,10 @@ #include <fcntl.h> -#include <stdint.h> #include <stdio.h> -#include <stdlib.h> -#include <sys/stat.h> +#include <unistd.h> -// FIXME: All modes not implemented // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html FILE *fopen(const char *pathname, const char *mode) { - uint8_t read = 0; - uint8_t write = 0; -// uint8_t append = 0; - // FIXME: Not parsed correctly + int flag = 0; for (; *mode; mode++) { // r or rb // Open file for reading. @@ -21,41 +15,30 @@ FILE *fopen(const char *pathname, const char *mode) { // end-of-file. switch (*mode) { case 'r': - read = 1; + flag |= O_READ; break; case 'w': - write = 1; + flag |= O_WRITE; break; case 'a': -// append = 1; + flag |= O_APPEND; break; } } - int flag = 0; - if (read) - flag |= O_READ; - if (write) - flag |= O_WRITE; int fd = open(pathname, flag, 0); - if (-1 == fd) + if (-1 == fd) { return NULL; + } - struct stat s; - stat(pathname, &s); - - FILE *r = calloc(1, sizeof(FILE)); - r->read = read_fd; - r->write = write_fd; - r->seek = seek_fd; - r->has_error = 0; - r->is_eof = 0; - r->offset_in_file = 0; - r->file_size = s.st_size; - r->cookie = NULL; - r->fd = fd; - r->read_buffer = NULL; - r->read_buffer_stored = 0; - r->fflush = fflush_fd; + FILE *r = fdopen(fd, mode); + if (!r) { + close(fd); + return NULL; + } + if(flag & O_WRITE) { + ftruncate(fd, 0); + } + r->has_control_over_the_fd = 1; return r; } |