feat: provide some libc routines only for testing
authorMinep <zelong56@gmail.com>
Mon, 2 Jan 2023 16:47:37 +0000 (16:47 +0000)
committerMinep <zelong56@gmail.com>
Mon, 2 Jan 2023 16:47:37 +0000 (16:47 +0000)
feat: ls
feat: readdir(3) for wrapping sys_readdir(2)
chore: clean ups

18 files changed:
lunaix-os/libs/klibc/string/strlen.c
lunaix-os/libs/ulibc/printf.c [deleted file]
lunaix-os/uprog/init.c
lunaix-os/uprog/ls.c [new file with mode: 0644]
lunaix-os/usr/includes/dirent.h [new file with mode: 0644]
lunaix-os/usr/includes/fcntl_defs.h
lunaix-os/usr/includes/stdio.h [moved from lunaix-os/includes/ulibc/stdio.h with 74% similarity]
lunaix-os/usr/includes/stdlib.h [new file with mode: 0644]
lunaix-os/usr/includes/string.h [new file with mode: 0644]
lunaix-os/usr/includes/sys/lxdirent.h [moved from lunaix-os/usr/includes/sys/dirent.h with 64% similarity]
lunaix-os/usr/includes/sys/types.h
lunaix-os/usr/libc/_mystdio.h [new file with mode: 0644]
lunaix-os/usr/libc/_vprintf.c [new file with mode: 0644]
lunaix-os/usr/libc/itoa.c [new file with mode: 0644]
lunaix-os/usr/libc/printf.c [new file with mode: 0644]
lunaix-os/usr/libc/readdir.c [new file with mode: 0644]
lunaix-os/usr/libc/string.c [new file with mode: 0644]
lunaix-os/usr/uwrap.S

index 30ceb654ddc584f0d0d9b89ec83108fc155475bf..c982f7ada1206af56d565155e639e1212e7b7e81 100644 (file)
@@ -10,7 +10,8 @@ strlen(const char* str)
 }
 
 size_t
-strnlen(const char* str, size_t max_len) {
+strnlen(const char* str, size_t max_len)
+{
     size_t len = 0;
     while (str[len] && len <= max_len)
         len++;
diff --git a/lunaix-os/libs/ulibc/printf.c b/lunaix-os/libs/ulibc/printf.c
deleted file mode 100644 (file)
index 3d0b0f6..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <klibc/stdio.h>
-#include <lunaix/spike.h>
-#include <ulibc/stdio.h>
-
-#include <unistd.h>
-
-// This is VERY bad implementation as it mixes both kernel and user space
-// code together. It is here however, just for the convenience of our testing
-// program.
-// FIXME Eliminate this when we're able to load program.
-
-void __USER__
-printf(const char* fmt, ...)
-{
-    const char buf[512];
-    va_list args;
-    va_start(args, fmt);
-
-    size_t sz = __ksprintf_internal(buf, fmt, 512, args);
-
-    write(stdout, buf, sz);
-
-    va_end(args);
-}
\ No newline at end of file
index 0d1eebc9ed131a0db8f49a5cb7ada7d012f082c5..c0c3fddf71a50e8055c904b4947667c9c69b8763 100644 (file)
@@ -1,4 +1,5 @@
 #include <fcntl.h>
+#include <stdio.h>
 #include <sys/lunaix.h>
 #include <unistd.h>
 
@@ -17,7 +18,16 @@ main(int argc, const char** argv)
         return 0;
     }
 
-    syslog(0, "(%p) user space!\n", main);
+    printf("(%p) user space!\n", main);
+
+    pid_t pid;
+    if (!(pid = fork())) {
+        int err = execve("/mnt/lunaix-os/usr/ls", NULL, NULL);
+        printf("fail to execute (%d)\n", err);
+        _exit(err);
+    }
+
+    waitpid(pid, NULL, 0);
 
     return 0;
 }
