]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
test: expand smoke tests to 44 — add epoll, inotify, aio_* coverage
authorTulio A M Mendes <[email protected]>
Sun, 15 Feb 2026 08:39:03 +0000 (05:39 -0300)
committerTulio A M Mendes <[email protected]>
Sun, 15 Feb 2026 08:39:03 +0000 (05:39 -0300)
tests/smoke_test.exp
user/init.c

index a4815f48d8dc1e45bd5a2d0737be745640d74617..0b0e3c26ef4a4e1bcbe31068056ed11c7f1a23bb 100755 (executable)
@@ -84,6 +84,9 @@ set tests {
     {"select regfile"       "\\[init\\] select regfile OK"}
     {"poll regfile"         "\\[init\\] poll regfile OK"}
     {"hard link"            "\\[init\\] hard link OK"}
+    {"epoll"                "\\[init\\] epoll OK"}
+    {"inotify"              "\\[init\\] inotify OK"}
+    {"aio"                  "\\[init\\] aio OK"}
 }
 
 # ---- Poll serial.log for results ----
index da3db773470c5bcc5cd55c2cda6c094a67287bbb..0a82dd40a67d05d46c46b47cb88e6b6f510fe0b0 100644 (file)
@@ -107,6 +107,19 @@ enum {
     SYSCALL_SETITIMER = 92,
     SYSCALL_GETITIMER = 93,
     SYSCALL_WAITID    = 94,
+
+    SYSCALL_EPOLL_CREATE = 112,
+    SYSCALL_EPOLL_CTL    = 113,
+    SYSCALL_EPOLL_WAIT   = 114,
+
+    SYSCALL_INOTIFY_INIT      = 115,
+    SYSCALL_INOTIFY_ADD_WATCH = 116,
+    SYSCALL_INOTIFY_RM_WATCH  = 117,
+
+    SYSCALL_AIO_READ    = 121,
+    SYSCALL_AIO_WRITE   = 122,
+    SYSCALL_AIO_ERROR   = 123,
+    SYSCALL_AIO_RETURN  = 124,
 };
 
 enum {
@@ -986,6 +999,125 @@ static int sys_waitid(uint32_t idtype, uint32_t id, void* infop, uint32_t option
     return __syscall_fix(ret);
 }
 
+static int sys_epoll_create(int size) {
+    int ret;
+    __asm__ volatile(
+        "int $0x80"
+        : "=a"(ret)
+        : "a"(SYSCALL_EPOLL_CREATE), "b"(size)
+        : "memory"
+    );
+    return __syscall_fix(ret);
+}
+
+static int sys_epoll_ctl(int epfd, int op, int fd, void* event) {
+    int ret;
+    __asm__ volatile(
+        "int $0x80"
+        : "=a"(ret)
+        : "a"(SYSCALL_EPOLL_CTL), "b"(epfd), "c"(op), "d"(fd), "S"(event)
+        : "memory"
+    );
+    return __syscall_fix(ret);
+}
+
+static int sys_epoll_wait(int epfd, void* events, int maxevents, int timeout) {
+    int ret;
+    __asm__ volatile(
+        "int $0x80"
+        : "=a"(ret)
+        : "a"(SYSCALL_EPOLL_WAIT), "b"(epfd), "c"(events), "d"(maxevents), "S"(timeout)
+        : "memory"
+    );
+    return __syscall_fix(ret);
+}
+
+static int sys_inotify_init(void) {
+    int ret;
+    __asm__ volatile(
+        "int $0x80"
+        : "=a"(ret)
+        : "a"(SYSCALL_INOTIFY_INIT)
+        : "memory"
+    );
+    return __syscall_fix(ret);
+}
+
+static int sys_inotify_add_watch(int fd, const char* path, uint32_t mask) {
+    int ret;
+    __asm__ volatile(
+        "int $0x80"
+        : "=a"(ret)
+        : "a"(SYSCALL_INOTIFY_ADD_WATCH), "b"(fd), "c"(path), "d"(mask)
+        : "memory"
+    );
+    return __syscall_fix(ret);
+}
+
+static int sys_inotify_rm_watch(int fd, int wd) {
+    int ret;
+    __asm__ volatile(
+        "int $0x80"
+        : "=a"(ret)
+        : "a"(SYSCALL_INOTIFY_RM_WATCH), "b"(fd), "c"(wd)
+        : "memory"
+    );
+    return __syscall_fix(ret);
+}
+
+struct aiocb {
+    int      aio_fildes;
+    void*    aio_buf;
+    uint32_t aio_nbytes;
+    uint32_t aio_offset;
+    int32_t  aio_error;
+    int32_t  aio_return;
+};
+
+static int sys_aio_read(struct aiocb* cb) {
+    int ret;
+    __asm__ volatile(
+        "int $0x80"
+        : "=a"(ret)
+        : "a"(SYSCALL_AIO_READ), "b"(cb)
+        : "memory"
+    );
+    return __syscall_fix(ret);
+}
+
+static int sys_aio_write(struct aiocb* cb) {
+    int ret;
+    __asm__ volatile(
+        "int $0x80"
+        : "=a"(ret)
+        : "a"(SYSCALL_AIO_WRITE), "b"(cb)
+        : "memory"
+    );
+    return __syscall_fix(ret);
+}
+
+static int sys_aio_error(struct aiocb* cb) {
+    int ret;
+    __asm__ volatile(
+        "int $0x80"
+        : "=a"(ret)
+        : "a"(SYSCALL_AIO_ERROR), "b"(cb)
+        : "memory"
+    );
+    return ret;
+}
+
+static int sys_aio_return(struct aiocb* cb) {
+    int ret;
+    __asm__ volatile(
+        "int $0x80"
+        : "=a"(ret)
+        : "a"(SYSCALL_AIO_RETURN), "b"(cb)
+        : "memory"
+    );
+    return ret;
+}
+
 __attribute__((noreturn)) static void sys_exit(int code) {
     __asm__ volatile(
         "int $0x80\n"
@@ -2928,6 +3060,127 @@ void _start(void) {
         }
     }
 
+    // C22: epoll_create/ctl/wait smoke
+    {
+        int epfd = sys_epoll_create(1);
+        if (epfd < 0) {
+            sys_write(1, "[init] epoll_create failed\n", (uint32_t)(sizeof("[init] epoll_create failed\n") - 1));
+            sys_exit(1);
+        }
+
+        int fds[2];
+        if (sys_pipe(fds) < 0) {
+            sys_write(1, "[init] epoll pipe failed\n", (uint32_t)(sizeof("[init] epoll pipe failed\n") - 1));
+            sys_exit(1);
+        }
+
+        struct { uint32_t events; uint32_t data; } ev;
+        ev.events = POLLIN;
+        ev.data = (uint32_t)fds[0];
+        if (sys_epoll_ctl(epfd, 1, fds[0], &ev) < 0) {
+            sys_write(1, "[init] epoll_ctl ADD failed\n", (uint32_t)(sizeof("[init] epoll_ctl ADD failed\n") - 1));
+            sys_exit(1);
+        }
+
+        struct { uint32_t events; uint32_t data; } out;
+        int n = sys_epoll_wait(epfd, &out, 1, 0);
+        if (n != 0) {
+            sys_write(1, "[init] epoll_wait expected 0\n", (uint32_t)(sizeof("[init] epoll_wait expected 0\n") - 1));
+            sys_exit(1);
+        }
+
+        (void)sys_write(fds[1], "E", 1);
+
+        n = sys_epoll_wait(epfd, &out, 1, 0);
+        if (n != 1 || !(out.events & POLLIN)) {
+            sys_write(1, "[init] epoll_wait expected POLLIN\n", (uint32_t)(sizeof("[init] epoll_wait expected POLLIN\n") - 1));
+            sys_exit(1);
+        }
+
+        (void)sys_close(fds[0]);
+        (void)sys_close(fds[1]);
+        (void)sys_close(epfd);
+        sys_write(1, "[init] epoll OK\n", (uint32_t)(sizeof("[init] epoll OK\n") - 1));
+    }
+
+    // C23: inotify_init/add_watch/rm_watch smoke
+    {
+        int ifd = sys_inotify_init();
+        if (ifd < 0) {
+            sys_write(1, "[init] inotify_init failed\n", (uint32_t)(sizeof("[init] inotify_init failed\n") - 1));
+            sys_exit(1);
+        }
+
+        int wd = sys_inotify_add_watch(ifd, "/tmp", 0x100);
+        if (wd < 0) {
+            sys_write(1, "[init] inotify_add_watch failed\n", (uint32_t)(sizeof("[init] inotify_add_watch failed\n") - 1));
+            sys_exit(1);
+        }
+
+        if (sys_inotify_rm_watch(ifd, wd) < 0) {
+            sys_write(1, "[init] inotify_rm_watch failed\n", (uint32_t)(sizeof("[init] inotify_rm_watch failed\n") - 1));
+            sys_exit(1);
+        }
+
+        (void)sys_close(ifd);
+        sys_write(1, "[init] inotify OK\n", (uint32_t)(sizeof("[init] inotify OK\n") - 1));
+    }
+
+    // C24: aio_read/aio_write smoke
+    {
+        int fd = sys_open("/disk/aiotest", O_CREAT | O_TRUNC);
+        if (fd < 0) {
+            sys_write(1, "[init] aio open failed\n", (uint32_t)(sizeof("[init] aio open failed\n") - 1));
+            sys_exit(1);
+        }
+
+        char wbuf[4] = {'A', 'I', 'O', '!'};
+        struct aiocb wcb;
+        wcb.aio_fildes = fd;
+        wcb.aio_buf = wbuf;
+        wcb.aio_nbytes = 4;
+        wcb.aio_offset = 0;
+        wcb.aio_error = -1;
+        wcb.aio_return = -1;
+        if (sys_aio_write(&wcb) < 0) {
+            sys_write(1, "[init] aio_write failed\n", (uint32_t)(sizeof("[init] aio_write failed\n") - 1));
+            sys_exit(1);
+        }
+        if (sys_aio_error(&wcb) != 0) {
+            sys_write(1, "[init] aio_error after write bad\n", (uint32_t)(sizeof("[init] aio_error after write bad\n") - 1));
+            sys_exit(1);
+        }
+        if (sys_aio_return(&wcb) != 4) {
+            sys_write(1, "[init] aio_return after write bad\n", (uint32_t)(sizeof("[init] aio_return after write bad\n") - 1));
+            sys_exit(1);
+        }
+
+        char rbuf[4] = {0, 0, 0, 0};
+        struct aiocb rcb;
+        rcb.aio_fildes = fd;
+        rcb.aio_buf = rbuf;
+        rcb.aio_nbytes = 4;
+        rcb.aio_offset = 0;
+        rcb.aio_error = -1;
+        rcb.aio_return = -1;
+        if (sys_aio_read(&rcb) < 0) {
+            sys_write(1, "[init] aio_read failed\n", (uint32_t)(sizeof("[init] aio_read failed\n") - 1));
+            sys_exit(1);
+        }
+        if (sys_aio_error(&rcb) != 0 || sys_aio_return(&rcb) != 4) {
+            sys_write(1, "[init] aio_read result bad\n", (uint32_t)(sizeof("[init] aio_read result bad\n") - 1));
+            sys_exit(1);
+        }
+        if (rbuf[0] != 'A' || rbuf[1] != 'I' || rbuf[2] != 'O' || rbuf[3] != '!') {
+            sys_write(1, "[init] aio_read data bad\n", (uint32_t)(sizeof("[init] aio_read data bad\n") - 1));
+            sys_exit(1);
+        }
+
+        (void)sys_close(fd);
+        (void)sys_unlink("/disk/aiotest");
+        sys_write(1, "[init] aio OK\n", (uint32_t)(sizeof("[init] aio OK\n") - 1));
+    }
+
     enum { NCHILD = 100 };
     int children[NCHILD];
     for (int i = 0; i < NCHILD; i++) {