feat: closedir(2)
authorMinep <zelong56@gmail.com>
Wed, 4 Jan 2023 16:35:48 +0000 (16:35 +0000)
committerMinep <zelong56@gmail.com>
Wed, 4 Jan 2023 16:42:54 +0000 (16:42 +0000)
regression: execve
fix: wrong signature for printf
fix: sys_readdir context misuse
fix: page fault handler: offset calculation for memory-mapped file
fix: (merged) interrupt reworks in favour of execve.
fix: mmap: gap fitting

16 files changed:
lunaix-os/includes/lunaix/dirent.h [deleted file]
lunaix-os/kernel/asm/x86/interrupt.S
lunaix-os/kernel/asm/x86/pfault.c
lunaix-os/kernel/loader/exec.c
lunaix-os/kernel/mm/mmap.c
lunaix-os/kernel/mm/region.c
lunaix-os/makefile.prog
lunaix-os/makefile.usr
lunaix-os/uprog/init.c
lunaix-os/uprog/ls.c
lunaix-os/usr/api/dirent.c
lunaix-os/usr/includes/dirent.h
lunaix-os/usr/includes/stdio.h
lunaix-os/usr/includes/string.h
lunaix-os/usr/libc/printf.c
lunaix-os/usr/libc/readdir.c

diff --git a/lunaix-os/includes/lunaix/dirent.h b/lunaix-os/includes/lunaix/dirent.h
deleted file mode 100644 (file)
index 160365d..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef __LUNAIX_DIRENT_H
-#define __LUNAIX_DIRENT_H
-
-#define DIRENT_NAME_MAX_LEN 256
-
-#define DT_FILE 0x0
-#define DT_DIR 0x1
-#define DT_SYMLINK 0x2
-#define DT_PIPE 0x2
-
-struct dirent
-{
-    unsigned int d_type;
-    unsigned int d_offset;
-    unsigned int d_nlen;
-    char d_name[DIRENT_NAME_MAX_LEN];
-};
-
-#endif /* __LUNAIX_DIRENT_H */
index c869db0ede48fda280d41beb6c59c2cfba7f4216..23df5b507a3a0b7c213d1a0407930a0b6c09d23d 100644 (file)
         .skip 128
     tmp_stack:
 
+/*
+    This perhaps the ugliest part in the project. 
+    It contains code to handle arbitrary depth of 
+    nested interrupt and all those corner cases and 
+    nasty gotchas.
+
+    Be aware the twists, offsets and hidden dependencies!
+
+*/
+
 .section .text
     .global interrupt_wrapper
     interrupt_wrapper:
index 2b0a8f1a4e81c234dbb09002fc82bab54126b2c6..610c1cb978fd0dd1031a4d5825b6cbbacc8fbb36 100644 (file)
@@ -79,6 +79,7 @@ intr_routine_page_fault(const isr_param* param)
             }
 
             *pte = *pte | pa | PG_PRESENT;
+            memset(PG_ALIGN(ptr), 0, PG_SIZE);
             goto resolved;
         }
         // permission denied on anon page (e.g., write on readonly page)