\ No newline at end of file
diff --git a/lunaix-os/uprog/ls.c b/lunaix-os/uprog/ls.c
new file mode 100644 (file)
index 0000000..605723c
--- /dev/null
@@ -0,0 +1,30 @@
+#include <dirent.h>
+#include <errno.h>
+#include <stdio.h>
+
+int
+main(int argc, const char* argv[])
+{
+    char* path = ".";
+    if (argc > 0) {
+        path = argv[0];
+    }
+
+    DIR* dir = opendir(path);
+
+    if (!dir) {
+        return errno;
+    }
+
+    struct dirent* dent;
+
+    while ((dent = readdir(dir))) {
+        if (dent->d_type == DT_DIR) {
+            printf(" \033[3m%s\033[39;49m\n", dent->d_name);
+        } else {
+            printf(" %s\n", dent->d_name);
+        }
+    }
+
+    return 0;
+}
\ No newline at end of file
diff --git a/lunaix-os/usr/includes/dirent.h b/lunaix-os/usr/includes/dirent.h
new file mode 100644 (file)
index 0000000..30ed892
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef __LUNAIX_SYS_DIRENT_H
+#define __LUNAIX_SYS_DIRENT_H
+
+#include <sys/dirent_defs.h>
+
+typedef struct
+{
+    int dirfd;
+    int prev_res;
+} DIR;
+
+struct dirent
+{
+    unsigned char d_type;
+    char d_name[256];
+};
+
+DIR*
+opendir(const char* dir);
+
+struct dirent*
+readdir(DIR* dir);
+
+#endif /* __LUNAIX_DIRENT_H */
index 01930cb26cc47c6d6c2c1d390de2f087dc2eedde..c6cbe4f645e98574386bd5d308e1ce0e07e96791 100644 (file)
@@ -4,11 +4,21 @@
 #define FO_CREATE 0x1
 #define FO_APPEND 0x2
 #define FO_DIRECT 0x4
+#define FO_WRONLY 0x8
+#define FO_RDONLY 0x10
+#define FO_RDWR 0x20
 
 #define FSEEK_SET 0x1
 #define FSEEK_CUR 0x2
 #define FSEEK_END 0x3
 
+#define O_CREAT FO_CREATE
+#define O_APPEND FO_APPEND
+#define O_DIRECT FO_DIRECT
+#define O_WRONLY FO_WRONLY
+#define O_RDONLY FO_RDONLY
+#define O_RDWR FO_RDWR
+
 #define MNT_RO 0x1
 
 #endif /* __LUNAIX_FNCTL_DEFS_H */
similarity index 74%
rename from lunaix-os/includes/ulibc/stdio.h
rename to lunaix-os/usr/includes/stdio.h
index e9496a825ad131ff293a080c315b2c9002067794..f898bedfee2f52b9efe0c1ae5cdc843a39974f07 100644 (file)
@@ -7,4 +7,7 @@
 void
 printf(const char* fmt, ...);
 
+const char*
+strchr(const char* str, int character);
+
 #endif /* __LUNAIX_USTDIO_H */
diff --git a/lunaix-os/usr/includes/stdlib.h b/lunaix-os/usr/includes/stdlib.h
new file mode 100644 (file)
index 0000000..0e38fb5
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __LUNAIX_STDLIB_H
+#define __LUNAIX_STDLIB_H
+
+char*
+itoa(int value, char* str, int base);
+
+#endif /* __LUNAIX_STDLIB_H */
diff --git a/lunaix-os/usr/includes/string.h b/lunaix-os/usr/includes/string.h
new file mode 100644 (file)
index 0000000..a309924
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __LUNAIX_STRING_H
+#define __LUNAIX_STRING_H
+
+#include <stddef.h>
+
+size_t
+strlen(const char* str);
+
+size_t
+strnlen(const char* str, size_t max_len);
+
+char*
+strncpy(char* dest, const char* src, size_t n);
+
+#endif /* __LUNAIX_STRING_H */
similarity index 64%
rename from lunaix-os/usr/includes/sys/dirent.h
rename to lunaix-os/usr/includes/sys/lxdirent.h
index 101f0508887628f9359a3aee9b6d830c0849673b..e616180a5fc9b1d4b68845480fec8be9331964bb 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __LUNAIX_SYS_DIRENT_H
-#define __LUNAIX_SYS_DIRENT_H
+#ifndef __LUNAIX_SYS_LXDIRENT_H
+#define __LUNAIX_SYS_LXDIRENT_H
 
 #include <sys/dirent_defs.h>
 
