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 | |
parent | 2dce92236b9fe0a9398287ac7c62f2f4e67d53b6 (diff) |
libc: Add append to f(d)open and other fixes
Diffstat (limited to 'userland/libc/stdio')
-rw-r--r-- | userland/libc/stdio/fclose.c | 4 | ||||
-rw-r--r-- | userland/libc/stdio/fopen.c | 49 | ||||
-rw-r--r-- | userland/libc/stdio/fwrite.c | 5 |
3 files changed, 25 insertions, 33 deletions
diff --git a/userland/libc/stdio/fclose.c b/userland/libc/stdio/fclose.c index eb92387..5d66830 100644 --- a/userland/libc/stdio/fclose.c +++ b/userland/libc/stdio/fclose.c @@ -1,5 +1,6 @@ #include <stdio.h> #include <stdlib.h> +#include <unistd.h> // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fclose.html // FIXME: Do some actual error checking. @@ -8,6 +9,9 @@ int fclose(FILE *stream) { if (stream->fflush) { stream->fflush(stream); } + if (stream->has_control_over_the_fd) { + close(stream->fd); + } free(stream->cookie); } free(stream); 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; } diff --git a/userland/libc/stdio/fwrite.c b/userland/libc/stdio/fwrite.c index 6499529..d2086cb 100644 --- a/userland/libc/stdio/fwrite.c +++ b/userland/libc/stdio/fwrite.c @@ -2,6 +2,11 @@ #include <sys/types.h> size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { + if (!stream->has_control_over_the_fd) { + if (stream->append) { + fseek(stream, 0, SEEK_END); + } + } // FIXME: Check for overflow size_t bytes_to_write = nmemb * size; size_t rc = stream->write(stream, ptr, bytes_to_write); |