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 | |
parent | 2dce92236b9fe0a9398287ac7c62f2f4e67d53b6 (diff) |
libc: Add append to f(d)open and other fixes
-rw-r--r-- | userland/libc/Makefile | 6 | ||||
-rw-r--r-- | userland/libc/include/stdio.h | 7 | ||||
-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 |
5 files changed, 35 insertions, 36 deletions
diff --git a/userland/libc/Makefile b/userland/libc/Makefile index a41e8e4..0e56a4a 100644 --- a/userland/libc/Makefile +++ b/userland/libc/Makefile @@ -1,12 +1,12 @@ CC="i686-sb-gcc" AR="i686-sb-ar" AS="i686-sb-as" -CFLAGS = -ggdb -ffreestanding -nostdlib -Ofast -Wall -Wextra -pedantic -Werror -Wimplicit-fallthrough -I./include/ -static -I../../include/ -Wno-int-conversion -Wno-unused-parameter -OBJ=crt0.o libc.o malloc/malloc.o pty.o sys/mman/mmap.o sys/mman/munmap.o memset.o assert.o stdio/snprintf.o stdio/vfprintf.o string/memcpy.o string/memcmp.o string/strcmp.o ubsan.o string/strcpy.o isspace.o stdio/puts.o stdio/putchar.o dirent/opendir.o dirent/readdir.o dirent/closedir.o unistd/getopt.o dirent/scandir.o dirent/alphasort.o stdio/printf.o stdio/vdprintf.o stdio/vprintf.o stdio/dprintf.o stdio/vprintf.o string/strlen.o string/strnlen.o stdio/stdin.o stdio/getchar.o stdio/fgetc.o arpa/inet/htons.o arpa/inet/htonl.o stdio/fread.o stdio/fwrite.o stdio/fopen.o stdio/fclose.o stdio/fseek.o ctype/isascii.o stdio/fprintf.o stdlib/atoi.o stdlib/strtol.o ctype/toupper.o ctype/tolower.o string/strcat.o string/strchr.o string/sscanf.o sys/stat/stat.o stdlib/getenv.o string/strrchr.o stdio/ftell.o stdio/tmpfile.o stdio/fgets.o stdio/feof.o stdio/fscanf.o stdio/ungetc.o string/strncmp.o stdio/fputc.o string/strncpy.o stdio/remove.o stdio/ferror.o stdio/fputs.o stdlib/rand.o stdlib/srand.o unistd/getpid.o stdlib/strtoul.o stdio/fflush.o stdlib/abort.o string/strcspn.o time/localtime.o time/time.o time/clock_gettime.o time/gmtime.o time/strftime.o string/strpbrk.o ctype/isdigit.o ctype/isalpha.o ctype/isxdigit.o ctype/ispunct.o stdio/setvbuf.o stdio/fileno.o stdio/putc.o stdio/sprintf.o stdlib/abs.o string/strspn.o stdlib/qsort.o string/memmove.o setjmp/longjmp.o setjmp/setjmp.o libgen/basename.o string/strdup.o string/strndup.o string/strlcpy.o stdlib/atexit.o stdio/open_memstream.o libgen/dirname.o unistd/unlink.o string/strstr.o string/strcasecmp.o string/strncasecmp.o stdlib/mkstemp.o string/strtok.o unistd/execvp.o unistd/_exit.o ctype/isalnum.o time/ctime_r.o stdlib/strtold.o sys/time/gettimeofday.o stdio/fgetpos.o stdio/fsetpos.o ctype/isprint.o stdlib/system.o stdio/tmpnam.o unistd/msleep.o stdlib/atof.o stdlib/strtod.o stdio/rename.o sys/stat/mkdir.o unistd/uptime.o unistd/ftruncate.o sys/socket/recvfrom.o sys/socket/sendto.o signal/kill.o signal/sigaction.o unistd/chdir.o unistd/getcwd.o stdio/getdelim.o stdio/getline.o unistd/isatty.o sys/socket/listen.o stdlib/realpath.o systemcall.o sys/random/randomfill.o fcntl/open.o unistd/write.o unistd/pwrite.o fcntl/open_process.o tb/sb.o tb/sv.o string/memchr.o stdlib/atol.o stdlib/atoll.o stdlib/strtoll.o sys/stat/fstat.o unistd/lseek.o ctype/isupper.o ctype/islower.o ctype/isblank.o ctype/isgraph.o ctype/iscntrl.o math/ldexp.o sys/socket/connect.o sys/socket/setsockopt.o arpa/inet/ntohl.o arpa/inet/ntohs.o netdb/getaddrinfo.o tb/sha1.o sys/socket/getpeername.o fcntl/fcntl.o queue.o sys/sendfile.o +CFLAGS = -ggdb -ffreestanding -O2 -Wall -Wextra -pedantic -Werror -Wimplicit-fallthrough -I./include/ -static -I../../include/ -Wno-int-conversion -Wno-unused-parameter +OBJ=crt0.o libc.o malloc/malloc.o pty.o sys/mman/mmap.o sys/mman/munmap.o memset.o assert.o stdio/snprintf.o stdio/vfprintf.o string/memcpy.o string/memcmp.o string/strcmp.o ubsan.o string/strcpy.o isspace.o stdio/puts.o stdio/putchar.o dirent/opendir.o dirent/readdir.o dirent/closedir.o unistd/getopt.o dirent/scandir.o dirent/alphasort.o stdio/printf.o stdio/vdprintf.o stdio/vprintf.o stdio/dprintf.o stdio/vprintf.o string/strlen.o string/strnlen.o stdio/stdin.o stdio/getchar.o stdio/fgetc.o arpa/inet/htons.o arpa/inet/htonl.o stdio/fread.o stdio/fwrite.o stdio/fopen.o stdio/fclose.o stdio/fseek.o ctype/isascii.o stdio/fprintf.o stdlib/atoi.o stdlib/strtol.o ctype/toupper.o ctype/tolower.o string/strcat.o string/strchr.o string/sscanf.o sys/stat/stat.o stdlib/getenv.o string/strrchr.o stdio/ftell.o stdio/tmpfile.o stdio/fgets.o stdio/feof.o stdio/fscanf.o stdio/ungetc.o string/strncmp.o stdio/fputc.o string/strncpy.o stdio/remove.o stdio/ferror.o stdio/fputs.o stdlib/rand.o stdlib/srand.o unistd/getpid.o stdlib/strtoul.o stdio/fflush.o stdlib/abort.o string/strcspn.o time/localtime.o time/time.o time/clock_gettime.o time/gmtime.o time/strftime.o string/strpbrk.o ctype/isdigit.o ctype/isalpha.o ctype/isxdigit.o ctype/ispunct.o stdio/setvbuf.o stdio/fileno.o stdio/putc.o stdio/sprintf.o stdlib/abs.o string/strspn.o stdlib/qsort.o string/memmove.o setjmp/longjmp.o setjmp/setjmp.o libgen/basename.o string/strdup.o string/strndup.o string/strlcpy.o stdlib/atexit.o stdio/open_memstream.o libgen/dirname.o unistd/unlink.o string/strstr.o string/strcasecmp.o string/strncasecmp.o stdlib/mkstemp.o string/strtok.o unistd/execvp.o unistd/_exit.o ctype/isalnum.o time/ctime_r.o stdlib/strtold.o sys/time/gettimeofday.o stdio/fgetpos.o stdio/fsetpos.o ctype/isprint.o stdlib/system.o stdio/tmpnam.o unistd/msleep.o stdlib/atof.o stdlib/strtod.o stdio/rename.o sys/stat/mkdir.o unistd/uptime.o unistd/ftruncate.o sys/socket/recvfrom.o sys/socket/sendto.o signal/kill.o signal/sigaction.o unistd/chdir.o unistd/getcwd.o stdio/getdelim.o stdio/getline.o unistd/isatty.o sys/socket/listen.o stdlib/realpath.o systemcall.o sys/random/randomfill.o fcntl/open.o unistd/write.o unistd/pwrite.o fcntl/open_process.o tb/sb.o tb/sv.o string/memchr.o stdlib/atol.o stdlib/atoll.o stdlib/strtoll.o sys/stat/fstat.o unistd/lseek.o ctype/isupper.o ctype/islower.o ctype/isblank.o ctype/isgraph.o ctype/iscntrl.o math/ldexp.o sys/socket/connect.o sys/socket/setsockopt.o arpa/inet/ntohl.o arpa/inet/ntohs.o netdb/getaddrinfo.o tb/sha1.o sys/socket/getpeername.o fcntl/fcntl.o queue.o sys/sendfile.o stdio/fdopen.o unistd/dup.o all: libc.a %.o: %.c - $(CC) $(CFLAGS) -I. -o $@ -c $< -lgcc + $(CC) $(CFLAGS) -I. -o $@ -c $< %.o: %.s $(AS) $< -o $@ diff --git a/userland/libc/include/stdio.h b/userland/libc/include/stdio.h index ac49a67..781b431 100644 --- a/userland/libc/include/stdio.h +++ b/userland/libc/include/stdio.h @@ -33,6 +33,12 @@ struct __IO_FILE { int buffered_char; int has_buffered_char; int fd; + + int has_control_over_the_fd; + int can_write; + int can_read; + int append; + uint8_t is_eof; uint8_t has_error; uint64_t file_size; @@ -89,6 +95,7 @@ int getchar(void); size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); FILE *fopen(const char *pathname, const char *mode); +FILE *fdopen(int fildes, const char *mode); int fclose(FILE *stream); int fseek(FILE *stream, long offset, int whence); int fprintf(FILE *f, const char *fmt, ...); 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); |