]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
Complete syscall coverage in ulibc and newlib wrappers
authorTulio A M Mendes <[email protected]>
Sun, 19 Apr 2026 18:12:28 +0000 (15:12 -0300)
committerTulio A M Mendes <[email protected]>
Sun, 19 Apr 2026 18:12:28 +0000 (15:12 -0300)
Audit of all 141 kernel syscalls vs ulibc/newlib wrappers revealed
many missing implementations. Both libraries had syscall numbers
defined but no corresponding POSIX wrapper functions.

ulibc additions (unistd.c):
  - select, fcntl, rename (was stub returning -1), umask
  - dup3, openat, fstatat, unlinkat
  - mount, umount2, umount
  - wait4, waitid, sigreturn, sigqueue, set_thread_area

ulibc header updates:
  - unistd.h: declarations for all new functions
  - signal.h: union sigval, sigqueue, sigreturn declarations
  - sys/mount.h: new header with mount/umount2/umount + flags
  - Removed old rename() stub from stdio.c

newlib additions (posix_stubs.c):
  - Complete syscall number table (was 32 entries, now all 141)
  - All missing POSIX wrappers: fcntl, rename, rmdir, mkdir, unlink,
    dup3, openat, fstatat, unlinkat, mount, umount2, umount, wait4,
    waitid, sigreturn, sigqueue, set_thread_area, pread, pwrite,
    truncate, ftruncate, fsync, fdatasync, sigpending, sigsuspend,
    readv, writev, times, flock, setitimer, getitimer, link, symlink,
    readlink, pipe2, clock_gettime, gettimeofday, mmap, munmap,
    mprotect, madvise, getrlimit, setrlimit, getrusage, uname,
    brk, sbrk
  - Added includes: sys/mman.h, sys/resource.h, sys/utsname.h,
    sys/uio.h, sys/times.h, sys/wait.h

Fix: setitimer/getitimer signatures corrected from void* to
struct itimerval* to match sys/time.h declarations.

Tests: 103/103 PASS, 16/16 battery PASS, 69/69 host PASS.

newlib/libgloss/adros/posix_stubs.c
user/ulibc/include/signal.h
user/ulibc/include/sys/mount.h [new file with mode: 0644]
user/ulibc/include/unistd.h
user/ulibc/src/stdio.c
user/ulibc/src/unistd.c

index c796b0b68fd335c351a2f75c650859a35a008172..b9c052cfd3fea01c9a7672ac9e5a51c7ca326ecb 100644 (file)
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/select.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/utsname.h>
+#include <sys/uio.h>
+#include <sys/times.h>
+#include <sys/wait.h>
 #include <termios.h>
 #include <signal.h>
 #include <unistd.h>
 #include <time.h>
 
 /* ---- AdrOS syscall numbers (must match include/syscall.h) ---- */
+#define SYS_EXIT        2
+#define SYS_GETPID      3
+#define SYS_OPEN        4
+#define SYS_READ        5
+#define SYS_CLOSE       6
 #define SYS_WAITPID     7
+#define SYS_LSEEK       9
+#define SYS_FSTAT       10
+#define SYS_STAT        11
 #define SYS_DUP         12
 #define SYS_DUP2        13
 #define SYS_PIPE        14
+#define SYS_EXECVE      15
+#define SYS_FORK        16
 #define SYS_GETPPID     17
 #define SYS_POLL        18
+#define SYS_KILL        19
 #define SYS_SELECT      20
 #define SYS_IOCTL       21
 #define SYS_SETSID      22
 #define SYS_GETPGRP     24
 #define SYS_SIGACTION   25
 #define SYS_SIGPROCMASK 26
+#define SYS_SIGRETURN   27
+#define SYS_MKDIR       28
+#define SYS_UNLINK      29
 #define SYS_GETDENTS    30
 #define SYS_FCNTL       31
 #define SYS_CHDIR       32
 #define SYS_GETCWD      33
+#define SYS_PIPE2       34
+#define SYS_DUP3        35
+#define SYS_OPENAT      36
+#define SYS_FSTATAT     37
+#define SYS_UNLINKAT    38
+#define SYS_RENAME      39
+#define SYS_RMDIR       40
+#define SYS_BRK         41
 #define SYS_NANOSLEEP   42
