Showing the changes to src/vm/sys/Sysmod.cpp (1 of 9 files). Show all
Unified · Split
| @@ -7,7 +7,11 @@ · 6 unmodified lines | |||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <chrono> | 8 | #include <chrono> |
| 9 | #include <thread> | 9 | #include <thread> |
| 10 | #include <iostream> | ||
| 11 | #include <fstream> | ||
| 12 | #include <streambuf> | ||
| 10 | #include <exceptions.h> | 13 | #include <exceptions.h> |
| 14 | #include <debug.h> | ||
| 11 | #include <utf8.h> | 15 | #include <utf8.h> |
| 12 | #include "Sysmod.h" | 16 | #include "Sysmod.h" |
| 13 | #include "sys_utils.h" | 17 | #include "sys_utils.h" |
| @@ -73,15 +77,113 @@ std::shared_ptr<const type_descriptor_t> T_FD; · 59 unmodified lines | |||
| 73 | std::shared_ptr<const type_descriptor_t> T_Connection; | 77 | std::shared_ptr<const type_descriptor_t> T_Connection; |
| 74 | std::shared_ptr<const type_descriptor_t> T_FileIO; | 78 | std::shared_ptr<const type_descriptor_t> T_FileIO; |
| 75 | 79 | ||
| 80 | struct vm_fd_t final : public Sys_FD | ||
| 81 | { | ||
| 82 | static void finalizer(vm_alloc_t *fileHandle) | ||
| 83 | { | ||
| 84 | auto fd = fileHandle->get_allocation<vm_fd_t>(); | ||
| 85 | fd->~vm_fd_t(); | ||
| 86 | } | ||
| 87 | |||
| 88 | vm_fd_t(word_t fd, std::unique_ptr<std::iostream> s) | ||
| 89 | : Sys_FD{ fd } | ||
| 90 | , _istream{ s.get() } | ||
| 91 | , _ostream{ s.get() } | ||
| 92 | { | ||
| 93 | assert(s != nullptr); | ||
| 94 | _stream = std::move(s); | ||
| 95 | } | ||
| 96 | |||
| 97 | vm_fd_t(word_t fd, std::unique_ptr<std::istream> s) | ||
| 98 | : Sys_FD{ fd } | ||
| 99 | , _istream{ s.get() } | ||
| 100 | , _ostream{ nullptr } | ||
| 101 | { | ||
| 102 | assert(s != nullptr); | ||
| 103 | _stream = std::move(s); | ||
| 104 | } | ||
| 105 | |||
| 106 | vm_fd_t(word_t fd, std::unique_ptr<std::ostream> s) | ||
| 107 | : Sys_FD{ fd } | ||
| 108 | , _istream{ nullptr } | ||
| 109 | , _ostream{ s.get() } | ||
| 110 | { | ||
| 111 | assert(s != nullptr); | ||
| 112 | _stream = std::move(s); | ||
| 113 | } | ||
| 114 | |||
| 115 | vm_fd_t(word_t fd, std::istream &s) | ||
| 116 | : Sys_FD{ fd } | ||
| 117 | , _istream{ &s } | ||
| 118 | , _ostream{ nullptr } | ||
| 119 | { | ||
| 120 | } | ||
| 121 | |||
| 122 | vm_fd_t(word_t fd, std::ostream &s) | ||
| 123 | : Sys_FD{ fd } | ||
| 124 | , _istream{ nullptr } | ||
| 125 | , _ostream{ &s } | ||
| 126 | { | ||
| 127 | } | ||
| 128 | |||
| 129 | ~vm_fd_t() | ||
| 130 | { | ||
| 131 | debug::assign_debug_pointer(&_istream); | ||
| 132 | debug::assign_debug_pointer(&_ostream); | ||
| 133 | |||
| 134 | if (debug::is_component_tracing_enabled<debug::component_trace_t::memory>()) | ||
| 135 | debug::log_msg(debug::component_trace_t::memory, debug::log_level_t::debug, "destroy: file descriptor: %d", fd); | ||
| 136 | } | ||
| 137 | |||
| 138 | std::istream& input() const | ||
| 139 | { | ||
| 140 | if (_istream == nullptr) | ||
| 141 | throw vm_user_exception{ "File descriptor not open for write" }; | ||
| 142 | |||
| 143 | return *_istream; | ||
| 144 | } | ||
| 145 | |||
| 146 | std::ostream& output() const | ||
| 147 | { | ||
| 148 | if (_ostream == nullptr) | ||
| 149 | throw vm_user_exception{ "File descriptor not open for read" }; | ||
| 150 | |||
| 151 | return *_ostream; | ||
| 152 | } | ||
| 153 | |||
| 154 | private: | ||
| 155 | std::istream *_istream; | ||
| 156 | std::ostream *_ostream; | ||
| 157 | std::unique_ptr<std::ios> _stream; | ||
| 158 | }; | ||
| 159 | |||
| 160 | namespace | ||
| 161 | { | ||
| 162 | vm_alloc_t *vm_stdin = nullptr; | ||
| 163 | vm_alloc_t *vm_stdout = nullptr; | ||
| 164 | vm_alloc_t *vm_stderr = nullptr; | ||
| 165 | } | ||
| 166 | |||
| 76 | void | 167 | void |
| 77 | Sysmodinit(void) | 168 | Sysmodinit(void) |
| 78 | { | 169 | { |
| 79 | builtin::register_module_exports(Sys_PATH, Sysmodlen, Sysmodtab); | 170 | builtin::register_module_exports(Sys_PATH, Sysmodlen, Sysmodtab); |
| 80 | T_Qid = type_descriptor_t::create(sizeof(Sys_Qid), sizeof(Sys_Qid_map), Sys_Qid_map); | 171 | T_Qid = type_descriptor_t::create(sizeof(Sys_Qid), sizeof(Sys_Qid_map), Sys_Qid_map); |
| 81 | T_Dir = type_descriptor_t::create(sizeof(Sys_Dir), sizeof(Sys_Dir_map), Sys_Dir_map); | 172 | T_Dir = type_descriptor_t::create(sizeof(Sys_Dir), sizeof(Sys_Dir_map), Sys_Dir_map); |
| 82 | T_FD = type_descriptor_t::create(sizeof(Sys_FD), sizeof(Sys_FD_map), Sys_FD_map); | 173 | T_FD = type_descriptor_t::create(sizeof(vm_fd_t), sizeof(Sys_FD_map), Sys_FD_map, vm_fd_t::finalizer); |
| 83 | T_Connection = type_descriptor_t::create(sizeof(Sys_Connection), sizeof(Sys_Connection_map), Sys_Connection_map); | 174 | T_Connection = type_descriptor_t::create(sizeof(Sys_Connection), sizeof(Sys_Connection_map), Sys_Connection_map); |
| 84 | T_FileIO = type_descriptor_t::create(sizeof(Sys_FileIO), sizeof(Sys_FileIO_map), Sys_FileIO_map); | 175 | T_FileIO = type_descriptor_t::create(sizeof(Sys_FileIO), sizeof(Sys_FileIO_map), Sys_FileIO_map); |
| 176 | |||
| 177 | // Initialize default file descriptors | ||
| 178 | |||
| 179 | vm_stdin = vm_alloc_t::allocate(T_FD); | ||
| 180 | ::new(vm_stdin->get_allocation()) vm_fd_t{ 0, std::cin }; | ||
| 181 | |||
| 182 | vm_stdout = vm_alloc_t::allocate(T_FD); | ||
| 183 | ::new(vm_stdout->get_allocation()) vm_fd_t{ 1, std::cout }; | ||
| 184 | |||
| 185 | vm_stderr = vm_alloc_t::allocate(T_FD); | ||
| 186 | ::new(vm_stderr->get_allocation()) vm_fd_t{ 2, std::cerr }; | ||
| 85 | } | 187 | } |
| 86 | 188 | ||
| 87 | void | 189 | void |
| @@ -354,13 +456,13 @@ Sys_print(vm_registers_t &r, vm_t &vm) · 266 unmodified lines | |||
| 354 | auto written = printf_to_buffer(*str, msg_args, fp_base, static_buffer.size(), static_buffer.data()); | 456 | auto written = printf_to_buffer(*str, msg_args, fp_base, static_buffer.size(), static_buffer.data()); |
| 355 | if (written >= 0) | 457 | if (written >= 0) |
| 356 | { | 458 | { |
| 357 | std::printf(static_buffer.data()); | 459 | vm_stdout->get_allocation<vm_fd_t>()->output() << static_buffer.data(); |
| 358 | } | 460 | } |
| 359 | else | 461 | else |
| 360 | { | 462 | { |
| 361 | auto dynamic_buffer = std::vector<char>(static_buffer.size() * 2); | 463 | auto dynamic_buffer = std::vector<char>(static_buffer.size() * 2); |
| 362 | written = printf_to_dynamic_buffer(*str, msg_args, fp_base, dynamic_buffer); | 464 | written = printf_to_dynamic_buffer(*str, msg_args, fp_base, dynamic_buffer); |
| 363 | std::printf(dynamic_buffer.data()); | 465 | vm_stdout->get_allocation<vm_fd_t>()->output() << static_buffer.data(); |
| 364 | } | 466 | } |
| 365 | 467 | ||
| 366 | *fp.ret = written; | 468 | *fp.ret = written; |