}
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++;
+++ /dev/null
-#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
#include <fcntl.h>
+#include <stdio.h>
#include <sys/lunaix.h>
#include <unistd.h>
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
--- /dev/null
+#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
--- /dev/null
+#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 */
#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 */
void
printf(const char* fmt, ...);
+const char*
+strchr(const char* str, int character);
+
#endif /* __LUNAIX_USTDIO_H */
--- /dev/null
+#ifndef __LUNAIX_STDLIB_H
+#define __LUNAIX_STDLIB_H
+
+char*
+itoa(int value, char* str, int base);
+
+#endif /* __LUNAIX_STDLIB_H */
--- /dev/null
+#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 */
-#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>
#ifndef __LUNAIX_SYS_TYPES_H
#define __LUNAIX_SYS_TYPES_H
+#define NULL (void*)0
+
#define PEXITTERM 0x100
#define PEXITSTOP 0x200
#define PEXITSIG 0x400
--- /dev/null
+#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 */
--- /dev/null
+#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;
+}
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
.section .text
.global _u_start
_u_start:
- movl $2, %eax
call usr_pre_init
jnz 1f