+#define SYS_CLOCK_GETTIME 43
+#define SYS_MMAP        44
+#define SYS_MUNMAP      45
+#define SYS_SHMGET      46
+#define SYS_SHMAT       47
+#define SYS_SHMDT       48
+#define SYS_SHMCTL      49
 #define SYS_CHMOD       50
 #define SYS_CHOWN       51
 #define SYS_GETUID      52
 #define SYS_GETGID      53
+#define SYS_LINK        54
+#define SYS_SYMLINK     55
+#define SYS_READLINK    56
+#define SYS_SET_THREAD_AREA 57
+#define SYS_SOCKET      58
+#define SYS_BIND        59
+#define SYS_LISTEN      60
+#define SYS_ACCEPT      61
+#define SYS_CONNECT     62
+#define SYS_SEND        63
+#define SYS_RECV        64
+#define SYS_SENDTO      65
+#define SYS_RECVFROM    66
+#define SYS_CLONE       67
+#define SYS_GETTID      68
+#define SYS_FSYNC       69
+#define SYS_FDATASYNC   70
+#define SYS_SIGPENDING  71
+#define SYS_PREAD       72
+#define SYS_PWRITE      73
 #define SYS_ACCESS      74
 #define SYS_UMASK       75
 #define SYS_SETUID      76
 #define SYS_SETGID      77
+#define SYS_TRUNCATE    78
+#define SYS_FTRUNCATE   79
+#define SYS_SIGSUSPEND  80
+#define SYS_READV       81
+#define SYS_WRITEV      82
 #define SYS_ALARM       83
+#define SYS_TIMES       84
+#define SYS_FUTEX       85
+#define SYS_SIGALTSTACK 86
+#define SYS_FLOCK       87
 #define SYS_GETEUID     88
 #define SYS_GETEGID     89
 #define SYS_SETEUID     90
 #define SYS_SETEGID     91
+#define SYS_SETITIMER   92
+#define SYS_GETITIMER   93
+#define SYS_WAITID      94
+#define SYS_SIGQUEUE    95
+#define SYS_POSIX_SPAWN 96
+#define SYS_MQ_OPEN     97
+#define SYS_MQ_CLOSE    98
+#define SYS_MQ_SEND     99
+#define SYS_MQ_RECEIVE  100
+#define SYS_MQ_UNLINK   101
+#define SYS_SEM_OPEN    102
+#define SYS_SEM_CLOSE   103
+#define SYS_SEM_WAIT    104
+#define SYS_SEM_POST    105
+#define SYS_SEM_UNLINK  106
+#define SYS_SEM_GETVALUE 107
+#define SYS_GETADDRINFO 108
+#define SYS_DLOPEN      109
+#define SYS_DLSYM       110
+#define SYS_DLCLOSE     111
+#define SYS_EPOLL_CREATE 112
+#define SYS_EPOLL_CTL   113
+#define SYS_EPOLL_WAIT  114
+#define SYS_INOTIFY_INIT     115
+#define SYS_INOTIFY_ADD_WATCH 116
+#define SYS_INOTIFY_RM_WATCH  117
+#define SYS_SENDMSG     118
+#define SYS_RECVMSG     119
+#define SYS_PIVOT_ROOT  120
+#define SYS_AIO_READ    121
+#define SYS_AIO_WRITE   122
+#define SYS_AIO_ERROR   123
+#define SYS_AIO_RETURN  124
+#define SYS_AIO_SUSPEND 125
+#define SYS_MOUNT       126
+#define SYS_GETTIMEOFDAY 127
+#define SYS_MPROTECT    128
+#define SYS_GETRLIMIT   129
+#define SYS_SETRLIMIT   130
+#define SYS_SETSOCKOPT  131
+#define SYS_GETSOCKOPT  132
+#define SYS_SHUTDOWN    133
+#define SYS_GETPEERNAME 134
+#define SYS_GETSOCKNAME 135
+#define SYS_UNAME       136
+#define SYS_GETRUSAGE   137
+#define SYS_UMOUNT2     138
+#define SYS_WAIT4       139
+#define SYS_MADVISE     140
+#define SYS_EXECVEAT    141
 
 /* ---- Raw syscall helpers ---- */
 
