Files
claude-os/apps/libc/syscalls.h

338 lines
9.2 KiB
C

/**
* @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
#define SYS_GFX 18
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);
}
/* ================================================================
* Graphics system calls
* ================================================================ */
/** Graphics sub-commands. */
#define GFX_CMD_ENTER 0
#define GFX_CMD_LEAVE 1
#define GFX_CMD_PIXEL 2
#define GFX_CMD_CLEAR 3
#define GFX_CMD_FILL_RECT 4
#define GFX_CMD_LINE 5
#define GFX_CMD_CIRCLE 6
#define GFX_CMD_GET_INFO 7
/** Graphics mode dimensions. */
#define GFX_WIDTH 320
#define GFX_HEIGHT 200
/** Palette color constants. */
#define GFX_BLACK 0
#define GFX_BLUE 1
#define GFX_GREEN 2
#define GFX_CYAN 3
#define GFX_RED 4
#define GFX_MAGENTA 5
#define GFX_BROWN 6
#define GFX_LIGHT_GREY 7
#define GFX_DARK_GREY 8
#define GFX_LIGHT_BLUE 9
#define GFX_LIGHT_GREEN 10
#define GFX_LIGHT_CYAN 11
#define GFX_LIGHT_RED 12
#define GFX_LIGHT_MAGENTA 13
#define GFX_YELLOW 14
#define GFX_WHITE 15
/** Command structs for complex drawing operations. */
typedef struct { uint32_t x, y, w, h, color; } gfx_rect_t;
typedef struct { uint32_t x1, y1, x2, y2, color; } gfx_line_t;
typedef struct { uint32_t cx, cy, r, color; } gfx_circle_t;
/** Convert RGB (0-255) to palette index using 6x6x6 color cube. */
static inline uint32_t gfx_rgb(uint32_t r, uint32_t g, uint32_t b) {
return 16 + (r / 51) * 36 + (g / 51) * 6 + (b / 51);
}
/** Enter graphics mode (320x200x256). */
static inline int32_t gfx_enter(void) {
return syscall1(SYS_GFX, GFX_CMD_ENTER);
}
/** Leave graphics mode, return to text. */
static inline int32_t gfx_leave(void) {
return syscall1(SYS_GFX, GFX_CMD_LEAVE);
}
/** Set a pixel. */
static inline int32_t gfx_pixel(uint32_t x, uint32_t y, uint32_t color) {
return syscall3(SYS_GFX, GFX_CMD_PIXEL, (x | (y << 16)), color);
}
/** Clear screen with a color. */
static inline int32_t gfx_clear(uint32_t color) {
return syscall2(SYS_GFX, GFX_CMD_CLEAR, color);
}
/** Fill a rectangle. */
static inline int32_t gfx_fill_rect(const gfx_rect_t *r) {
return syscall2(SYS_GFX, GFX_CMD_FILL_RECT, (uint32_t)r);
}
/** Draw a line. */
static inline int32_t gfx_line(const gfx_line_t *l) {
return syscall2(SYS_GFX, GFX_CMD_LINE, (uint32_t)l);
}
/** Draw a filled circle. */
static inline int32_t gfx_circle(const gfx_circle_t *c) {
return syscall2(SYS_GFX, GFX_CMD_CIRCLE, (uint32_t)c);
}
/** Get graphics info: returns (width | height<<16). */
static inline int32_t gfx_get_info(void) {
return syscall1(SYS_GFX, GFX_CMD_GET_INFO);
}
/* 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 */