index a4b7f2999d84e81ca71959a85ae704f13f8d5f72..8b30318f83b7f3b68e6c8333e7e34cf38da94b0d 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef __LUNAIX_SYS_TYPES_H
 #define __LUNAIX_SYS_TYPES_H
 
+#define NULL (void*)0
+
 #define PEXITTERM 0x100
 #define PEXITSTOP 0x200
 #define PEXITSIG 0x400
diff --git a/lunaix-os/usr/libc/_mystdio.h b/lunaix-os/usr/libc/_mystdio.h
new file mode 100644 (file)
index 0000000..d60fed3
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __LUNAIX__MYSTDIO_H
+#define __LUNAIX__MYSTDIO_H
+
+#include <stdarg.h>
+#include <stddef.h>
+
+int
+__vprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs);
+
+#endif /* __LUNAIX__MYSTDIO_H */
diff --git a/lunaix-os/usr/libc/_vprintf.c b/lunaix-os/usr/libc/_vprintf.c
new file mode 100644 (file)
index 0000000..1e56305
--- /dev/null
@@ -0,0 +1,198 @@
+#include "_mystdio.h"
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define NUMBUFSIZ 24
+
+static const char flag_chars[] = "#0- +";
+
+#define FLAG_ALT (1 << 0)
+#define FLAG_ZERO (1 << 1)
+#define FLAG_LEFTJUSTIFY (1 << 2)
+#define FLAG_SPACEPOSITIVE (1 << 3)
+#define FLAG_PLUSPOSITIVE (1 << 4)
+#define FLAG_NUMERIC (1 << 5)
+#define FLAG_SIGNED (1 << 6)
+#define FLAG_NEGATIVE (1 << 7)
+#define FLAG_ALT2 (1 << 8)
+#define FLAG_CAPS (1 << 9)
+
+int
+__vprintf_internal(char* buffer, char* fmt, size_t max_len, va_list vargs)
+{
+    // This sprintf just a random implementation I found it on Internet . lol.
+    //      Of course, with some modifications for porting to LunaixOS :)
+
+    char numbuf[NUMBUFSIZ];
+    uintptr_t ptr = 0;
+    for (; *fmt; ++fmt) {
+        if (max_len && ptr >= max_len - 1) {
+            break;
+        }
+
+        if (*fmt != '%') {
+            buffer[ptr++] = *fmt;
+            continue;
+        }
+
+        // process flags
+        int flags = 0;
+        for (++fmt; *fmt; ++fmt) {
+            const char* flagc = strchr(flag_chars, *fmt);
+            if (flagc) {
+                flags |= 1 << (flagc - flag_chars);
+            } else {
+                break;
+            }
+        }
+
+        // process width
+        int width = -1;
+        if (*fmt >= '1' && *fmt <= '9') {
+            for (width = 0; *fmt >= '0' && *fmt <= '9';) {
+                width = 10 * width + *fmt++ - '0';
+            }
+        } else if (*fmt == '*') {
+            width = va_arg(vargs, int);
+            ++fmt;
+        }
+
+        // process precision
+        int precision = -1;
+        if (*fmt == '.') {
+            ++fmt;
+            if (*fmt >= '0' && *fmt <= '9') {
+                for (precision = 0; *fmt >= '0' && *fmt <= '9';) {
+                    precision = 10 * precision + *fmt++ - '0';
+                }
+            } else if (*fmt == '*') {
+                precision = va_arg(vargs, int);
+                ++fmt;
+            }
+            if (precision < 0) {
+                precision = 0;
+            }
+        }
+
+        // process main conversion character
+        int base = 10;
+        unsigned long num = 0;
+        int length = 0;
+        char* data = "";
+    again:
+        switch (*fmt) {
+            case 'l':
+            case 'z':
+                length = 1;
+                ++fmt;
+                goto again;
+            case 'd':
+            case 'i': {
+                long x = length ? va_arg(vargs, long) : va_arg(vargs, int);
+                int negative = x < 0 ? FLAG_NEGATIVE : 0;
+                num = negative ? -x : x;
+                flags |= FLAG_NUMERIC | FLAG_SIGNED | negative;
+                break;
+            }
+            case 'u':
+            format_unsigned:
+                num = length ? va_arg(vargs, unsigned long)
+                             : va_arg(vargs, unsigned);
+                flags |= FLAG_NUMERIC;
+                break;
+            case 'b':
+                base = 2;
+                goto format_unsigned;
+            case 'x':
+                base = 16;
+                goto format_unsigned;
+            case 'X':
+                flags = flags | FLAG_CAPS;
+                base = 16;
+                goto format_unsigned;
+            case 'p':
+                num = (uintptr_t)va_arg(vargs, void*);
+                base = 16;
+                flags |= FLAG_ALT | FLAG_ALT2 | FLAG_NUMERIC;
+                break;
+            case 's':
+                data = va_arg(vargs, char*);
+                break;
+            case 'c':
+                data = numbuf;
+                numbuf[0] = va_arg(vargs, int);
+                numbuf[1] = '\0';
+                break;
+            default:
+                data = numbuf;
+                numbuf[0] = (*fmt ? *fmt : '%');
+                numbuf[1] = '\0';
+                if (!*fmt) {
+                    fmt--;
+                }
+                break;
+        }
+
+        if (flags & FLAG_NUMERIC) {
+            data = itoa(num, numbuf, base);
+            int i = 0;
+            char c;
+            while ((flags & FLAG_CAPS) && (c = data[i])) {
+                data[i] = c & ~((c & 0x40) >> 1);
+                i++;
+            }
+        }
+
+        const char* prefix = "";
+        if ((flags & FLAG_NUMERIC) && (flags & FLAG_SIGNED)) {
+            if (flags & FLAG_NEGATIVE) {
+                prefix = "-";
+            } else if (flags & FLAG_PLUSPOSITIVE) {
+                prefix = "+";
+            } else if (flags & FLAG_SPACEPOSITIVE) {
+                prefix = " ";
+            }
+        } else if ((flags & FLAG_NUMERIC) && (flags & FLAG_ALT) &&
+                   (base == 16 || base == -16) &&
+                   (num || (flags & FLAG_ALT2))) {
+            prefix = "0x";
+        }
+
+        int len;
+        if (precision >= 0 && !(flags & FLAG_NUMERIC)) {
+            len = strnlen(data, precision);
+        } else {
+            len = strlen(data);
+        }
+        int zeros;
+        if ((flags & FLAG_NUMERIC) && precision >= 0) {
+            zeros = precision > len ? precision - len : 0;
+        } else if ((flags & FLAG_NUMERIC) && (flags & FLAG_ZERO) &&
+                   !(flags & FLAG_LEFTJUSTIFY) &&
+                   len + (int)strlen(prefix) < width) {
+            zeros = width - len - strlen(prefix);
+        } else {
+            zeros = 0;
+        }
+        width -= len + zeros + strlen(prefix);
+        for (; !(flags & FLAG_LEFTJUSTIFY) && width > 0; --width) {
+            buffer[ptr++] = ' ';
+        }
+        for (; *prefix; ++prefix) {
+            buffer[ptr++] = *prefix;
+        }
+        for (; zeros > 0; --zeros) {
+            buffer[ptr++] = '0';
+        }
+        for (; len > 0; ++data, --len) {
+            buffer[ptr++] = *data;
+        }
+        for (; width > 0; --width) {
+            buffer[ptr++] = ' ';
+        }
+    }
+    buffer[ptr++] = '\0';
+
+    return ptr;
+}
diff --git a/lunaix-os/usr/libc/itoa.c b/lunaix-os/usr/libc/itoa.c
new file mode 100644 (file)
index 0000000..d60599f
--- /dev/null
@@ -0,0 +1,46 @@
+#include <stddef.h>
+#include <stdlib.h>
+
+char base_char[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+char*
+__uitoa_internal(unsigned int value, char* str, int base, unsigned int* size)
+{
+    unsigned int ptr = 0;
+    do {
+        str[ptr] = base_char[value % base];
+        value = value / base;
+        ptr++;
+    } while (value);
+
+    for (unsigned int i = 0; i < (ptr >> 1); i++) {
+        char c = str[i];
+        str[i] = str[ptr - i - 1];
+        str[ptr - i - 1] = c;
+    }
+    str[ptr] = '\0';
+    if (size) {
+        *size = ptr;
+    }
+    return str;
+}
+
+char*
+__itoa_internal(int value, char* str, int base, unsigned int* size)
+{
+    if (value < 0 && base == 10) {
+        str[0] = '-';
+        unsigned int _v = (unsigned int)(-value);
+        __uitoa_internal(_v, str + 1, base, size);
+    } else {
+        __uitoa_internal(value, str, base, size);
+    }
+
+    return str;
+}
+
+char*
+itoa(int value, char* str, int base)
+{
+    return __itoa_internal(value, str, base, NULL);
+}
\ No newline at end of file
diff --git a/lunaix-os/usr/libc/printf.c b/lunaix-os/usr/libc/printf.c
new file mode 100644 (file)
index 0000000..2557117
--- /dev/null
@@ -0,0 +1,15 @@
+#include "_mystdio.h"
+#include <stdio.h>
+#include <unistd.h>
+
+void
+printf(const char* fmt, ...)
+{
+    char buf[1024];
+    va_list args;
+    va_start(args, fmt);
+    int n = __vprintf_internal(buf, fmt, 1024, args);
+    va_end(args);
+
+    return write(stdout, buf, n);
+}
\ No newline at end of file
diff --git a/lunaix-os/usr/libc/readdir.c b/lunaix-os/usr/libc/readdir.c
new file mode 100644 (file)
index 0000000..9d2b23e
--- /dev/null
@@ -0,0 +1,41 @@
+#include <dirent.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/lxdirent.h>
+
+DIR*
+opendir(const char* dir)
+{
+    static DIR _dir;
+    int fd = open(dir, O_RDONLY);
+    if (fd < 0) {
+        return NULL;
+    }
+
+    _dir = (DIR){ .dirfd = fd, .prev_res = 0 };
+    return &_dir;
+}
+
+struct dirent*
+readdir(DIR* dir)
+{
+    static struct dirent _dirent;
+    if (!dir) {
+        return NULL;
+    }
+
+    struct lx_dirent _lxd;
+    int more = sys_readdir(dir->dirfd, &_lxd);
+
+    _dirent.d_type = _lxd.d_type;
+    strncpy(_dirent.d_name, _lxd.d_name, 256);
+
+    if (more || dir->prev_res) {
+        dir->prev_res = more;
+        return &_dirent;
+    }
+
+    if (!dir->prev_res) {
+        return NULL;
+    }
+}
\ No newline at end of file
diff --git a/lunaix-os/usr/libc/string.c b/lunaix-os/usr/libc/string.c
new file mode 100644 (file)
index 0000000..2e34dc7
--- /dev/null
@@ -0,0 +1,44 @@
+#include <string.h>
+
+size_t
+strlen(const char* str)
+{
+    size_t len = 0;
+    while (str[len])
+        len++;
+    return len;
+}
+
+const char*
+strchr(const char* str, int character)
+{
+    char c = (char)character;
+    while ((*str)) {
+        if (*str == c) {
+            return str;
+        }
+        str++;
+    }
+    return c == '\0' ? str : NULL;
+}
+
+size_t
+strnlen(const char* str, size_t max_len)
+{
+    size_t len = 0;
+    while (str[len] && len <= max_len)
+        len++;
+    return len;
+}
+
+char*
+strncpy(char* dest, const char* src, size_t n)
+{
+    char c;
+    unsigned int i = 0;
+    while ((c = src[i]) && i <= n)
+        dest[i++] = c;
+    while (i <= n)
+        dest[i++] = 0;
+    return dest;
+}
\ No newline at end of file
index 1cd6515c57182386b4309204b6394d94e844730d..1f077228da8d889b3829a6c00b875686b98860a5 100644 (file)
@@ -4,7 +4,6 @@
 .section .text
     .global _u_start
     _u_start:
-        movl $2, %eax
         call usr_pre_init
         jnz 1f