liblinux++

Log | Files | Refs

commit 41570a8a6d7d842b810b049cb067283df23bc050
parent d96ae84c979ca4198154c5e4ddf44f9ab626355f
Author: Henry Wilson <henry@henryandlizzy.uk>
Date:   Mon, 22 Dec 2025 21:13:44 +0000

move cat to .cpp and add file descriptor type

Diffstat:
Dcat.c | 29-----------------------------
Acat.cpp | 29+++++++++++++++++++++++++++++
Mlinux.hpp | 28+++++++++++++++++-----------
Mtest.cpp | 6+++---
Mx86_64.s | 7++++++-
5 files changed, 55 insertions(+), 44 deletions(-)

diff --git a/cat.c b/cat.c @@ -1,29 +0,0 @@ -#include "linux.h" - -static void cat(int fd) -{ - static char buf[0x1000]; - - for (;;) - { - int n = read(fd, buf, sizeof(buf)); - if (get_errno(n)) - exit(2); - if (n == 0) - return; - if (write(1, buf, n) != n) - exit(3); - } -} - -int main(int argc, char* argv[]) -{ - for (int i = 1; i < argc; ++i) - { - int fd = openat(AT_FDCWD, argv[i], 0, O_RDONLY); - if (get_errno(fd)) - return 1; - cat(fd); - close(fd); - } -} diff --git a/cat.cpp b/cat.cpp @@ -0,0 +1,29 @@ +#include "linux.hpp" + +static void cat(filedesc fd) +{ + static char buf[0x1000]; + + for (;;) + { + int n = read(fd, buf, sizeof(buf)); + if (get_errno(n)) + exit(2); + if (n == 0) + return; + if (write(stdout, buf, n) != n) + exit(3); + } +} + +int main(int argc, char* argv[]) +{ + for (int i = 1; i < argc; ++i) + { + filedesc fd = openat(AT_FDCWD, argv[i], 0, O_RDONLY); + if (!fd) + return 1; + cat(fd); + close(fd); + } +} diff --git a/linux.hpp b/linux.hpp @@ -60,23 +60,29 @@ struct span {} }; +struct filedesc +{ + int num = -1; + inline operator bool() const { return num >= 0; } +}; + +filedesc const stdin{0}; +filedesc const stdout{1}; +filedesc const stderr{2}; + __attribute__((noreturn)) extern void exit(int error_code); -extern "C" { -extern int read(int fd, char* data, size_t count); -} -extern int read(int fd, span<char> data); +extern ssize_t read(filedesc fd, char* data, size_t count); +extern ssize_t read(filedesc fd, span<char> data); -extern "C" { -extern int write(int fd, char const* data, size_t count); -} -extern int write(int fd, span<char const> data); -extern ssize_t write(int fd, span<span<char const> const> data); +extern ssize_t write(filedesc fd, char const* data, size_t count); +extern ssize_t write(filedesc fd, span<char const> data); +extern ssize_t write(filedesc fd, span<span<char const> const> data); -extern int openat(int fd, char const* name, int flags, int mode); +extern filedesc openat(int fd, char const* name, int flags, int mode); -extern int close(int fd); +extern int close(filedesc fd); struct linux_dirent64 { ino64_t d_ino; /* 64-bit inode number */ diff --git a/test.cpp b/test.cpp @@ -6,14 +6,14 @@ char bss[4]; void text() { - write(1, {rodata, sizeof(rodata) - 1}); - write(1, {data, sizeof(data) - 1}); + write(stdout, {rodata, sizeof(rodata) - 1}); + write(stdout, {data, sizeof(data) - 1}); bss[0] = 'b'; bss[1] = 's'; bss[2] = 's'; bss[3] = '\n'; - write(1, bss); + write(stdout, bss); } int main() diff --git a/x86_64.s b/x86_64.s @@ -45,13 +45,16 @@ syscall6: ret extern read +extern_alias _Z4read8filedescPcy _syscall 0 syscall3 extern write -extern_alias _Z5writei4spanIKcE +extern_alias _Z5write8filedescPKcy +extern_alias _Z5write8filedesc4spanIKcE _syscall 1 syscall3 extern close +extern_alias _Z5close8filedesc _syscall 3 syscall3 extern mmap @@ -66,10 +69,12 @@ extern_alias _Z9nanosleepPK8timespecPS_ _syscall 35 syscall3 extern exit +extern_alias _Z4exiti _syscall 60 syscall3 extern getdents64 _syscall 217 syscall3 extern openat +extern_alias _Z6openatiPKcii _syscall 257 syscall6