@@ -419,6 +533,213 @@ int gethostname(char *name, size_t len) {
     errno = ENAMETOOLONG; return -1;
 }
 
+/* ================================================================
+ * Additional POSIX wrappers (previously missing)
+ * ================================================================ */
+
+int fcntl(int fd, int cmd, ...) {
+    va_list ap;
+    va_start(ap, cmd);
+    int arg = va_arg(ap, int);
+    va_end(ap);
+    return _check(_sc3(SYS_FCNTL, fd, cmd, arg));
+}
+
+int rename(const char *oldpath, const char *newpath) {
+    return _check(_sc2(SYS_RENAME, (int)oldpath, (int)newpath));
+}
+
+int rmdir(const char *path) {
+    return _check(_sc1(SYS_RMDIR, (int)path));
+}
+
+int mkdir(const char *path, mode_t mode) {
+    (void)mode;
+    return _check(_sc1(SYS_MKDIR, (int)path));
+}
+
+int unlink(const char *path) {
+    return _check(_sc1(SYS_UNLINK, (int)path));
+}
+
+int dup3(int oldfd, int newfd, int flags) {
+    return _check(_sc3(SYS_DUP3, oldfd, newfd, flags));
+}
+
+int openat(int dirfd, const char *path, int flags, ...) {
+    return _check(_sc3(SYS_OPENAT, dirfd, (int)path, flags));
+}
+
+int fstatat(int dirfd, const char *path, struct stat *buf, int flags) {
+    return _check(_sc4(SYS_FSTATAT, dirfd, (int)path, (int)buf, flags));
+}
+
+int unlinkat(int dirfd, const char *path, int flags) {
+    return _check(_sc3(SYS_UNLINKAT, dirfd, (int)path, flags));
+}
+
+int mount(const char *source, const char *target, const char *fs_type,
+          unsigned long flags, const void *data) {
+    return _check(_sc5(SYS_MOUNT, (int)source, (int)target, (int)fs_type, (int)flags, (int)data));
+}
+
+int umount2(const char *target, int flags) {
+    return _check(_sc2(SYS_UMOUNT2, (int)target, flags));
+}
+
+int umount(const char *target) {
+    return umount2(target, 0);
+}
+
+pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage) {
+    return (pid_t)_check(_sc4(SYS_WAIT4, (int)pid, (int)status, options, (int)rusage));
+}
+
+int waitid(int idtype, int id, void *info, int options) {
+    return _check(_sc4(SYS_WAITID, idtype, id, (int)info, options));
+}
+
+int sigreturn(void) {
+    return _sc0(SYS_SIGRETURN);
+}
+
+int sigqueue(pid_t pid, int sig, const union sigval value) {
+    return _check(_sc3(SYS_SIGQUEUE, (int)pid, sig, (int)value.sival_int));
+}
+
+int set_thread_area(void *desc) {
+    return _check(_sc1(SYS_SET_THREAD_AREA, (int)desc));
+}
+
+ssize_t pread(int fd, void *buf, size_t count, off_t offset) {
+    return (ssize_t)_check(_sc4(SYS_PREAD, fd, (int)buf, (int)count, (int)offset));
+}
+
+ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset) {
+    return (ssize_t)_check(_sc4(SYS_PWRITE, fd, (int)buf, (int)count, (int)offset));
+}
+
+int truncate(const char *path, off_t length) {
+    return _check(_sc2(SYS_TRUNCATE, (int)path, (int)length));
+}
+
+int ftruncate(int fd, off_t length) {
+    return _check(_sc2(SYS_FTRUNCATE, fd, (int)length));
+}
+
+int fsync(int fd) {
+    return _check(_sc1(SYS_FSYNC, fd));
+}
+
+int fdatasync(int fd) {
+    return _check(_sc1(SYS_FDATASYNC, fd));
+}
+
+int sigpending(sigset_t *set) {
+    return _check(_sc1(SYS_SIGPENDING, (int)set));
+}
+
+int sigsuspend(const sigset_t *mask) {
+    return _check(_sc1(SYS_SIGSUSPEND, (int)mask));
+}
+
+ssize_t readv(int fd, const struct iovec *iov, int iovcnt) {
+    return (ssize_t)_check(_sc3(SYS_READV, fd, (int)iov, iovcnt));
+}
+
+ssize_t writev(int fd, const struct iovec *iov, int iovcnt) {
+    return (ssize_t)_check(_sc3(SYS_WRITEV, fd, (int)iov, iovcnt));
+}
+
+clock_t times(struct tms *buf) {
+    return (clock_t)_sc1(SYS_TIMES, (int)buf);
+}
+
+int flock(int fd, int operation) {
+    return _check(_sc2(SYS_FLOCK, fd, operation));
+}
+
+int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value) {
+    return _check(_sc3(SYS_SETITIMER, which, (int)new_value, (int)old_value));
+}
+
+int getitimer(int which, struct itimerval *curr_value) {
+    return _check(_sc2(SYS_GETITIMER, which, (int)curr_value));
+}
+
+int link(const char *oldpath, const char *newpath) {
+    return _check(_sc2(SYS_LINK, (int)oldpath, (int)newpath));
+}
+
+int symlink(const char *target, const char *linkpath) {
+    return _check(_sc2(SYS_SYMLINK, (int)target, (int)linkpath));
+}
+
+ssize_t readlink(const char *path, char *buf, size_t bufsiz) {
+    return (ssize_t)_check(_sc3(SYS_READLINK, (int)path, (int)buf, (int)bufsiz));
+}
+
+int pipe2(int fds[2], int flags) {
+    return _check(_sc2(SYS_PIPE2, (int)fds, flags));
+}
+
+int clock_gettime(clockid_t clk_id, struct timespec *tp) {
+    return _check(_sc2(SYS_CLOCK_GETTIME, (int)clk_id, (int)tp));
+}
+
+int gettimeofday(struct timeval *tv, void *tz) {
+    (void)tz;
+    return _check(_sc2(SYS_GETTIMEOFDAY, (int)tv, 0));
+}
+
+void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) {
+    int ret = _sc5(SYS_MMAP, (int)addr, (int)length, prot, flags, fd);
+    (void)offset;
+    if (ret < 0 && ret > -4096) { errno = -ret; return MAP_FAILED; }
+    return (void *)ret;
+}
+
+int munmap(void *addr, size_t length) {
+    return _check(_sc2(SYS_MUNMAP, (int)addr, (int)length));
+}
+
+int mprotect(void *addr, size_t len, int prot) {
+    return _check(_sc3(SYS_MPROTECT, (int)addr, (int)len, prot));
+}
+
+int madvise(void *addr, size_t length, int advice) {
+    return _check(_sc3(SYS_MADVISE, (int)addr, (int)length, advice));
+}
+
+int getrlimit(int resource, struct rlimit *rlim) {
+    return _check(_sc2(SYS_GETRLIMIT, resource, (int)rlim));
+}
+
+int setrlimit(int resource, const struct rlimit *rlim) {
+    return _check(_sc2(SYS_SETRLIMIT, resource, (int)rlim));
+}
+
+int getrusage(int who, struct rusage *usage) {
+    return _check(_sc2(SYS_GETRUSAGE, who, (int)usage));
+}
+
+int uname(struct utsname *buf) {
+    return _check(_sc1(SYS_UNAME, (int)buf));
+}
+
+void *brk(void *addr) {
+    return (void *)_sc1(SYS_BRK, (int)addr);
+}
+
+void *sbrk(intptr_t increment) {
+    void *cur = brk(0);
+    if (increment == 0) return cur;
+    void *new_end = (void *)((char *)cur + increment);
+    void *result = brk(new_end);
+    if ((uintptr_t)result < (uintptr_t)new_end) return (void *)-1;
+    return cur;
+}
+
 int mkfifo(const char *path, mode_t mode) {
     (void)path; (void)mode;
     errno = ENOSYS;
index f0cd36f02271d52cebb57177b7a1766c998d59de..e8e143002de4757d4b7695fcf221e8869828b1d8 100644 (file)
@@ -66,6 +66,11 @@ struct siginfo {
 
 typedef struct siginfo siginfo_t;
 
+union sigval {
+    int   sival_int;
+    void* sival_ptr;
+};
+
 int kill(int pid, int sig);
 int raise(int sig);
 int sigaction(int signum, const struct sigaction* act,
@@ -106,5 +111,7 @@ typedef struct {
 } stack_t;
 
 int sigaltstack(const stack_t* ss, stack_t* old_ss);
+int sigqueue(int pid, int sig, const union sigval value);
+int sigreturn(void);
 
 #endif
diff --git a/user/ulibc/include/sys/mount.h b/user/ulibc/include/sys/mount.h
new file mode 100644 (file)
index 0000000..aa7561f
--- /dev/null
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2018, Tulio A M Mendes <[email protected]>
+ * All rights reserved.
+ * See LICENSE for details.
+ *
+ * Source: https://github.com/tadryanom/AdrOS
+ */
+
+#ifndef ULIBC_SYS_MOUNT_H
+#define ULIBC_SYS_MOUNT_H
+
+#include <stddef.h>
+
+/* Mount flags */
+#define MS_RDONLY      1
+#define MS_NOSUID      2
+#define MS_NODEV       4
+#define MS_NOEXEC      8
+#define MS_SYNCHRONOUS 16
+#define MS_REMOUNT     32
+#define MS_NOATIME     1024
+
+/* Umount flags */
+#define MNT_FORCE      1
+#define MNT_DETACH     2
+#define MNT_EXPIRE     4
+
+int mount(const char* source, const char* target, const char* fs_type,
+          unsigned long flags, const void* data);
+int umount2(const char* target, int flags);
+int umount(const char* target);
+
+#endif
index 3ca39ff17bffcf3c6b624e8aa5cd9cf05d36a45e..066800ebc5843c63463589b916a5552eed7c633e 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <stdint.h>
 #include <stddef.h>
+#include <signal.h>
 
 #define SEEK_SET 0
 #define SEEK_CUR 1
@@ -63,6 +64,7 @@ unsigned int alarm(unsigned int seconds);
 #define LOCK_UN 8
 #define LOCK_NB 4
 int     flock(int fd, int operation);
+int     umask(int mask);
 int     isatty(int fd);
 void*   brk(void* addr);
 
@@ -112,6 +114,18 @@ char*   ttyname(int fd);
 int     pipe2(int fds[2], int flags);
 int     execle(const char* path, const char* arg, ...);
 int     execveat(int dirfd, const char* path, char* const argv[], char* const envp[], int flags);
+int     dup3(int oldfd, int newfd, int flags);
+int     openat(int dirfd, const char* path, int flags, ...);
+int     fstatat(int dirfd, const char* path, void* buf, int flags);
+int     unlinkat(int dirfd, const char* path, int flags);
+int     mount(const char* source, const char* target, const char* fs_type, unsigned long flags, const void* data);
+int     umount2(const char* target, int flags);
+int     umount(const char* target);
+int     wait4(int pid, int* status, int options, void* rusage);
+int     waitid(int idtype, int id, void* info, int options);
+int     sigreturn(void);
+int     sigqueue(int pid, int sig, const union sigval value);
+int     set_thread_area(void* desc);
 char*   getlogin(void);
 int     getlogin_r(char* buf, size_t bufsize);
 int     tcgetpgrp(int fd);
index 257ed12ae696c69003f1118116de45e441d240a9..ce6092a2f325a96daf2e23ed1b450e15cea09970 100644 (file)
@@ -196,11 +196,6 @@ int remove(const char* path) {
     return unlink(path);
 }
 
-int rename(const char* oldpath, const char* newpath) {
-    (void)oldpath; (void)newpath;
-    return -1;
-}
-
 int setvbuf(FILE* fp, char* buf, int mode, size_t size) {
     (void)buf; (void)size; /* we use internal buffer only */
     if (!fp) return -1;
index 6dcadb35e478182e42503204f62de6d23241d0cf..f0b79279ba01f1a6fbd0615af8f1b5965f4b734e 100644 (file)
@@ -12,6 +12,9 @@
 #include "errno.h"
 #include "termios.h"
 #include "stdlib.h"
+#include "sys/select.h"
+#include "sys/time.h"
+#include "signal.h"
 
 int read(int fd, void* buf, size_t count) {
     return __syscall_ret(_syscall3(SYS_READ, fd, (int)buf, (int)count));
@@ -179,11 +182,11 @@ unsigned int alarm(unsigned int seconds) {
     return (unsigned int)_syscall1(SYS_ALARM, (int)seconds);
 }
 
-int setitimer(int which, const void* new_value, void* old_value) {
+int setitimer(int which, const struct itimerval* new_value, struct itimerval* old_value) {
     return __syscall_ret(_syscall3(SYS_SETITIMER, which, (int)new_value, (int)old_value));
 }
 
-int getitimer(int which, void* curr_value) {
+int getitimer(int which, struct itimerval* curr_value) {
     return __syscall_ret(_syscall2(SYS_GETITIMER, which, (int)curr_value));
 }
 
@@ -312,3 +315,73 @@ void* sbrk(int increment) {
     if ((unsigned int)result < (unsigned int)new_end) return (void*)-1;
     return cur;
 }
+
+int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
+           struct timeval* timeout) {
+    return __syscall_ret(_syscall5(SYS_SELECT, nfds, (int)readfds, (int)writefds,
+                                   (int)exceptfds, (int)timeout));
+}
+
+int fcntl(int fd, int cmd, ...) {
+    __builtin_va_list ap;
+    __builtin_va_start(ap, cmd);
+    int arg = __builtin_va_arg(ap, int);
+    __builtin_va_end(ap);
+    return __syscall_ret(_syscall3(SYS_FCNTL, fd, cmd, arg));
+}
+
+int rename(const char* oldpath, const char* newpath) {
+    return __syscall_ret(_syscall2(SYS_RENAME, (int)oldpath, (int)newpath));
+}
+
+int umask(int mask) {
+    return _syscall1(SYS_UMASK, mask);
+}
+
+int dup3(int oldfd, int newfd, int flags) {
+    return __syscall_ret(_syscall3(SYS_DUP3, oldfd, newfd, flags));
+}
+
+int openat(int dirfd, const char* path, int flags, ...) {
+    return __syscall_ret(_syscall3(SYS_OPENAT, dirfd, (int)path, flags));
+}
+
+int fstatat(int dirfd, const char* path, void* buf, int flags) {
+    return __syscall_ret(_syscall4(SYS_FSTATAT, dirfd, (int)path, (int)buf, flags));
+}
+
+int unlinkat(int dirfd, const char* path, int flags) {
+    return __syscall_ret(_syscall3(SYS_UNLINKAT, dirfd, (int)path, flags));
+}
+
+int mount(const char* source, const char* target, const char* fs_type, unsigned long flags, const void* data) {
+    return __syscall_ret(_syscall5(SYS_MOUNT, (int)source, (int)target, (int)fs_type, (int)flags, (int)data));
+}
+
+int umount2(const char* target, int flags) {
+    return __syscall_ret(_syscall2(SYS_UMOUNT2, (int)target, flags));
+}
+
+int umount(const char* target) {
+    return umount2(target, 0);
+}
+
+int wait4(int pid, int* status, int options, void* rusage) {
+    return __syscall_ret(_syscall4(SYS_WAIT4, pid, (int)status, options, (int)rusage));
+}
+
+int waitid(int idtype, int id, void* info, int options) {
+    return __syscall_ret(_syscall4(SYS_WAITID, idtype, id, (int)info, options));
+}
+
+int sigreturn(void) {
+    return _syscall0(SYS_SIGRETURN);
+}
+
+int sigqueue(int pid, int sig, const union sigval value) {
+    return __syscall_ret(_syscall3(SYS_SIGQUEUE, pid, sig, (int)value.sival_int));
+}
+
+int set_thread_area(void* desc) {
+    return __syscall_ret(_syscall1(SYS_SET_THREAD_AREA, (int)desc));
+}