]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
POSIX compliance audit: fix syscall wrappers, headers, and commands
authorTulio A M Mendes <[email protected]>
Sun, 19 Apr 2026 18:38:13 +0000 (15:38 -0300)
committerTulio A M Mendes <[email protected]>
Sun, 19 Apr 2026 18:38:13 +0000 (15:38 -0300)
ulibc fixes:
- mkdir(): change from variadic to (path, mode_t) per POSIX
- stat/fstat/fstatat: use struct stat* instead of void*
- wait4: use pid_t return and struct rusage* parameter
- waitid: use siginfo_t* instead of void*
- lseek: return off_t instead of int
- pread/pwrite: return ssize_t, use off_t offset
- truncate/ftruncate: use off_t length
- chmod: use mode_t instead of int
- open(): extract mode from va_args (was silently ignored)
- openat(): extract mode and pass as 4th syscall arg
- Add pivot_root() wrapper (syscall 120 existed but had no wrapper)
- Add lstat() (delegates to stat, no symlinks in AdrOS)
- Add fchmod() stub (ENOSYS, no kernel syscall yet)

ulibc header fixes:
- unistd.h: add sys/types.h include, forward declare struct stat/rusage
- fcntl.h: add O_EXCL, O_NOCTTY, O_DIRECTORY, O_NOFOLLOW, AT_FDCWD,
  AT_SYMLINK_NOFOLLOW, AT_REMOVEDIR, AT_SYMLINK_FOLLOW, AT_EACCESS
- sys/stat.h: add lstat, fchmod declarations, fix mkdir/chmod types

newlib fixes:
- openat(): extract mode from va_args, pass as 4th arg (was _sc3)
- Add pivot_root() wrapper

command fixes:
- mkdir: pass mode 0755 to mkdir() calls (was calling with 0 args)
- stat: remove unnecessary void* cast
- df: replace hardcoded stub with /proc/mounts reader

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

newlib/libgloss/adros/posix_stubs.c
user/cmds/df/df.c
user/cmds/mkdir/mkdir.c
user/cmds/stat/stat.c
user/ulibc/include/fcntl.h
user/ulibc/include/sys/stat.h
user/ulibc/include/unistd.h
user/ulibc/src/unistd.c

