From bd7e00e7e85e912a728af309ff70c2d95d49c46a Mon Sep 17 00:00:00 2001 From: Tom-on64 Date: Fri, 25 Oct 2024 12:32:22 +0200 Subject: [PATCH] Wrote a new stdio.h, Implemented fcntl.h --- libc/include/fcntl.h | 18 ++++++ libc/include/stdio.h | 73 +++++++++++++++++++----- libc/stdio/char.c | 17 ------ libc/stdio/file.c | 68 ----------------------- libc/stdio/printf.c | 129 ------------------------------------------- libc/stdio/read.c | 23 -------- 6 files changed, 76 insertions(+), 252 deletions(-) create mode 100644 libc/include/fcntl.h delete mode 100644 libc/stdio/char.c delete mode 100644 libc/stdio/file.c delete mode 100644 libc/stdio/printf.c delete mode 100644 libc/stdio/read.c diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h new file mode 100644 index 0000000..c5be997 --- /dev/null +++ b/libc/include/fcntl.h @@ -0,0 +1,18 @@ +#ifndef _FCNTL_H +#define _FCNTL_H + +/* File access modes */ +#define O_CREAT 0x0001 // Create if does not exist +#define O_RDONLY 0x0002 // Read only +#define O_WRONLY 0x0004 // Write only +#define O_RDWR 0x0008 // Read and write +#define O_APPEND 0x0010 // Always writes at the end (appends) +#define O_TRUNC 0x0020 // Truncate file size and position to 0 on Open +#define O_EXCL 0x0040 // Error if file exists (with O_CREAT) +#define O_BIN 0x0080 // Read bytes, not text +#define O_DIRECTORY 0x0100 // Error if file is not a directory +// TODO: more! + +/* TODO: File lock */ + +#endif diff --git a/libc/include/stdio.h b/libc/include/stdio.h index ee60fc9..5a4ad7e 100644 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -2,8 +2,27 @@ #define _STDIO_H #include +#include -// Nobody should have to interface with the internals of this structure +// End Of File +#define EOF (-1) + +// File related macros +#define BUFSIZ 512 +#define FILENAME_MAX 255 +#define FOPEN_MAX 32 + +// Seek positions +#define SEEK_CUR 0 +#define SEEK_END 1 +#define SEEK_SET 2 + +// Standard file pointers +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +/* The ultimate FILE struct */ typedef struct _iobuf { // 24B unsigned char* _ptr; // File buffer base unsigned int _size; // Size of buffer @@ -14,28 +33,52 @@ typedef struct _iobuf { // 24B char __reserved[6]; } FILE; -// Standard file pointers extern FILE* stdin; extern FILE* stdout; extern FILE* stderr; -/* File IO */ -FILE* fopen(const char* filename, const char* mode); +/* File operations */ +FILE* fopen(const char* path, const char* mode); int fclose(FILE* stream); size_t fread(void* ptr, size_t size, size_t count, FILE* stream); -size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream); -int fseek(FILE* stream, long int origin, int offset); -long int ftell(FILE* stream); +size_t fwrite(void* ptr, size_t size, size_t count, FILE* stream); +int fseek(FILE* stream, long offset, int whence); +long ftell(FILE* stream); +void rewind(FILE* stream); +int fflush(FILE* stream); -/* Terminal IO */ +/* Character I/O */ +int getchar(void); +int putchar(int c); +int getc(FILE* stream); +int putc(int c, FILE* stream); +int ungetc(int c, FILE* stream); + +/* Line I/O */ +char* fgets(char* str, int n, FILE* stream); +int fputs(const char* str, FILE* stream); +int puts(const char* str); + +/* Error handling */ +void perror(const char* s); +int feof(FILE* stream); +int ferror(FILE* stream); +void clearerr(FILE* stream); + +/* Formatted I/O */ int printf(const char* fmt, ...); -int sprintf(char* str, const char* fmt, ...); -int snprintf(char* str, size_t n, const char* fmt, ...); +int vprintf(const char* fmt, va_list va); int fprintf(FILE* stream, const char* fmt, ...); -void putc(char c); -char getc(); -void print(const char* str); -void clear(); -void reads(char* str); +int vfprintf(FILE* stream, const char* fmt, va_list va); +// INFO: (v)sprinf() Has been depricated and removed as it is unsafe (potencial buffer overflow). Please use (v)snprintf() +int snprintf(char* str, size_t size, const char* fmt, ...); +int vsnprintf(char* str, size_t size, const char* fmt, va_list va); + +int scanf(const char* fmt, ...); +int vscanf(const char* fmt, va_list va); +int fscanf(FILE* stream, const char* fmt, ...); +int vfscanf(FILE* stream, const char* fmt, va_list va); +int sscanf(const char* str, const char* fmt, ...); +int vsscanf(const char* str, const char* fmt, va_list va); #endif diff --git a/libc/stdio/char.c b/libc/stdio/char.c deleted file mode 100644 index 014b22f..0000000 --- a/libc/stdio/char.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include - -void putc(char c) { - // write(stdout, &c, 1); TODO: This doesn't work and we need to use a static variable - static char _c; - _c = c; - write(1, &_c, 1); -} - -char getc() { - char* c = (char*)0x2100; // TODO: Don't use a random looking memory address -_('-')_- - *c= '\0'; - while (*c == '\0') { __asm__ volatile ("hlt"); } - return *c; -} - diff --git a/libc/stdio/file.c b/libc/stdio/file.c deleted file mode 100644 index 9a5e4f6..0000000 --- a/libc/stdio/file.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include - -FILE* stdin; -FILE* stdout; -FILE* stderr; - -FILE* fopen(const char* filename, const char* mode) { - int oflag = O_RDWR | O_CREAT | O_BIN; // TODO! - - int fd = open(filename, oflag); - if (fd < 0) { - printf(""); // TODO: i'd prefer if i didn't need this - return NULL; - } - - // TODO: Somehow get the open file table - FILE* fp = malloc(sizeof(FILE)); - fp->_file = fd; - - return fp; -} - -int fclose(FILE* stream) { - int res = close(stream->_file); - return res; -} - -size_t fread(void* ptr, size_t size, size_t count, FILE* stream) { - unsigned int offset = 0; - size_t readEl = 0; - int fd = stream->_file; - - while (readEl != count) { - if (read(fd, (void*)(ptr + offset), size) != (int)size) break; - offset += size; - readEl++; - } - - return readEl; -} - -size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream) { - unsigned int offset = 0; - size_t writtenEl = 0; - int fd = stream->_file; - - while (writtenEl != count) { - if (write(fd, (void*)(ptr + offset), size) != (int)size) break; - offset += size; - writtenEl++; - } - - return writtenEl; -} - -int fseek(FILE* stream, long int origin, int offset) { - // TODO - return -1; -} - -long int ftell(FILE* stream) { - // TODO - return -1; -} - diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c deleted file mode 100644 index 4ba5e61..0000000 --- a/libc/stdio/printf.c +++ /dev/null @@ -1,129 +0,0 @@ -#include -#include -#include -#include -#include -#include - -// Warning: returns an allocated buffer, must be freed! -char* _format(const char* fmt, va_list args) { - static char* buffer; - size_t len = 0; - size_t max = 256; - - buffer = malloc(max); - - size_t i = 0; - while (fmt[i] != '\0') { - if (len > max) { - max *= 2; - // Reallocate a larger buffer - char* temp = malloc(max); - strcpy(temp, buffer); - free(buffer); - buffer = temp; - } - - // Formatting magic... - if (fmt[i] == '%') { i++; - /* TODO: - %p - pointer (0x########) - %n - "" - */ - int pad = -1; - char padc = ' '; - - if (fmt[i] == '0') { i++; padc = '0'; } - if (fmt[i] >= '0' && fmt[i] <= '9') { - pad = atoi(fmt + i); - while (fmt[i] >= '0' && fmt[i] <= '9') { i++; } - } - while (pad > 0) { buffer[len++] = padc; pad--; } - - char c = fmt[i++]; - if (c == 'd' || c == 'x' || c == 'o') { - int base = 10; - if (c == 'x') base = 16; - else if (c == 'o') base = 8; - - char* s = itoa(va_arg(args, int), base); - if (pad == 0) len -= strlen(s); - while ((buffer[len++] = *s++) != '\0'); - len--; - } else if (c == 'c') { - if (pad == 0) len--; - buffer[len++] = va_arg(args, char); - } else if (c == 's') { - char* s = va_arg(args, char*); - if (pad == 0) len -= strlen(s); - while ((buffer[len++] = *s++) != '\0'); - len--; - } else if (c == '%') { - buffer[len++] = '%'; - } else { - buffer[len++] = '%'; - if (padc == '0') { buffer[len++] = '0'; } - if (pad > 0) { buffer[len++] = '#'; } // TODO - buffer[len++] = c; - } - } else { buffer[len++] = fmt[i++]; } - } - - buffer[len] = '\0'; - return buffer; -} - -int sprintf(char* str, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - - char* buffer = _format(fmt, args); - strcpy(str, buffer); - free(buffer); - va_end(args); - - return strlen(str); -} - -int snprintf(char* str, size_t n, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - - char* buffer = _format(fmt, args); - strncpy(str, buffer, n); - free(buffer); - va_end(args); - - return strlen(str); -} - -int fprintf(FILE* stream, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - - char* buffer = _format(fmt, args); - size_t len = strlen(buffer); - write(stream->_file, buffer, len); // TODO: use fwrite() - - free(buffer); - va_end(args); - return len; -} - -int printf(const char* fmt, ...) { - va_list args; - va_start(args, fmt); - - char* buffer = _format(fmt, args); - size_t len = strlen(buffer); - write(stdout->_file, buffer, len); // TODO: use fwrite() - - free(buffer); - va_end(args); - return len; -} - -void print(const char* s) { - write(1, s, strlen(s)); -} - diff --git a/libc/stdio/read.c b/libc/stdio/read.c deleted file mode 100644 index 8a360aa..0000000 --- a/libc/stdio/read.c +++ /dev/null @@ -1,23 +0,0 @@ -#include - -// Reads until a newline -// TODO: Use Read() Syscall -void reads(char* buffer) { - char c; - int len = 0; - - while ((c = getc()) != '\n') { - if (c == '\b') { - if (len < 1) continue; // Can we backspace? - len--; - putc(c); - } else { - buffer[len++] = c; - putc(c); - } - } - - putc(c); // Print the newline - buffer[len] = '\0'; // Null terminate -} -