diff options
Diffstat (limited to 'euler')
-rw-r--r-- | euler/include/euler/start_process.hpp | 30 | ||||
-rw-r--r-- | euler/include/euler/syscall.hpp | 28 | ||||
-rw-r--r-- | euler/include/type_traits | 23 | ||||
-rw-r--r-- | euler/include/utility | 12 | ||||
-rw-r--r-- | euler/include/vector | 62 | ||||
-rw-r--r-- | euler/makefile | 3 | ||||
-rw-r--r-- | euler/source/euler/start_process.cpp | 35 | ||||
-rw-r--r-- | euler/source/euler/syscall.asm | 18 |
8 files changed, 210 insertions, 1 deletions
diff --git a/euler/include/euler/start_process.hpp b/euler/include/euler/start_process.hpp new file mode 100644 index 0000000..00ebbab --- /dev/null +++ b/euler/include/euler/start_process.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include <euler/syscall.hpp> +#include <vector> + +namespace euler { + + struct start_process { + + private: + const char *path; + uint64_t path_len; + std::vector<__euler_env_var_spec> env_var_specs; + std::vector<__euler_gift_stream_spec> gift_stream_specs; + + public: + //path needs to stay valid through any call to start + start_process(const char *path); + + //name and value need to stay valid through any call to start + void add_env_variable(const char *name, const char *value); + + void gift_stream( + __euler_stream_handle to_gifter, __euler_stream_handle to_giftee); + + __euler_stream_result start(__euler_process_handle &handle_out); + + }; + +} diff --git a/euler/include/euler/syscall.hpp b/euler/include/euler/syscall.hpp index 761dbcc..981925f 100644 --- a/euler/include/euler/syscall.hpp +++ b/euler/include/euler/syscall.hpp @@ -27,6 +27,7 @@ enum __euler_seek_from : uint8_t { }; typedef uint64_t __euler_stream_handle; +typedef uint64_t __euler_process_handle; extern "C" __euler_stream_result __euler_open_file( const char *path, uint64_t path_len, __euler_stream_handle &handle_out, @@ -72,3 +73,30 @@ enum __euler_input_packet_type : uint8_t { extern "C" __euler_input_packet_type __euler_get_input_packet( __euler_mouse_buttons &buttons_out, int16_t &x_change_out, int16_t &y_change_out, uint32_t &keyboard_packet_out); + +struct [[gnu::packed]] __euler_env_var_spec { + uint64_t name_len; + const char *name; + uint64_t value_len; + const char *value; +}; + +struct [[gnu::packed]] __euler_gift_stream_spec { + __euler_stream_handle stream_handle_to_gifter; + __euler_stream_handle stream_handle_to_giftee; +}; + +struct [[gnu::packed]] __euler_process_start_info { + uint64_t file_path_length; + const char *file_path; + uint64_t env_var_count; + const __euler_env_var_spec *env_vars; + uint64_t gift_stream_count; + const __euler_gift_stream_spec *gift_streams; +}; + +extern "C" __euler_stream_result __euler_start_process( + const __euler_process_start_info &info, __euler_process_handle &handle_out); + +extern "C" __euler_stream_result __euler_get_other_end_process_handle( + __euler_stream_handle handle_in, __euler_process_handle &handle_out); diff --git a/euler/include/type_traits b/euler/include/type_traits new file mode 100644 index 0000000..fcea013 --- /dev/null +++ b/euler/include/type_traits @@ -0,0 +1,23 @@ +#pragma once + +namespace std { + + template <class t> + struct remove_reference { + typedef t type; + }; + + template <class t> + struct remove_reference<t &> { + typedef t type; + }; + + template <class t> + struct remove_reference<t &&> { + typedef t type; + }; + + template <class t> + using remove_reference_t = typename remove_reference<t>::type; + +} diff --git a/euler/include/utility b/euler/include/utility new file mode 100644 index 0000000..23648c4 --- /dev/null +++ b/euler/include/utility @@ -0,0 +1,12 @@ +#pragma once + +#include <type_traits> + +namespace std { + + template <class t> + constexpr std::remove_reference_t<t> &&move(t &&x) { + return static_cast<std::remove_reference_t<t> &&>(x); + } + +} diff --git a/euler/include/vector b/euler/include/vector new file mode 100644 index 0000000..f5083ed --- /dev/null +++ b/euler/include/vector @@ -0,0 +1,62 @@ +#pragma once + +#include <stddef.h> +#include <utility> + +namespace std { + + template <class t> + class vector { + + t *buffer; + size_t buffer_length;//always positive + size_t count; + + public: + vector() : buffer(new t[16]), buffer_length(16), count(0) {} + + ~vector() { + delete[] buffer; + } + + t &operator[](size_t pos) { + return buffer[pos]; + } + + const t &operator[](size_t pos) const { + return buffer[pos]; + } + + t *data() { + return buffer; + } + + const t *data() const { + return buffer; + } + + size_t size() const { + return count; + } + + void reserve(size_t new_length) { + if (new_length <= buffer_length) + return; + t *new_buffer = new t[new_length]; + for (size_t i = 0; i < count; ++i) + new_buffer[i] = std::move(buffer[i]); + delete[] buffer; + buffer = new_buffer; + buffer_length = new_length; + } + + void push_back(t &&value) { + if (count == buffer_length) + reserve(count * 2); + buffer[count++] = std::move(value); + } + + //TODO + }; + +} diff --git a/euler/makefile b/euler/makefile index b9d440f..1767d75 100644 --- a/euler/makefile +++ b/euler/makefile @@ -1,6 +1,7 @@ LIBSTDCPP_SOURCES = euler/stream.cpp strings/strlen.cpp euler/syscall.asm \ euler/entry.cpp io/fopen.cpp euler/gcc.asm memory/delete.cpp euler/heap.cpp \ - memory/new.cpp io/fclose.cpp io/fread.cpp strings/memcpy.cpp io/fseek.cpp + memory/new.cpp io/fclose.cpp io/fread.cpp strings/memcpy.cpp io/fseek.cpp \ + euler/start_process.cpp clean: rm -rf build diff --git a/euler/source/euler/start_process.cpp b/euler/source/euler/start_process.cpp new file mode 100644 index 0000000..64e16c5 --- /dev/null +++ b/euler/source/euler/start_process.cpp @@ -0,0 +1,35 @@ +#include <euler/start_process.hpp> +#include <cstring> + +namespace euler { + + start_process::start_process(const char *path) + : path(path), path_len(std::strlen(path)) {} + + void start_process::add_env_variable(const char *name, const char *value) { + env_var_specs.push_back({ + .name_len = std::strlen(name), .name = name, + .value_len = std::strlen(value), .value = value }); + } + + void start_process::gift_stream( + __euler_stream_handle to_gifter, __euler_stream_handle to_giftee) { + gift_stream_specs.push_back({ + .stream_handle_to_gifter = to_gifter, + .stream_handle_to_giftee = to_giftee }); + } + + __euler_stream_result start_process::start( + __euler_process_handle &handle_out) { + __euler_process_start_info info = { + .file_path_length = path_len, + .file_path = path, + .env_var_count = env_var_specs.size(), + .env_vars = env_var_specs.data(), + .gift_stream_count = gift_stream_specs.size(), + .gift_streams = gift_stream_specs.data(), + }; + return __euler_start_process(info, handle_out); + } + +} diff --git a/euler/source/euler/syscall.asm b/euler/source/euler/syscall.asm index 41bd05c..64f08f8 100644 --- a/euler/source/euler/syscall.asm +++ b/euler/source/euler/syscall.asm @@ -12,6 +12,8 @@ global __euler_read_from_stream global __euler_get_framebuffer global __euler_encode_color global __euler_get_input_packet +global __euler_start_process +global __euler_get_other_end_process_handle section .text @@ -124,3 +126,19 @@ __euler_get_input_packet: mov byte [rdx], al mov al, 1 ret + +__euler_start_process: + push rsi + mov rax, 16 + syscall + pop rsi + mov qword [rsi], rdi + ret + +__euler_get_other_end_process_handle: + push rsi + mov rax, 19 + syscall + pop rsi + mov qword [rsi], rdi + ret |