liblinux++

A hosted C++ runtime without any libc.
git clone git://henryandlizzy.uk/liblinux++
Log | Files | Refs

commit dc63fe778af6488f6b12a78b6b41a4beaaa07663
parent 44c8140fe7d217d01ad78509175d90d3248610c0
Author: Henry Wilson <henry@henryandlizzy.uk>
Date:   Tue, 23 Dec 2025 15:12:42 +0000

convert cat to .cpp

Diffstat:
Mlinux.hpp | 9+++++++++
Dtac.c | 58----------------------------------------------------------
Atac.cpp | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mx86_64.s | 1+
4 files changed, 69 insertions(+), 58 deletions(-)

diff --git a/linux.hpp b/linux.hpp @@ -60,6 +60,7 @@ struct span struct file { + file() = default; explicit file(int n) : num{n} {} int num = -1; inline operator bool() const { return num >= 0; } @@ -122,10 +123,18 @@ extern void exit(int error_code); extern syscall_result<size_t> read(file fd, char data[], size_t count); extern syscall_result<size_t> read(file fd, span<char> data); +inline syscall_result<size_t> read(file fd, char* begin, char* end) +{ + return read(fd, begin, end - begin); +} extern syscall_result<size_t> write(file fd, char const data[], size_t count); extern syscall_result<size_t> write(file fd, span<char const> data); extern syscall_result<size_t> write(file fd, span<span<char const> const> data); +inline syscall_result<size_t> write(file fd, char const* begin, char const* end) +{ + return write(fd, begin, end - begin); +} extern syscall_result<file> openat(file fd, c_str name, int flags, int mode); diff --git a/tac.c b/tac.c @@ -1,58 +0,0 @@ -#include "linux.h" - -extern char mappable[]; - -static int rd(int const fd, char* const start, char const* const end) -{ - char* pos = start; - while (pos != end) - { - int n = read(fd, pos, end - pos); - if (get_errno(n)) - exit(2); - if (n == 0) - break; - pos += n; - } - return pos - start; -} - -static void wr(int const fd, char const* start, char const* const end) -{ - while (start != end) - { - int n = write(fd, start, end - start); - if (get_errno(n)) - exit(3); - start += n; - } -} - -int main() -{ - char* buf = mappable; - size_t cap = 0; - size_t len = 0; - - while (len == cap) - { - intptr_t m = mmap(buf + cap, cap ?: 0x1000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - if (get_errno(m)) - return 1; - cap += cap ?: 0x1000; - - len += rd(0, buf + len, buf + cap); - } - -reverse: - char const* end = buf + len; - char const* str = end; - - while (--str > buf) - { - while (str > buf && str[-1] != '\n') - --str; - wr(1, str, end); - end = str; - } -} diff --git a/tac.cpp b/tac.cpp @@ -0,0 +1,59 @@ +#include "linux.hpp" + +extern char mappable[]; + +static int rd(file const fd, char* const start, char* const end) +{ + char* pos = start; + while (pos != end) + { + auto res = read(fd, pos, end); + if (!res) + exit(2); + auto n = *res; + if (n == 0) + break; + pos += n; + } + return pos - start; +} + +static void wr(file const fd, char const* start, char const* const end) +{ + while (start != end) + { + auto n = write(fd, start, end); + if (!n) + exit(3); + start += *n; + } +} + +int main() +{ + char* buf = mappable; + size_t cap = 0; + size_t len = 0; + + while (len == cap) + { + auto m = mmap(buf + cap, cap ?: 0x1000, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, {}, 0); + if (!m) + return 1; + cap += cap ?: 0x1000; + + len += rd(stdin, buf + len, buf + cap); + } + +reverse: + char const* end = buf + len; + char const* str = end; + + while (--str > buf) + { + while (str > buf && str[-1] != '\n') + --str; + wr(stdout, str, end); + end = str; + } +} diff --git a/x86_64.s b/x86_64.s @@ -58,6 +58,7 @@ extern_alias _Z5close4file _syscall 3 syscall3 extern mmap +extern_alias _Z4mmapPvmmm4filem _syscall 9 syscall6 extern writev