/** * @file syscalls.h * @brief User-space system call wrappers for ClaudeOS. * * Provides inline functions that invoke INT 0x80 with the appropriate * system call numbers and arguments. */ #ifndef USERSPACE_SYSCALLS_H #define USERSPACE_SYSCALLS_H typedef unsigned int uint32_t; typedef int int32_t; /* System call numbers (must match kernel's syscall.h) */ #define SYS_EXIT 0 #define SYS_WRITE 1 #define SYS_READ 2 #define SYS_FORK 3 #define SYS_GETPID 4 #define SYS_YIELD 5 #define SYS_WAITPID 6 #define SYS_EXEC 7 #define SYS_GETENV 8 #define SYS_SETENV 9 #define SYS_READDIR 10 #define SYS_OPEN 11 #define SYS_CLOSE 12 #define SYS_SOCKET 13 #define SYS_CONNECT 14 #define SYS_SEND 15 #define SYS_RECV 16 #define SYS_SOCKSTATE 17 static inline int32_t syscall0(int num) { int32_t ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(num)); return ret; } static inline int32_t syscall1(int num, uint32_t arg1) { int32_t ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(num), "b"(arg1)); return ret; } static inline int32_t syscall2(int num, uint32_t arg1, uint32_t arg2) { int32_t ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(num), "b"(arg1), "c"(arg2)); return ret; } static inline int32_t syscall3(int num, uint32_t arg1, uint32_t arg2, uint32_t arg3) { int32_t ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(num), "b"(arg1), "c"(arg2), "d"(arg3)); return ret; } static inline void exit(int code) { syscall1(SYS_EXIT, (uint32_t)code); __builtin_unreachable(); } static inline int32_t write(int fd, const void *buf, uint32_t len) { return syscall3(SYS_WRITE, (uint32_t)fd, (uint32_t)buf, len); } static inline int32_t read(int fd, void *buf, uint32_t len) { return syscall3(SYS_READ, (uint32_t)fd, (uint32_t)buf, len); } static inline int32_t fork(void) { return syscall0(SYS_FORK); } static inline int32_t getpid(void) { return syscall0(SYS_GETPID); } static inline void yield(void) { syscall0(SYS_YIELD); } static inline int32_t waitpid(int32_t pid) { return syscall1(SYS_WAITPID, (uint32_t)pid); } static inline int32_t exec(const char *path) { return syscall1(SYS_EXEC, (uint32_t)path); } static inline int32_t getenv(const char *key, char *buf, uint32_t bufsize) { return syscall3(SYS_GETENV, (uint32_t)key, (uint32_t)buf, bufsize); } static inline int32_t setenv(const char *key, const char *value) { return syscall2(SYS_SETENV, (uint32_t)key, (uint32_t)value); } /** * Read a directory entry. * @param path Directory path. * @param idx Entry index (0-based). * @param name Buffer for entry name (128 bytes min). * @return Entry type (1=file, 2=dir) on success, -1 at end. */ static inline int32_t readdir(const char *path, uint32_t idx, char *name) { return syscall3(SYS_READDIR, (uint32_t)path, idx, (uint32_t)name); } /** * Open a file by path. * @param path File path. * @param flags Open flags (currently unused, pass 0). * @return File descriptor (>= 3) on success, -1 on failure. */ static inline int32_t open(const char *path, uint32_t flags) { return syscall2(SYS_OPEN, (uint32_t)path, flags); } /** * Close a file descriptor. * @param fd File descriptor. * @return 0 on success, -1 on failure. */ static inline int32_t close(int32_t fd) { return syscall1(SYS_CLOSE, (uint32_t)fd); } /* ================================================================ * Networking system calls * ================================================================ */ /** Socket type constants. */ #define SOCK_TCP 0 #define SOCK_UDP 1 /** TCP state constants (match kernel tcp.h). */ #define TCP_STATE_CLOSED 0 #define TCP_STATE_SYN_SENT 2 #define TCP_STATE_ESTABLISHED 4 #define TCP_STATE_CLOSE_WAIT 7 /** * Create a network socket. * @param type SOCK_TCP (0) or SOCK_UDP (1). * @return Socket descriptor (>= 0) or -1 on failure. */ static inline int32_t socket(uint32_t type) { return syscall1(SYS_SOCKET, type); } /** * Connect a TCP socket to a remote host. * @param sockfd Socket descriptor. * @param ip Remote IP address (host byte order). * @param port Remote port (host byte order). * @return 0 on success (SYN sent), -1 on failure. */ static inline int32_t connect(int32_t sockfd, uint32_t ip, uint32_t port) { return syscall3(SYS_CONNECT, (uint32_t)sockfd, ip, port); } /** * Send data on a connected socket. * @param sockfd Socket descriptor. * @param buf Data buffer. * @param len Data length. * @return Bytes sent, or -1 on failure. */ static inline int32_t net_send(int32_t sockfd, const void *buf, uint32_t len) { return syscall3(SYS_SEND, (uint32_t)sockfd, (uint32_t)buf, len); } /** * Receive data from a connected socket (non-blocking). * @param sockfd Socket descriptor. * @param buf Buffer. * @param bufsize Buffer size. * @return Bytes received, 0 if no data, -1 on error/closed. */ static inline int32_t net_recv(int32_t sockfd, void *buf, uint32_t bufsize) { return syscall3(SYS_RECV, (uint32_t)sockfd, (uint32_t)buf, bufsize); } /** * Get the state of a TCP socket. * @param sockfd Socket descriptor. * @return TCP state constant, or -1. */ static inline int32_t sockstate(int32_t sockfd) { return syscall1(SYS_SOCKSTATE, (uint32_t)sockfd); } /* Basic string operations for user-space */ static inline uint32_t strlen(const char *s) { uint32_t len = 0; while (s[len]) len++; return len; } static inline int strcmp(const char *a, const char *b) { while (*a && *a == *b) { a++; b++; } return (unsigned char)*a - (unsigned char)*b; } static inline int strncmp(const char *a, const char *b, uint32_t n) { while (n && *a && *a == *b) { a++; b++; n--; } return n ? ((unsigned char)*a - (unsigned char)*b) : 0; } static inline char *strcpy(char *dst, const char *src) { char *d = dst; while ((*d++ = *src++)); return dst; } static inline char *strncpy(char *dst, const char *src, uint32_t n) { char *d = dst; while (n && (*d++ = *src++)) n--; while (n--) *d++ = '\0'; return dst; } static inline void *memset(void *s, int c, uint32_t n) { unsigned char *p = (unsigned char *)s; while (n--) *p++ = (unsigned char)c; return s; } static inline void *memcpy(void *dst, const void *src, uint32_t n) { unsigned char *d = (unsigned char *)dst; const unsigned char *s = (const unsigned char *)src; while (n--) *d++ = *s++; return dst; } /** Print a string to stdout. */ static inline void puts(const char *s) { write(1, s, strlen(s)); } /** Print a single character to stdout. */ static inline void putchar(char c) { write(1, &c, 1); } #endif /* USERSPACE_SYSCALLS_H */