index b9c052cfd3fea01c9a7672ac9e5a51c7ca326ecb..4952bfd8f98198a415fd505f1d9d787c7f472c30 100644 (file)
@@ -567,7 +567,11 @@ int dup3(int oldfd, int newfd, int flags) {
 }
 
 int openat(int dirfd, const char *path, int flags, ...) {
-    return _check(_sc3(SYS_OPENAT, dirfd, (int)path, flags));
+    va_list ap;
+    va_start(ap, flags);
+    int mode = va_arg(ap, int);
+    va_end(ap);
+    return _check(_sc4(SYS_OPENAT, dirfd, (int)path, flags, mode));
 }
 
 int fstatat(int dirfd, const char *path, struct stat *buf, int flags) {
@@ -740,6 +744,10 @@ void *sbrk(intptr_t increment) {
     return cur;
 }
 
+int pivot_root(const char *new_root, const char *put_old) {
+    return _check(_sc2(SYS_PIVOT_ROOT, (int)new_root, (int)put_old));
+}
+
 int mkfifo(const char *path, mode_t mode) {
     (void)path; (void)mode;
     errno = ENOSYS;
index 0929e41b2eda92f862952a34c70b9975a60ef674..9eacf3db52f9e04974d278eeb6949566278223e1 100644 (file)
@@ -9,11 +9,20 @@
 
 /* AdrOS df utility — display filesystem disk space usage */
 #include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
 
 int main(void) {
+    int fd = open("/proc/mounts", O_RDONLY);
+    if (fd < 0) {
+        fprintf(stderr, "df: cannot open /proc/mounts\n");
+        return 1;
+    }
     printf("Filesystem     Size  Used  Avail  Use%%  Mounted on\n");
-    printf("overlayfs         -     -      -     -  /\n");
-    printf("devfs             -     -      -     -  /dev\n");
-    printf("procfs            -     -      -     -  /proc\n");
+    char buf[1024];
+    int n;
+    while ((n = read(fd, buf, sizeof(buf))) > 0)
+        write(STDOUT_FILENO, buf, (size_t)n);
+    close(fd);
     return 0;
 }
index 4e803efb6ceb80841f4b7ab977f77d96c54fdd91..45e6b2ecc9c19d4a1a69970b759ca72164f6c06d 100644 (file)
@@ -11,6 +11,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/stat.h>
 
 static int pflag = 0;   /* -p: create parent directories */
 
@@ -23,11 +24,11 @@ static int mkdir_p(const char* path) {
     for (char* p = tmp + 1; *p; p++) {
         if (*p == '/') {
             *p = '\0';
-            mkdir(tmp);   /* ignore errors — parent may already exist */
+            mkdir(tmp, 0755);   /* ignore errors — parent may already exist */
             *p = '/';
         }
     }
-    return mkdir(tmp);
+    return mkdir(tmp, 0755);
 }
 
 int main(int argc, char** argv) {
@@ -59,7 +60,7 @@ int main(int argc, char** argv) {
         if (pflag) {
             r = mkdir_p(argv[i]);
         } else {
-            r = mkdir(argv[i]);
+            r = mkdir(argv[i], 0755);
         }
         if (r < 0) {
             fprintf(stderr, "mkdir: cannot create directory '%s'\n", argv[i]);
index 1460fb3b3535638094dacf86d947c52f935ac540..fdd33fff48e944ebc08201d2f32482a2ed14ce24 100644 (file)
@@ -21,7 +21,7 @@ int main(int argc, char** argv) {
     int rc = 0;
     for (int i = 1; i < argc; i++) {
         struct stat st;
-        if (stat(argv[i], (void*)&st) < 0) {
+        if (stat(argv[i], &st) < 0) {
             fprintf(stderr, "stat: cannot stat '%s'\n", argv[i]);
             rc = 1;
             continue;
index 11f92e4e2c977000da201ca142230802928a6898..d277b84c3aa9b0ca968a538ff2b7af731d3eca8f 100644 (file)
 #define O_WRONLY    0x0001
 #define O_RDWR      0x0002
 #define O_CREAT     0x0040
+#define O_EXCL      0x0080
+#define O_NOCTTY    0x0100
 #define O_TRUNC     0x0200
 #define O_APPEND    0x0400
 #define O_NONBLOCK  0x0800
+#define O_DIRECTORY 0x10000
+#define O_NOFOLLOW  0x20000
 #define O_CLOEXEC   0x80000
 
 #define F_DUPFD     0
 
 #define FD_CLOEXEC  1
 
+/* AT_* constants for *at() syscalls */
+#define AT_FDCWD         -100
+#define AT_SYMLINK_NOFOLLOW 0x100
+#define AT_REMOVEDIR     0x200
+#define AT_SYMLINK_FOLLOW  0x400
+#define AT_EACCESS       0x0400
+
 /* Record lock types */
 #define F_RDLCK     0
 #define F_WRLCK     1
index 42739674a8b2dc5b0b06bf7d8596d8fadc61df5f..be90b783e530c8dd9e1370f5cf2967fe904d2c87 100644 (file)
@@ -51,7 +51,9 @@ struct stat {
 
 int stat(const char* path, struct stat* buf);
 int fstat(int fd, struct stat* buf);
-int mkdir(const char* path, ...);
-int chmod(const char* path, int mode);
+int lstat(const char* path, struct stat* buf);
+int mkdir(const char* path, mode_t mode);
+int chmod(const char* path, mode_t mode);
+int fchmod(int fd, mode_t mode);
 
 #endif
index 066800ebc5843c63463589b916a5552eed7c633e..c757910dc78829686a416aacbf4c839492980103 100644 (file)
 
 #include <stdint.h>
 #include <stddef.h>
+#include <sys/types.h>
 #include <signal.h>
 
+struct stat;
+struct rusage;
+
 #define SEEK_SET 0
 #define SEEK_CUR 1
 #define SEEK_END 2
@@ -26,7 +30,7 @@ int     read(int fd, void* buf, size_t count);
 int     write(int fd, const void* buf, size_t count);
 int     open(const char* path, int flags, ...);
 int     close(int fd);
-int     lseek(int fd, int offset, int whence);
+off_t   lseek(int fd, off_t offset, int whence);
 int     dup(int oldfd);
 int     dup2(int oldfd, int newfd);
 int     pipe(int fds[2]);
@@ -36,7 +40,7 @@ int     getpid(void);
 int     getppid(void);
 int     chdir(const char* path);
 char*   getcwd(char* buf, size_t size);
-int     mkdir(const char* path, ...);  /* mode_t optional in AdrOS */
+int     mkdir(const char* path, mode_t mode);
 int     unlink(const char* path);
 int     rmdir(const char* path);
 int     setsid(void);
@@ -45,8 +49,8 @@ int     getpgrp(void);
 int     gettid(void);
 int     fsync(int fd);
 int     fdatasync(int fd);
-int     pread(int fd, void* buf, size_t count, int offset);
-int     pwrite(int fd, const void* buf, size_t count, int offset);
+ssize_t pread(int fd, void* buf, size_t count, off_t offset);
+ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset);
 int     access(const char* path, int mode);
 int     getuid(void);
 int     getgid(void);
@@ -56,8 +60,8 @@ int     setuid(int uid);
 int     setgid(int gid);
 int     seteuid(int euid);
 int     setegid(int egid);
-int     truncate(const char* path, int length);
-int     ftruncate(int fd, int length);
+int     truncate(const char* path, off_t length);
+int     ftruncate(int fd, off_t length);
 unsigned int alarm(unsigned int seconds);
 #define LOCK_SH 1
 #define LOCK_EX 2
@@ -70,7 +74,7 @@ void*   brk(void* addr);
 
 int     waitpid(int pid, int* status, int options);
 int     getdents(int fd, void* buf, size_t count);
-int     chmod(const char* path, int mode);
+int     chmod(const char* path, mode_t mode);
 int     chown(const char* path, int owner, int group);
 int     link(const char* oldpath, const char* newpath);
 int     symlink(const char* target, const char* linkpath);
@@ -116,16 +120,17 @@ 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     fstatat(int dirfd, const char* path, struct stat* 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);
+pid_t   wait4(pid_t pid, int* status, int options, struct rusage* rusage);
+int     waitid(int idtype, int id, siginfo_t* info, int options);
 int     sigreturn(void);
 int     sigqueue(int pid, int sig, const union sigval value);
 int     set_thread_area(void* desc);
+int     pivot_root(const char* new_root, const char* put_old);
 char*   getlogin(void);
 int     getlogin_r(char* buf, size_t bufsize);
 int     tcgetpgrp(int fd);
index f0b79279ba01f1a6fbd0615af8f1b5965f4b734e..748b78a48a77649baa62a3f92593f88d1b315a22 100644 (file)
@@ -14,6 +14,8 @@
 #include "stdlib.h"
 #include "sys/select.h"
 #include "sys/time.h"
+#include "sys/stat.h"
+#include "sys/resource.h"
 #include "signal.h"
 
 int read(int fd, void* buf, size_t count) {
@@ -25,7 +27,11 @@ int write(int fd, const void* buf, size_t count) {
 }
 
 int open(const char* path, int flags, ...) {
-    (void)flags; /* mode arg unused by kernel currently */
+    __builtin_va_list ap;
+    __builtin_va_start(ap, flags);
+    int mode = __builtin_va_arg(ap, int);
+    __builtin_va_end(ap);
+    (void)mode; /* kernel ignores mode currently */
     return __syscall_ret(_syscall2(SYS_OPEN, (int)path, flags));
 }
 
@@ -33,8 +39,8 @@ int close(int fd) {
     return __syscall_ret(_syscall1(SYS_CLOSE, fd));
 }
 
-int lseek(int fd, int offset, int whence) {
-    return __syscall_ret(_syscall3(SYS_LSEEK, fd, offset, whence));
+off_t lseek(int fd, off_t offset, int whence) {
+    return __syscall_ret(_syscall3(SYS_LSEEK, fd, (int)offset, whence));
 }
 
 int dup(int oldfd) {
@@ -90,7 +96,8 @@ char* getcwd(char* buf, size_t size) {
     return buf;
 }
 
-int mkdir(const char* path, ...) {
+int mkdir(const char* path, mode_t mode) {
+    (void)mode; /* kernel ignores mode currently */
     return __syscall_ret(_syscall1(SYS_MKDIR, (int)path));
 }
 
@@ -126,12 +133,12 @@ int fdatasync(int fd) {
     return __syscall_ret(_syscall1(SYS_FDATASYNC, fd));
 }
 
-int pread(int fd, void* buf, size_t count, int offset) {
-    return __syscall_ret(_syscall4(SYS_PREAD, fd, (int)buf, (int)count, offset));
+ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
+    return __syscall_ret(_syscall4(SYS_PREAD, fd, (int)buf, (int)count, (int)offset));
 }
 
-int pwrite(int fd, const void* buf, size_t count, int offset) {
-    return __syscall_ret(_syscall4(SYS_PWRITE, fd, (int)buf, (int)count, offset));
+ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) {
+    return __syscall_ret(_syscall4(SYS_PWRITE, fd, (int)buf, (int)count, (int)offset));
 }
 
 int access(const char* path, int mode) {
@@ -170,12 +177,12 @@ int setegid(int egid) {
     return __syscall_ret(_syscall1(SYS_SETEGID, egid));
 }
 
-int truncate(const char* path, int length) {
-    return __syscall_ret(_syscall2(SYS_TRUNCATE, (int)path, length));
+int truncate(const char* path, off_t length) {
+    return __syscall_ret(_syscall2(SYS_TRUNCATE, (int)path, (int)length));
 }
 
-int ftruncate(int fd, int length) {
-    return __syscall_ret(_syscall2(SYS_FTRUNCATE, fd, length));
+int ftruncate(int fd, off_t length) {
+    return __syscall_ret(_syscall2(SYS_FTRUNCATE, fd, (int)length));
 }
 
 unsigned int alarm(unsigned int seconds) {
@@ -214,16 +221,26 @@ int getdents(int fd, void* buf, size_t count) {
     return __syscall_ret(_syscall3(SYS_GETDENTS, fd, (int)buf, (int)count));
 }
 
-int stat(const char* path, void* buf) {
+int stat(const char* path, struct stat* buf) {
     return __syscall_ret(_syscall2(SYS_STAT, (int)path, (int)buf));
 }
 
-int fstat(int fd, void* buf) {
+int fstat(int fd, struct stat* buf) {
     return __syscall_ret(_syscall2(SYS_FSTAT, fd, (int)buf));
 }
 
-int chmod(const char* path, int mode) {
-    return __syscall_ret(_syscall2(SYS_CHMOD, (int)path, mode));
+int lstat(const char* path, struct stat* buf) {
+    return stat(path, buf);  /* no symlinks in AdrOS, same as stat */
+}
+
+int chmod(const char* path, mode_t mode) {
+    return __syscall_ret(_syscall2(SYS_CHMOD, (int)path, (int)mode));
+}
+
+int fchmod(int fd, mode_t mode) {
+    (void)fd; (void)mode;
+    errno = ENOSYS;
+    return -1;
 }
 
 int chown(const char* path, int owner, int group) {
@@ -343,10 +360,14 @@ int dup3(int oldfd, int newfd, int flags) {
 }
 
 int openat(int dirfd, const char* path, int flags, ...) {
-    return __syscall_ret(_syscall3(SYS_OPENAT, dirfd, (int)path, flags));
+    __builtin_va_list ap;
+    __builtin_va_start(ap, flags);
+    int mode = __builtin_va_arg(ap, int);
+    __builtin_va_end(ap);
+    return __syscall_ret(_syscall4(SYS_OPENAT, dirfd, (int)path, flags, mode));
 }
 
-int fstatat(int dirfd, const char* path, void* buf, int flags) {
+int fstatat(int dirfd, const char* path, struct stat* buf, int flags) {
     return __syscall_ret(_syscall4(SYS_FSTATAT, dirfd, (int)path, (int)buf, flags));
 }
 
@@ -366,11 +387,11 @@ 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));
+pid_t wait4(pid_t pid, int* status, int options, struct rusage* rusage) {
+    return __syscall_ret(_syscall4(SYS_WAIT4, (int)pid, (int)status, options, (int)rusage));
 }
 
-int waitid(int idtype, int id, void* info, int options) {
+int waitid(int idtype, int id, siginfo_t* info, int options) {
     return __syscall_ret(_syscall4(SYS_WAITID, idtype, id, (int)info, options));
 }
 
@@ -385,3 +406,7 @@ int sigqueue(int pid, int sig, const union sigval value) {
 int set_thread_area(void* desc) {
     return __syscall_ret(_syscall1(SYS_SET_THREAD_AREA, (int)desc));
 }
+
+int pivot_root(const char* new_root, const char* put_old) {
+    return __syscall_ret(_syscall2(SYS_PIVOT_ROOT, (int)new_root, (int)put_old));
+}