summaryrefslogtreecommitdiff
path: root/euler/source/std/cstdio.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'euler/source/std/cstdio.cpp')
-rw-r--r--euler/source/std/cstdio.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/euler/source/std/cstdio.cpp b/euler/source/std/cstdio.cpp
new file mode 100644
index 0000000..8c12a7c
--- /dev/null
+++ b/euler/source/std/cstdio.cpp
@@ -0,0 +1,59 @@
+#include <cstdio>
+
+extern "C" FILE *fopen(const char *filename, const char *mode) {
+
+ bool r = false, w = false, a = false, p = false, x = false;
+ for (size_t i = 0; mode[i] != '\0'; ++i)
+ if (mode[i] == 'r') r = true;
+ else if (mode[i] == 'w') w = true;
+ else if (mode[i] == 'a') a = true;
+ else if (mode[i] == 'p') p = true;
+ else if (mode[i] == 'x') x = true;
+
+ euler::syscall::stream_handle handle;
+ if (euler::syscall::open_file(filename, !r, x, handle) !=
+ euler::syscall::stream_result::success)
+ return 0;
+
+ if (w && euler::syscall::set_stream_length(handle, 0) !=
+ euler::syscall::stream_result::success)
+ return 0;
+
+ if (a && euler::syscall::seek_stream(
+ handle, euler::syscall::seek_from::end, 0) !=
+ euler::syscall::stream_result::success) {
+ euler::syscall::close_stream(handle);
+ return 0;
+ }
+
+ uint64_t length;
+ if (euler::syscall::get_stream_length(handle, length) !=
+ euler::syscall::stream_result::success) {
+ euler::syscall::close_stream(handle);
+ return 0;
+ }
+
+ return new euler::file_stream(handle, r || p, length, a ? length : 0);
+
+}
+
+extern "C" void fclose(FILE *stream) {
+ stream->close();
+ delete stream;
+}
+
+extern "C" int fseek(FILE *stream, long offset, int origin) {
+
+ if (origin < 0 || origin > 2)
+ return -1;
+
+ return (int)stream->seek((euler::syscall::seek_from)origin, offset);
+
+}
+
+extern "C" size_t fread(
+ void *buffer, size_t size, size_t count, FILE *stream) {
+
+ return (stream->read(size * count, buffer).first - 1) / size + 1;
+
+}