@@ -88,8 +89,10 @@ intr_routine_page_fault(const isr_param* param)
     // if mfile is set (Non-anonymous), then it is a mem map
     if (hit_region->mfile && !PG_IS_PRESENT(*pte)) {
         struct v_file* file = hit_region->mfile;
-        u32_t offset =
-          ((ptr - hit_region->start) & (PG_SIZE - 1)) + hit_region->foff;
+
+        ptr = PG_ALIGN(ptr);
+
+        u32_t offset = (ptr - hit_region->start) + hit_region->foff;
         uintptr_t pa = pmm_alloc_page(__current->pid, 0);
 
         if (!pa) {
@@ -99,7 +102,6 @@ intr_routine_page_fault(const isr_param* param)
         cpu_invplg(pte);
         *pte = (*pte & 0xFFF) | pa | PG_PRESENT;
 
-        ptr = PG_ALIGN(ptr);
         memset(ptr, 0, PG_SIZE);
 
         int errno = 0;
index cf0a422e2f1d7acab87cc8253d61fb1667ba4abb..0105753a614492e74baa58b12b75d4904b9ac598 100644 (file)
@@ -47,7 +47,7 @@ __exec_remap_heap(struct ld_param* param, struct proc_mm* pvms)
 
     struct mmap_param map_param = { .pvms = pvms,
                                     .vms_mnt = param->vms_mnt,
-                                    .flags = MAP_ANON | MAP_PRIVATE | MAP_FIXED,
+                                    .flags = MAP_ANON | MAP_PRIVATE,
                                     .type = REGION_TYPE_HEAP,
                                     .proct = PROT_READ | PROT_WRITE,
                                     .mlen = DEFAULT_HEAP_PAGES * PG_SIZE };
@@ -181,11 +181,12 @@ __DEFINE_LXSYSCALL3(int,
             schedule();
             fail("should not reach");
         }
+        goto done;
     }
 
-    isr_param* intr_ctx = &__current->intr_ctx;
-    intr_ctx->esp = ldparam.info.stack_top;
-    intr_ctx->eip = ldparam.info.entry;
+    volatile struct exec_param* execp = __current->intr_ctx.execp;
+    execp->esp = ldparam.info.stack_top;
+    execp->eip = ldparam.info.entry;
 
     // we will jump to new entry point (_u_start) upon syscall's
     // return so execve 'will not return' from the perspective of it's invoker
index da1a0b6284f6d8103efe2ae333152ba824805e60..3a8677dd6cdd92b60c8cc803839f1945090e45e3 100644 (file)
@@ -67,13 +67,13 @@ mem_map(void** addr_out,
     {
         if (last_end < found_loc) {
             size_t avail_space = pos->start - found_loc;
-            if ((int)avail_space > 0 && avail_space > param->mlen) {
+            if (pos->start > found_loc && avail_space > param->mlen) {
                 goto found;
             }
             found_loc = pos->end + PG_SIZE;
         }
 
-        last_end = pos->end + PG_SIZE;
+        last_end = pos->end;
     }
 
     return ENOMEM;
@@ -213,7 +213,7 @@ mem_unmap(ptr_t mnt, vm_regions_t* regions, void* addr, size_t length)
         }
     }
 
-    while (&pos->head != regions && cur_addr > pos->start) {
+    while (&pos->head != regions && cur_addr >= pos->start) {
         u32_t l = pos->end - cur_addr;
         pos->end = cur_addr;
 
index f883edba78c02f453a205607498e3f85704d09f0..6340cfbb9d1768632abda81f34352f62898b4d26 100644 (file)
@@ -46,7 +46,7 @@ region_add(vm_regions_t* lead, struct mm_region* vmregion)
         cur_end = n->end;
         pos = n;
         n = list_entry(n->head.next, struct mm_region, head);
-    } while ((ptr_t)&pos->head != (ptr_t)lead);
+    } while ((ptr_t)&n->head != (ptr_t)lead);
 
     // XXX caution. require mm_region::head to be the lead of struct
     llist_insert_after(&pos->head, &vmregion->head);
index 1c09c78bd47c52a48e971b459aa1bde29a0e8ea1..2c8b8e7ffaba6303ca71c61dd74251ae6bd5545b 100644 (file)
@@ -7,6 +7,6 @@ PROGRAMES := $(patsubst uprog/%.c, $(USR_DIR)/%, $(SRC_FILES))
 
 $(USR_DIR)/%:
        @echo "  BUILD   $(*F)"
-       @$(CC) -T usr/link-usr.ld $(INCLUDES) $(CFLAGS) $(LDFLAGS) uprog/$(*F).c $(BIN_DIR)/$(USR_LIB) -o $@
+       @$(CC) -T usr/link-usr.ld $(INCLUDES) $(CFLAGS) -g $(LDFLAGS) uprog/$(*F).c $(BIN_DIR)/$(USR_LIB) -o $@
 
 all: $(PROGRAMES)
\ No newline at end of file
index d71ad714c3c785107c4a9b7fdd0e7316c6d6ed1a..7cbec35cb468b7316bab3e28693721e340db8260 100644 (file)
@@ -16,7 +16,7 @@ $(OBJECT_DIR)/%.S.o: %.S
 $(OBJECT_DIR)/%.c.o: %.c 
        @mkdir -p $(@D)
        @echo "  CC    $<"
-       @$(CC) $(INCLUDES) -c $< -o $@ $(CFLAGS)
+       @$(CC) $(INCLUDES) $(CFLAGS) -g -c $< -o $@ 
 
 $(BIN_DIR)/$(USR_LIB): $(OBJS)
        @echo "  AR    $@"
index c0c3fddf71a50e8055c904b4947667c9c69b8763..dd083add12be17fe2f84968ee6b83809bfd57290 100644 (file)
@@ -18,7 +18,7 @@ main(int argc, const char** argv)
         return 0;
     }
 
