summaryrefslogtreecommitdiff
path: root/userland/libc/stdio
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-11-23 14:59:26 +0100
committerAnton Kling <anton@kling.gg>2024-11-23 16:31:25 +0100
commit934c30d35a3ca0e0bf6cd8709d779e060e27f6d2 (patch)
treeb2d5df8919b7bf721b9901b56cccad3f3d1644e0 /userland/libc/stdio
parent2dce92236b9fe0a9398287ac7c62f2f4e67d53b6 (diff)
libc: Add append to f(d)open and other fixes
Diffstat (limited to 'userland/libc/stdio')
-rw-r--r--userland/libc/stdio/fclose.c4
-rw-r--r--userland/libc/stdio/fopen.c49
-rw-r--r--userland/libc/stdio/fwrite.c5
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);