liblinux++

Log | Files | Refs

commit a70c9b5473f64760c15d65245b08ba5fa0414e66
parent 528829c7f8919c34edae11b46a8582c775fa5882
Author: Henry Wilson <henry@henryandlizzy.uk>
Date:   Sun, 21 Dec 2025 19:59:51 +0000

Add ls

Diffstat:
Mlinux.h | 12++++++++++++
Als.c | 43+++++++++++++++++++++++++++++++++++++++++++
Mx86_64.s | 1+
3 files changed, 56 insertions(+), 0 deletions(-)

diff --git a/linux.h b/linux.h @@ -4,6 +4,8 @@ typedef unsigned long long size_t; typedef signed long long ssize_t; typedef unsigned long long uintptr_t; typedef signed long long intptr_t; +typedef unsigned long long ino64_t; +typedef signed long long off64_t; enum { AT_FDCWD = -100, @@ -27,4 +29,14 @@ extern int read(int fd, char* data, size_t count); extern int write(int fd, char const* data, size_t count); extern int openat(int fd, char const* name, int flags, int mode); extern int close(int fd); + +struct linux_dirent64 { + ino64_t d_ino; /* 64-bit inode number */ + off64_t d_off; /* Not an offset; see getdents() */ + unsigned short d_reclen; /* Size of this dirent */ + unsigned char d_type; /* File type */ + char d_name[]; /* Filename (null-terminated) */ +}; +extern ssize_t getdents64(int fd, struct linux_dirent64 dirp[], size_t count); + extern void* mmap(void* addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long off); diff --git a/ls.c b/ls.c @@ -0,0 +1,43 @@ +#include "linux.h" + +#define assert(x) if (!(x)) __builtin_trap() + +size_t strlen(char const* p) +{ + char const* const begin = p; + while (*p) + ++p; + + return p - begin; +} + +ssize_t wr(int fd, char const* str) +{ + return write(fd, str, strlen(str)); +} + +int main() +{ + int fd = openat(AT_FDCWD, ".", O_RDONLY, 0); + assert(fd >= 0); + + struct linux_dirent64 buf[4]; + for (;;) + { + ssize_t n = getdents64(fd, buf, sizeof(buf)); + assert (n >= 0); + + if (!n) + break; + + char* const begin = (void*)buf; + + for (ssize_t i = 0; i < n;) + { + struct linux_dirent64* e = (void*)(begin + i); + wr(1, e->d_name); + wr(1, "\n"); + i += e->d_reclen; + } + } +} diff --git a/x86_64.s b/x86_64.s @@ -47,4 +47,5 @@ _syscall 1 syscall3 write _syscall 3 syscall3 close _syscall 9 syscall6 mmap _syscall 60 syscall3 exit +_syscall 217 syscall3 getdents64 _syscall 257 syscall6 openat