commit dc63fe778af6488f6b12a78b6b41a4beaaa07663
parent 44c8140fe7d217d01ad78509175d90d3248610c0
Author: Henry Wilson <henry@henryandlizzy.uk>
Date: Tue, 23 Dec 2025 15:12:42 +0000
convert cat to .cpp
Diffstat:
| M | linux.hpp | | | 9 | +++++++++ |
| D | tac.c | | | 58 | ---------------------------------------------------------- |
| A | tac.cpp | | | 59 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | x86_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