diff --git a/.vscode/settings.json b/.vscode/settings.json index 6f092c0a..bdd00831 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,6 +10,11 @@ "editor.tabSize": 2, "files.associations": { "source_location": "cpp", + "stdio.h": "c", + "stddef.h": "c", + "errno.h": "c", + "ansi_files.h": "c", + "types.h": "c" }, "files.autoSave": "onFocusChange", "files.insertFinalNewline": true, diff --git a/asm/Runtime/FILE_POS.s b/asm/Runtime/FILE_POS.s index 04d2d444..c68db4e1 100644 --- a/asm/Runtime/FILE_POS.s +++ b/asm/Runtime/FILE_POS.s @@ -1,10 +1,10 @@ .include "macros.inc" -.section .sbss -.balign 8 -.global errno -errno: - .skip 0x8 +#.section .sbss +#.balign 8 +#.global errno +#errno: +# .skip 0x8 .section .text, "ax" diff --git a/configure.py b/configure.py index 9354e96c..d2a953cb 100755 --- a/configure.py +++ b/configure.py @@ -860,7 +860,8 @@ LIBS = [ ["Runtime/locale", True], ["Runtime/direct_io", True], ["Runtime/file_io", True], - "Runtime/FILE_POS", + ["Runtime/errno", True], + ["Runtime/FILE_POS", True], "Runtime/mbstring", ["Runtime/mem", True], ["Runtime/mem_funcs", True], diff --git a/ldscript.lcf b/ldscript.lcf index f9f472de..2fb2bd6e 100644 --- a/ldscript.lcf +++ b/ldscript.lcf @@ -35,4 +35,5 @@ SECTIONS FORCEFILES { __init_cpp_exceptions.o + errno.o } diff --git a/libc/errno.h b/libc/errno.h index 96304fc6..982e8ec2 100644 --- a/libc/errno.h +++ b/libc/errno.h @@ -10,7 +10,7 @@ extern int errno; #define ENOERR 0 #define EDOM 33 #define ERANGE 34 -#define EFPOS 35 +#define EFPOS 40 #define ESIGPARM 36 #ifdef __cplusplus diff --git a/libc/stdio.h b/libc/stdio.h index 914a99c5..7fb47db7 100644 --- a/libc/stdio.h +++ b/libc/stdio.h @@ -108,7 +108,9 @@ int printf(const char*, ...); int sprintf(char* s, const char* format, ...); int vprintf(const char* format, va_list arg); int vsprintf(char* s, const char* format, va_list arg); +size_t fread(const void*, size_t memb_size, size_t num_memb, FILE*); size_t fwrite(const void*, size_t memb_size, size_t num_memb, FILE*); +int fseek(FILE * file, long offset, int mode); size_t __fwrite(const void*, size_t, size_t, FILE*); #ifdef __cplusplus diff --git a/obj_files.mk b/obj_files.mk index f7a31544..ad343701 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -735,7 +735,7 @@ MSL_PPCEABI_BARE_H :=\ $(BUILD_DIR)/src/Runtime/locale.o\ $(BUILD_DIR)/src/Runtime/direct_io.o\ $(BUILD_DIR)/src/Runtime/file_io.o\ - $(BUILD_DIR)/asm/Runtime/FILE_POS.o\ + $(BUILD_DIR)/src/Runtime/FILE_POS.o\ $(BUILD_DIR)/asm/Runtime/mbstring.o\ $(BUILD_DIR)/src/Runtime/mem.o\ $(BUILD_DIR)/src/Runtime/mem_funcs.o\ diff --git a/src/Runtime/FILE_POS.c b/src/Runtime/FILE_POS.c new file mode 100644 index 00000000..64134474 --- /dev/null +++ b/src/Runtime/FILE_POS.c @@ -0,0 +1,102 @@ +#include +#include + +inline fpos_t _ftell(FILE* file) { + int charsInUndoBuffer = 0; + fpos_t position; + + unsigned char tmp_kind = file->mode.file_kind; + if (!(tmp_kind == __disk_file || tmp_kind == __console_file) || file->state.error) { + errno = EFPOS; + return (-1L); + } + + if (file->state.io_state == __neutral) + return (file->position); + + position = file->buffer_pos + (file->buffer_ptr - file->buffer); + + if (file->state.io_state >= __rereading) { + charsInUndoBuffer = file->state.io_state - __rereading + 1; + position -= charsInUndoBuffer; + } + + return (position); +} + +long ftell(FILE* file) { + long retval; + + retval = (long)_ftell(file); + + return retval; +} + +int _fseek(FILE* file, fpos_t offset, int mode) { + fpos_t position; + __pos_proc pos_proc; + + unsigned char tmp_kind = file->mode.file_kind; + if (!(tmp_kind == __disk_file) || file->state.error) { + errno = EFPOS; + return (-1); + } + + if (file->state.io_state == __writing) { + if (__flush_buffer(file, NULL) != __no_io_error) { + set_error(file); + errno = EFPOS; + return (-1); + } + } + + if (mode == SEEK_CUR) { + + mode = SEEK_SET; + + if ((position = _ftell(file)) < 0) + position = 0; + + offset += position; + } + + if ((mode != SEEK_END) && (file->mode.io_mode != __read_write) && + ((file->state.io_state == __reading) || (file->state.io_state == __rereading))) { + if ((offset >= file->position) || offset < file->buffer_pos) { + file->state.io_state = __neutral; + } else { + file->buffer_ptr = file->buffer + (offset - file->buffer_pos); + file->buffer_len = file->position - offset; + file->state.io_state = __reading; + } + } else { + file->state.io_state = __neutral; + } + + if (file->state.io_state == __neutral) { + if ((pos_proc = file->position_proc) != 0 && + (*pos_proc)(file->handle, &offset, mode, file->idle_proc)) { + set_error(file); + errno = EFPOS; + return (-1); + } + + file->state.eof = 0; + file->position = offset; + file->buffer_len = 0; + } + + return 0; +} + +int fseek(FILE * file, long offset, int mode) +{ + fpos_t real_offset = (fpos_t)offset; + int retval; + + + retval = _fseek(file, real_offset, mode); + + + return(retval); +} diff --git a/src/Runtime/errno.c b/src/Runtime/errno.c new file mode 100644 index 00000000..d013499d --- /dev/null +++ b/src/Runtime/errno.c @@ -0,0 +1,3 @@ +#include + +int errno;