commit aa4d292508143c16f35d77ae003dbe29d02cb656
parent d2aa68d70e312446d01bd451d8e6b172b67d8291
Author: evenfri <evenfri@noreply.codeberg.org>
Date: Fri, 24 Jul 2026 18:10:30 +0200
update (#4)
Co-authored-by: evenfri <evenfri256@gmail.com>
Reviewed-on: https://codeberg.org/evenfri/libc/pulls/4
Diffstat:
13 files changed, 102 insertions(+), 69 deletions(-)
diff --git a/_exit.c b/_exit.c
@@ -6,12 +6,7 @@
#include "libc.h"
void _exit(int status) {
- asm volatile (
- "syscall"
- :
- : "a"(sys_exit), "D"(status)
- : "memory"
- );
+ syscall(sys_exit, status);
for (;;) {}
}
diff --git a/chdir.c b/chdir.c
@@ -0,0 +1,14 @@
+/*
+ * chdir.c — change working directory
+ * Copyright (C) 2026. All rights reserved.
+ */
+
+#include "libc.h"
+
+int chdir(const char *path) {
+ long ret = syscall(sys_chdir, path);
+ if (ret < 0) {
+ return -1;
+ }
+ return 0;
+}
diff --git a/close.c b/close.c
@@ -6,14 +6,7 @@
#include "libc.h"
int close(int fd) {
- long ret;
-
- asm volatile (
- "syscall"
- : "=a"(ret)
- : "a"(sys_close), "D"(fd)
- : "rcx", "r11", "memory"
- );
+ long ret = syscall(sys_close, fd);
return ret;
}
diff --git a/execve.c b/execve.c
@@ -6,17 +6,7 @@
#include "libc.h"
int execve(const char *path, char *const argv[], char *const envp[]) {
- long ret;
-
- asm volatile (
- "syscall"
- : "=a"(ret)
- : "a"(sys_execve),
- "D"(path),
- "S"(argv),
- "d"(envp)
- : "rcx", "r11", "memory"
- );
+ long ret = syscall3(sys_execve, path, argv, envp);
if (ret < 0) {
return -1;
diff --git a/fork.c b/fork.c
@@ -8,14 +8,7 @@
#define sigchld 17
int fork(void) {
- long ret;
-
- asm volatile (
- "syscall"
- : "=a"(ret)
- : "a"(sys_clone), "D"((long)sigchld), "S"(0L)
- : "rcx", "r11", "memory"
- );
+ long ret = syscall2(sys_clone, (long)sigchld, 0L);
return (int)ret;
}
diff --git a/getcwd.c b/getcwd.c
@@ -0,0 +1,14 @@
+/*
+ * chdir.c — change working directory
+ * Copyright (C) 2026. All rights reserved.
+ */
+
+#include "libc.h"
+
+int chdir(const char *path) {
+ long ret = syscall(sys_chdir, path);
+ if (ret < 0) {
+ return -1;
+ }
+ return 0;
+}
diff --git a/getdents.c b/getdents.c
@@ -0,0 +1,10 @@
+/*
+ * getdents.c — get directory entries
+ * Copyright (C) 2026. All rights reserved.
+ */
+
+#include "libc.h"
+
+int getdents64(int fd, struct linux_dirent64 *dirp, unsigned int count) {
+ return (int)syscall3(sys_getdents64, fd, (long)dirp, count);
+}
diff --git a/libc.h b/libc.h
@@ -19,11 +19,54 @@ typedef long ssize_t;
#define stdout 1
#define stderr 2
+struct linux_dirent64 {
+ unsigned long d_ino;
+ long d_off;
+ unsigned short d_reclen;
+ unsigned char d_type;
+ char d_name[];
+};
+
+/* macros */
+#define syscall(n, d) ({ \
+ long ret; \
+ asm volatile ( \
+ "syscall" \
+ : "=a"(ret) \
+ : "a"(n), "D"(d) \
+ : "rcx", "r11", "memory" \
+ ); \
+ ret; \
+ })
+
+#define syscall2(n, arg1, arg2) ({ \
+ long ret; \
+ asm volatile ( \
+ "syscall" \
+ : "=a"(ret) \
+ : "a"(n), "D"(arg1), "S"(arg2) \
+ : "rcx", "r11", "memory" \
+ ); \
+ ret; \
+ })
+
+#define syscall3(n, arg1, arg2, arg3) ({ \
+ long ret; \
+ asm volatile ( \
+ "syscall" \
+ : "=a"(ret) \
+ : "a"(n), "D"(arg1), "S"(arg2), "d"(arg3) \
+ : "rcx", "r11", "memory" \
+ ); \
+ ret; \
+ })
+
/* open flags */
#define o_rdonly 00
#define o_wronly 01
#define o_rdwr 02
#define o_creat 0100
+#define o_directory 0200000
/* syscall numbers */
#define sys_read 0
@@ -37,7 +80,10 @@ typedef long ssize_t;
#define sys_execve 59
#define sys_exit 60
#define sys_waitpid 61
+#define sys_getcwd 79
+#define sys_chdir 80
#define sys_mount 165
+#define sys_getdents64 217
/* mmap flags */
#define prot_read 0x1
@@ -61,10 +107,13 @@ int execvp(const char *file, char *const argv[]);
int fork(void);
int waitpid(int pid, int *status, int options);
int mount(const char *source,
- const char *target,
- const char *filesystemtype,
- ulong_t mountflags,
- const void *data);
+ const char *target,
+ const char *filesystemtype,
+ ulong_t mountflags,
+ const void *data);
+int chdir(const char *path);
+char *getcwd(char *buf, size_t size);
+int getdents64(int fd, struct linux_dirent64 *dirp, unsigned int count);
/* memory prototypes */
void* mmap(void *addr, size_t length, int prot, int flags, int fd, long offset);
diff --git a/mkfile b/mkfile
@@ -22,6 +22,9 @@ ofiles = start.$o \
malloc.$o \
calloc.$o \
realloc.$o \
+ getcwd.$o \
+ chdir.$o \
+ getdents.$o \
strlen.$o \
strchr.$o \
strcmp.$o \
diff --git a/munmap.c b/munmap.c
@@ -6,14 +6,7 @@
#include "libc.h"
int munmap(void *addr, size_t length) {
- long ret;
-
- asm volatile (
- "syscall"
- : "=a"(ret)
- : "a"(sys_munmap), "D"(addr), "S"(length)
- : "rcx", "r11", "memory"
- );
+ long ret = syscall2(sys_munmap, addr, length);
return (int)ret;
}
diff --git a/open.c b/open.c
@@ -6,14 +6,7 @@
#include "libc.h"
int open(const char *filename, int flags, int mode) {
- long ret;
-
- asm volatile (
- "syscall"
- : "=a"(ret)
- : "a"(sys_open), "D"(filename), "S"(flags), "d"(mode)
- : "rcx", "r11", "memory"
- );
+ long ret = syscall3(sys_open, filename, flags, mode);
return ret;
}
diff --git a/read.c b/read.c
@@ -6,14 +6,7 @@
#include "libc.h"
ssize_t read(int fd, void *buf, size_t count) {
- long ret;
-
- asm volatile (
- "syscall"
- : "=a"(ret)
- : "a"(sys_read), "D"(fd), "S"(buf), "d"(count)
- : "rcx", "r11", "memory"
- );
+ long ret = syscall3(sys_read, fd, buf, count);
return ret;
}
diff --git a/write.c b/write.c
@@ -6,14 +6,7 @@
#include "libc.h"
ssize_t write(int fd, const void *buf, size_t count) {
- long ret;
-
- asm volatile (
- "syscall"
- : "=a"(ret)
- : "a"(sys_write), "D"(fd), "S"(buf), "d"(count)
- : "rcx", "r11", "memory"
- );
+ long ret = syscall3(sys_write, fd, buf, count);
return ret;
}