-    printf("(%p) user space!\n", main);
+    printf("(%p) user space!\n", (void*)main);
 
     pid_t pid;
     if (!(pid = fork())) {
index 605723c541d8031e908044d7e95ed240f92de25e..accc7f7fb9758c0e0cc6377665d38d60ad2c60ba 100644 (file)
@@ -26,5 +26,7 @@ main(int argc, const char* argv[])
         }
     }
 
+    closedir(dir);
+
     return 0;
 }
\ No newline at end of file
index 10d9213a6416755ce5a8cda404a5b48b429446eb..e309582a15448924ae7b17dcf0ada7f51a0467ca 100644 (file)
@@ -1,4 +1,4 @@
 #include <lunaix/syscall.h>
-#include <sys/dirent.h>
+#include <sys/lxdirent.h>
 
 __LXSYSCALL2(int, sys_readdir, int, fd, struct lx_dirent*, dent)
index 30ed8920ede980db07b8220d58d97d86497d2c22..78d57e3bb3835b36309e52d3a7676b88aff68110 100644 (file)
@@ -6,7 +6,7 @@
 typedef struct
 {
     int dirfd;
-    int prev_res;
+    struct lx_dirent _lxd;
 } DIR;
 
 struct dirent
@@ -16,7 +16,10 @@ struct dirent
 };
 
 DIR*
-opendir(const char* dir);
+opendir(const char* dirp);
+
+int
+closedir(DIR* dirp);
 
 struct dirent*
 readdir(DIR* dir);
index f898bedfee2f52b9efe0c1ae5cdc843a39974f07..0ef2e146fa2211b1a2fee357c7cb9e2271ea4e6e 100644 (file)
@@ -4,10 +4,7 @@
 #define stdout 0
 #define stdin 1
 
-void
+int
 printf(const char* fmt, ...);
 
-const char*
-strchr(const char* str, int character);
-
 #endif /* __LUNAIX_USTDIO_H */
index a3099247c53903992206ddd80200e780cf4082be..4c45ce290d8f1c3a720170070bed2f9a084a505f 100644 (file)
@@ -12,4 +12,7 @@ strnlen(const char* str, size_t max_len);
 char*
 strncpy(char* dest, const char* src, size_t n);
 
+const char*
+strchr(const char* str, int character);
+
 #endif /* __LUNAIX_STRING_H */
index 25571170583c16716f37db521f939d20c962e93e..3268a3f466562bdaa3d82d9187cde8faa872f303 100644 (file)
@@ -2,7 +2,7 @@
 #include <stdio.h>
 #include <unistd.h>
 
-void
+int
 printf(const char* fmt, ...)
 {
     char buf[1024];
index 9d2b23ed3b80ef45859155a496fa2ef2328eaa50..f8285b88d2293ab5b70fa392ed13101c3f23a58d 100644 (file)
@@ -2,6 +2,7 @@
 #include <fcntl.h>
 #include <string.h>
 #include <sys/lxdirent.h>
+#include <unistd.h>
 
 DIR*
 opendir(const char* dir)
@@ -12,10 +13,28 @@ opendir(const char* dir)
         return NULL;
     }
 
-    _dir = (DIR){ .dirfd = fd, .prev_res = 0 };
+    _dir = (DIR){ .dirfd = fd };
     return &_dir;
 }
 
+int
+closedir(DIR* dirp)
+{
+    if (!dirp || dirp->dirfd == -1) {
+        // TODO migrate the status.h
+        return -1;
+    }
+
+    int err = close(dirp->dirfd);
+
+    if (!err) {
+        dirp->dirfd = -1;
+        return 0;
+    }
+
+    return -1;
+}
+
 struct dirent*
 readdir(DIR* dir)
 {
@@ -24,18 +43,16 @@ readdir(DIR* dir)
         return NULL;
     }
 
-    struct lx_dirent _lxd;
-    int more = sys_readdir(dir->dirfd, &_lxd);
+    struct lx_dirent* _lxd = &dir->_lxd;
+
+    int more = sys_readdir(dir->dirfd, _lxd);
 
-    _dirent.d_type = _lxd.d_type;
-    strncpy(_dirent.d_name, _lxd.d_name, 256);
+    _dirent.d_type = _lxd->d_type;
+    strncpy(_dirent.d_name, _lxd->d_name, 256);
 
-    if (more || dir->prev_res) {
-        dir->prev_res = more;
+    if (more) {
         return &_dirent;
     }
 
-    if (!dir->prev_res) {
-        return NULL;
-    }
+    return NULL;
 }
\ No newline at end of file