diff options
author | quou <quou@disroot.org> | 2024-07-13 23:45:08 +1000 |
---|---|---|
committer | quou <quou@disroot.org> | 2024-07-13 23:45:08 +1000 |
commit | a43eb70ebe7844db0a4ffece47c22ae12384781b (patch) | |
tree | 57bde2c38a15602ecdad23627970aafbddf587a7 | |
parent | 5f59b1517ef18d85e6dd05f2985e5a441deb5cac (diff) |
Add file API
-rw-r--r-- | plat.c | 91 | ||||
-rw-r--r-- | plat.h | 23 |
2 files changed, 114 insertions, 0 deletions
@@ -8,11 +8,15 @@ #define _POSIX_SOURCE #define _GNU_SOURCE +#include <fcntl.h> #include <stdarg.h> #include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> #include <sys/time.h> #include <sys/types.h> #include <time.h> +#include <unistd.h> extern int isatty(int); extern int fileno(FILE*); @@ -86,16 +90,103 @@ void pbreak(Error code) { #endif } +struct File { + int handle; + int cursor; + int size; +}; + +File* file_open(const char* name, File_Flags flags) { + File* file; + int handle, f = 0; + struct stat info; + + if (flags & file_flags_write) { + f |= O_WRONLY | O_TRUNC; + } + + if (flags & file_flags_read) { + f |= O_RDONLY; + } + + if (flags & file_flags_read_write) { + f |= O_RDWR; + } + + if (stat(name, &info) < 0) { + info.st_size = 0; + if (flags & file_flags_create) { + f |= O_CREAT | S_IRUSR | S_IWUSR; + } + } + + handle = open(name, f); + if (handle < 0) { + return 0; + } + + file = (File*)malloc(sizeof *file); + file->handle = handle; + file->cursor = 0; + file->size = (int)info.st_size; + + return file; +} + +void file_close(File* file) { + close(file->handle); + free(file); +} + +void file_read(File* file, void* buffer, int size) { + lseek(file->handle, (off_t)file->cursor, SEEK_SET); + read(file->handle, buffer, size); + file->cursor += size; +} + +void file_write(File* file, const void* buffer, int size) { + lseek(file->handle, (off_t)file->cursor, SEEK_SET); + write(file->handle, buffer, size); + file->cursor += size; +} + +void file_seek(File* file, int offset, File_Whence whence) { + switch (whence) { + case file_whence_begin: + file->cursor = offset; + break; + case file_whence_end: + file->cursor = file->size - offset; + break; + case file_whence_cur: + file->cursor += offset; + break; + } +} + +int file_size(File* file) { + return file->size; +} + +int file_exists(const char* name) { + struct stat info; + return stat(name, &info) == 0; +} + + static clockid_t global_clock; static unsigned long global_freq; void init_timer(void) { + struct timespec ts; global_clock = CLOCK_REALTIME; global_freq = 1000000000; #if defined(_POSIX_MONOTONIC_CLOCK) if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { global_clock = CLOCK_MONOTONIC; } +#else + (void)ts; #endif } @@ -29,6 +29,29 @@ void print_err(const char* fmt, ...); void print_war(const char* fmt, ...); void pbreak(Error code); +typedef struct File File; + +typedef enum { + file_flags_write = 1 << 0, + file_flags_read = 1 << 1, + file_flags_read_write = 1 << 2, + file_flags_create = 1 << 3 +} File_Flags; + +typedef enum { + file_whence_begin, + file_whence_end, + file_whence_cur +} File_Whence; + +File* file_open(const char* name, File_Flags flags); +void file_close(File* file); +void file_read(File* file, void* buffer, int size); +void file_write(File* file, const void* buffer, int size); +void file_seek(File* file, int offset, File_Whence whence); +int file_size(File* file); +int file_exists(const char* name); + typedef struct { int mpf; int fps; |