Reorganize the files.
authorcoderain <coderain@sdf.org>
Sat, 13 Oct 2018 15:06:52 +0000 (17:06 +0200)
committercoderain <coderain@sdf.org>
Sat, 13 Oct 2018 15:06:52 +0000 (17:06 +0200)
78 files changed:
.gitignore
Makefile
crt/.gitignore [deleted file]
crt/Makefile [deleted file]
crt/include/ctype.h [deleted file]
crt/include/errno.h [deleted file]
crt/include/fcntl.h [deleted file]
crt/include/malloc.h [deleted file]
crt/include/setjmp.h [deleted file]
crt/include/stdio.h [deleted file]
crt/include/stdlib.h [deleted file]
crt/include/string.h [deleted file]
crt/include/unistd.h [deleted file]
crt/src/algorithm.c [deleted file]
crt/src/crt0.c [deleted file]
crt/src/ctype.c [deleted file]
crt/src/errno.c [deleted file]
crt/src/exit.c [deleted file]
crt/src/fcntl.c [deleted file]
crt/src/io.c [deleted file]
crt/src/io_priv.h [deleted file]
crt/src/malloc.c [deleted file]
crt/src/numconv.c [deleted file]
crt/src/printf.c [deleted file]
crt/src/setjmp.c [deleted file]
crt/src/string.c [deleted file]
crt/src/wd.c [deleted file]
drivers/acpica/Makefile
drivers/fatfs/Makefile
drivers/floppy/Makefile
drivers/ps2/Makefile
drivers/ramfs/Makefile
drivers/serial/Makefile
drivers/speaker/Makefile
drivers/vesa/Makefile
kernel/Makefile
kernel/include/heap.h
libraries/.gitignore [new file with mode: 0644]
libraries/Makefile [new file with mode: 0644]
libraries/mlcrt/.gitignore [new file with mode: 0644]
libraries/mlcrt/Makefile [new file with mode: 0644]
libraries/mlcrt/include/ctype.h [new file with mode: 0644]
libraries/mlcrt/include/errno.h [new file with mode: 0644]
libraries/mlcrt/include/fcntl.h [new file with mode: 0644]
libraries/mlcrt/include/malloc.h [new file with mode: 0644]
libraries/mlcrt/include/setjmp.h [new file with mode: 0644]
libraries/mlcrt/include/stdio.h [new file with mode: 0644]
libraries/mlcrt/include/stdlib.h [new file with mode: 0644]
libraries/mlcrt/include/string.h [new file with mode: 0644]
libraries/mlcrt/include/unistd.h [new file with mode: 0644]
libraries/mlcrt/src/algorithm.c [new file with mode: 0644]
libraries/mlcrt/src/crt0.c [new file with mode: 0644]
libraries/mlcrt/src/ctype.c [new file with mode: 0644]
libraries/mlcrt/src/errno.c [new file with mode: 0644]
libraries/mlcrt/src/exit.c [new file with mode: 0644]
libraries/mlcrt/src/fcntl.c [new file with mode: 0644]
libraries/mlcrt/src/io.c [new file with mode: 0644]
libraries/mlcrt/src/io_priv.h [new file with mode: 0644]
libraries/mlcrt/src/malloc.c [new file with mode: 0644]
libraries/mlcrt/src/numconv.c [new file with mode: 0644]
libraries/mlcrt/src/printf.c [new file with mode: 0644]
libraries/mlcrt/src/setjmp.c [new file with mode: 0644]
libraries/mlcrt/src/string.c [new file with mode: 0644]
libraries/mlcrt/src/wd.c [new file with mode: 0644]
libraries/mlsys/.gitignore [new file with mode: 0644]
libraries/mlsys/Makefile [new file with mode: 0644]
libraries/mlsys/src/syscall.asm [new file with mode: 0644]
library/.gitignore [deleted file]
library/Makefile [deleted file]
library/src/syscall.asm [deleted file]
manager/.gitignore [deleted file]
manager/Makefile [deleted file]
manager/src/start.c [deleted file]
programs/.gitignore [new file with mode: 0644]
programs/Makefile [new file with mode: 0644]
programs/manager/.gitignore [new file with mode: 0644]
programs/manager/Makefile [new file with mode: 0644]
programs/manager/src/start.c [new file with mode: 0644]

index 5e3e29fb336089ebf514fc5b9723977247319921..eca5924e791d641bb83206a6f1c6103be3c4431a 100644 (file)
 !tools/packages/*.sig
 !kernel
 !kernel/*
-!crt
-!crt/*
-!library
-!library/*
+!libraries
+!libraries/**
 !tests
 !tests/**
-!manager
-!manager/*
+!programs
+!programs/**
 !drivers
 !drivers/**
 !sdk
index 5d8cdceb1b57c8422256f85a3c4481e94fce4c18..ec077de7ea1a1fb7c8c4d4da6fc2af441307edb5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-.PHONY: all clean crt kernel drivers library manager tests generate
+.PHONY: all clean kernel drivers libraries programs tests generate
 
 TOOLSDIR     := tools
 TOOLSROOTDIR := root
@@ -10,20 +10,17 @@ GENERATED_SOURCES := sdk/syscall_enum.h kernel/src/syscall_table.inl library/src
 
 all: livecd.iso tests
 
-crt:
-       $(MAKE) -C crt all
-
-kernel: generate crt
+kernel: generate libraries
        $(MAKE) -C kernel all
 
 drivers: kernel
        $(MAKE) -C drivers all
 
-library: generate crt
-       $(MAKE) -C library all
+libraries: generate
+       $(MAKE) -C libraries all
 
-manager: library
-       $(MAKE) -C manager all
+programs: libraries
+       $(MAKE) -C programs all
 
 tests:
        $(MAKE) -C tests all
@@ -32,25 +29,24 @@ generate: $(GENERATED_SOURCES)
 
 sdk/syscall_enum.h: $(wildcard sdk/*.h) syscalls.awk
        @echo 'Generating system call sources/headers...'
-       sort sdk/* | awk -v enum_file=sdk/syscall_enum.h -v table_file=kernel/src/syscall_table.inl -v wrappers_file=library/src/wrappers.c -f syscalls.awk
+       sort sdk/* | awk -v enum_file=sdk/syscall_enum.h -v table_file=kernel/src/syscall_table.inl -v wrappers_file=libraries/mlsys/src/wrappers.c -f syscalls.awk
 
 kernel/src/syscall_table.inl: sdk/syscall_enum.h
 
 library/src/wrappers.c: sdk/syscall_enum.h
 
-livecd.iso : kernel drivers library manager
+livecd.iso : kernel drivers libraries programs
        mkdir -p livecd/monolithium livecd/boot/grub livecd/monolithium/drivers
        cp kernel/monolithium livecd/monolithium/kernel
-       find drivers -type f -name '*.drv' -exec cp {} livecd/monolithium/drivers/ \;
-       cp manager/manager livecd/monolithium/manager
+       cp drivers/bin/* livecd/monolithium/drivers/
+       cp programs/bin/* livecd/monolithium/
        cp grub.cfg livecd/boot/grub/grub.cfg
        grub-mkrescue -o $@ livecd
 
 clean:
-       $(MAKE) -C crt clean
        $(MAKE) -C kernel clean
        $(MAKE) -C drivers clean
-       $(MAKE) -C library clean
-       $(MAKE) -C manager clean
+       $(MAKE) -C libraries clean
+       $(MAKE) -C programs clean
        $(MAKE) -C tests clean
        rm -f $(GENERATED_SOURCES) livecd.iso
diff --git a/crt/.gitignore b/crt/.gitignore
deleted file mode 100644 (file)
index 55a8867..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-*
-
-# Include the following files:
-!.gitignore
-!Makefile
-!src
-!src/*
-!include
-!include/*
diff --git a/crt/Makefile b/crt/Makefile
deleted file mode 100644 (file)
index abc825f..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Makefile
-#
-# Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-# Settings
-DEBUG = yes
-
-# Flags
-CFLAGS   := -Wall -Werror -ffreestanding -nostdlib -fPIC -I include -I ../sdk
-ASMFLAGS := -felf
-
-# Input and output files
-SOURCES =  $(wildcard $(SRCDIR)/*.c)
-SOURCES += $(wildcard $(SRCDIR)/*.asm)
-
-OUTPUT_STATIC_LIB = libmlcrt.a
-
--include ../common.mk
diff --git a/crt/include/ctype.h b/crt/include/ctype.h
deleted file mode 100644 (file)
index e3c3b1b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * ctype.h
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _CTYPE_H_
-#define _CTYPE_H_
-
-int isprint(int c);
-int isdigit(int c);
-int isxdigit(int c);
-int isspace(int c);
-char tolower(char c);
-char toupper(char c);
-
-#endif
diff --git a/crt/include/errno.h b/crt/include/errno.h
deleted file mode 100644 (file)
index c0ffe70..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * errno.h
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _ERRNO_H_
-#define _ERRNO_H_
-
-#include <stdint.h>
-
-#define EPERM        1
-#define ENOENT       2
-#define ESRCH        3
-#define EINTR        4
-#define EIO          5
-#define ENXIO        6
-#define E2BIG        7
-#define ENOEXEC      8
-#define EBADF        9
-#define ECHILD       10
-#define EAGAIN       11
-#define ENOMEM       12
-#define EACCES       13
-#define EFAULT       14
-#define EBUSY        16
-#define EEXIST       17
-#define EXDEV        18
-#define ENODEV       19
-#define ENOTDIR      20
-#define EISDIR       21
-#define EINVAL       22
-#define ENFILE       23
-#define EMFILE       24
-#define ENOTTY       25
-#define EFBIG        27
-#define ENOSPC       28
-#define ESPIPE       29
-#define EROFS        30
-#define EMLINK       31
-#define EPIPE        32
-#define EDOM         33
-#define ERANGE       34
-#define EDEADLK      36
-#define EDEADLOCK    EDEADLK
-#define ENAMETOOLONG 38
-#define ENOLCK       39
-#define ENOSYS       40
-#define ENOTEMPTY    41
-#define EILSEQ       42
-#define ECANCELED    43
-#define ETIMEDOUT    44
-#define ETOOSMALL    45
-#define EOVERFLOW    46
-
-extern int errno;
-
-int __crt_translate_error(uint32_t status_code);
-
-#endif
-
diff --git a/crt/include/fcntl.h b/crt/include/fcntl.h
deleted file mode 100644 (file)
index 5f373a5..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * fcntl.h
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _FCNTL_H_
-#define _FCNTL_H_
-
-#include <unistd.h>
-#include <stdlib.h>
-
-#define FD_CLOEXEC (1 << 0)
-#define FD_PIPE    (1 << 1)
-
-#endif
diff --git a/crt/include/malloc.h b/crt/include/malloc.h
deleted file mode 100644 (file)
index b3001e8..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * malloc.h
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _MALLOC_H_
-#define _MALLOC_H_
-
-#define __CRT_HEAP_FLAG_READY    (1 << 0)
-#define __CRT_HEAP_FLAG_ZEROFILL (1 << 1)
-#define __CRT_HEAP_FLAG_BESTFIT  (1 << 2)
-
-enum
-{
-    __CRT_HEAP_CORRUPTED,
-    __CRT_HEAP_DOUBLE_FREE,
-    __CRT_HEAP_BAD_POINTER,
-    __CRT_HEAP_OUT_OF_MEMORY,
-};
-
-typedef struct
-{
-    uint32_t magic;
-    void *base;
-    size_t size;
-    uint32_t flags;
-    uintptr_t next_offset;
-    void *mutex;
-    void (*lock_mutex_proc)(void*);
-    void (*unlock_mutex_proc)(void*);
-    void (*problem)(int);
-} __crt_heap_t;
-
-void *malloc(size_t size);
-void free(void *ptr);
-void *calloc(size_t nmemb, size_t size);
-void *realloc(void *ptr, size_t size);
-
-#endif
diff --git a/crt/include/setjmp.h b/crt/include/setjmp.h
deleted file mode 100644 (file)
index 0c1dad2..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * setjmp.c
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _SETJMP_H_
-#define _SETJMP_H_
-
-#include <stddef.h>
-#include <monolithium.h>
-
-typedef struct
-{
-    int val;
-    thread_state_t state;
-} jmp_buf[1];
-
-int setjmp(jmp_buf env);
-int longjmp(jmp_buf env, int val);
-
-#endif
diff --git a/crt/include/stdio.h b/crt/include/stdio.h
deleted file mode 100644 (file)
index 467956d..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * stdio.h
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _STDIO_H_
-#define _STDIO_H_
-
-#include <stdlib.h>
-#include <stdarg.h>
-
-#define EOF -1
-
-#define getc(s) fgetc(s)
-#define getchar() fgetc(stdin)
-#define putc(c, s) fputc(c, s)
-#define putchar(c) fputc(c, stdout)
-
-#define getc_unlocked(s) fgetc_unlocked(s)
-#define getchar_unlocked() fgetc_unlocked(stdin)
-#define putc_unlocked(c, s) fputc_unlocked(c, s)
-#define putchar_unlocked(c) fputc(c, stdout)
-
-struct __crt_file;
-typedef struct __crt_file FILE;
-
-extern FILE *stdin;
-extern FILE *stdout;
-extern FILE *stderr;
-
-int fgetc(FILE *stream);
-int fputc(int c, FILE *stream);
-char *fgets(char *s, int size, FILE *stream);
-int fputs(const char *s, FILE *stream);
-int ungetc(int c, FILE *stream);
-char *gets(char *s);
-int puts(const char *s);
-
-int fgetc_unlocked(FILE *stream);
-int fputc_unlocked(int c, FILE *stream);
-char *fgets_unlocked(char *s, int size, FILE *stream);
-int fputs_unlocked(const char *s, FILE *stream);
-
-FILE *fopen(const char *pathname, const char *mode);
-FILE *fdopen(int fd, const char *mode);
-FILE *fmemopen(void *buf, size_t size, const char *mode);
-int fclose(FILE *stream);
-
-#define BUFSIZ 4096
-#define _IOFBF 0
-#define _IOLBF 1
-#define _IONBF 2
-
-int setvbuf(FILE *stream, char *buf, int mode, size_t size);
-void setbuf(FILE *stream, char *buf);
-void setbuffer(FILE *stream, char *buf, size_t size);
-void setlinebuf(FILE *stream);
-
-int printf(const char *format, ...);
-int fprintf(FILE *stream, const char *format, ...);
-int dprintf(int fd, const char *format, ...);
-int sprintf(char *str, const char *format, ...);
-int snprintf(char *str, size_t size, const char *format, ...);
-int vprintf(const char *format, va_list ap);
-int vfprintf(FILE *stream, const char *format, va_list ap);
-int vdprintf(int fd, const char *format, va_list ap);
-int vsprintf(char *str, const char *format, va_list ap);
-int vsnprintf(char *str, size_t size, const char *format, va_list ap);
-
-
-#endif
diff --git a/crt/include/stdlib.h b/crt/include/stdlib.h
deleted file mode 100644 (file)
index f1a9524..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * stdlib.h
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _STDLIB_H_
-#define _STDLIB_H_
-
-#include <stddef.h>
-#include <stdint.h>
-#include <malloc.h>
-#include <errno.h>
-
-char *itoa(int value, char *str, int base);
-char *ltoa(long value, char *str, int base);
-char *lltoa(long long value, char *str, int base);
-char *uitoa(unsigned int value, char *str, int base);
-char *ultoa(unsigned long value, char *str, int base);
-char *ulltoa(unsigned long long value, char *str, int base);
-int atoi(const char *str);
-long atol(const char *str);
-long long atoll(const char *str);
-long strtol(const char *str, char **endptr, int base);
-long long strtoll(const char *str, char **endptr, int base);
-unsigned long strtoul(const char *str, char **endptr, int base);
-unsigned long long strtoull(const char *str, char **endptr, int base);
-
-void qsort(void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*));
-void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*));
-
-#define ATEXIT_MAX 32
-
-int atexit(void (*function)(void));
-void __attribute__((__noreturn__)) exit(int status);
-
-typedef uint32_t pid_t;
-
-pid_t getpid(void);
-pid_t getppid(void);
-pid_t fork(void);
-
-#endif
diff --git a/crt/include/string.h b/crt/include/string.h
deleted file mode 100644 (file)
index 9bc9057..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * string.h
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _STRING_H_
-#define _STRING_H_
-
-#include <stddef.h>
-#include <stdint.h>
-#include <limits.h>
-#include <ctype.h>
-
-char *strcpy(char *destination, const char *source);
-char *strncpy(char *destination, const char *source, size_t n);
-int strcmp(const char *str1, const char *str2);
-int stricmp(const char *str1, const char *str2);
-int strncmp(const char *str1, const char *str2, size_t n);
-char *strstr(const char *haystack, const char *needle);
-char *strchr(const char *str, char c);
-char *strrchr(const char *str, char c);
-char *strcat(char *destination, const char *source);
-char *strncat(char *destination, const char *source, size_t n);
-char *strdup(const char *source);
-char *strtok(char *str, const char *delimiters);
-char *strtok_r(char *str, const char *delimiters, char **endptr);
-size_t strlen(const char *str);
-void strrev(char *str);
-void memset(void *ptr, int value, size_t n);
-void memcpy(void *destination, const void *source, size_t n);
-void memmove(void *destination, const void *source, size_t n);
-int memcmp(const void *mem1, const void *mem2, size_t n);
-
-#endif
diff --git a/crt/include/unistd.h b/crt/include/unistd.h
deleted file mode 100644 (file)
index a1f1b8a..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * unistd.h
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _UNISTD_H_
-#define _UNISTD_H_
-
-#include <stddef.h>
-#include <stdint.h>
-
-#define PATH_MAX 16384
-
-#define STDIN_FILENO  0
-#define STDOUT_FILENO 1
-#define STDERR_FILENO 2
-
-#define O_RDONLY   0
-#define O_WRONLY   1
-#define O_RDWR     2
-#define O_CREAT    (1 << 6)
-#define O_EXCL     (1 << 7)
-#define O_TRUNC    (1 << 9)
-#define O_APPEND   (1 << 10)
-#define O_NONBLOCK (1 << 11)
-
-#define SEEK_SET 0
-#define SEEK_CUR 1
-#define SEEK_END 2
-
-typedef uint16_t mode_t;
-
-typedef ptrdiff_t off_t;
-typedef ptrdiff_t ssize_t;
-
-char *getcwd(char *buf, size_t size);
-char *getwd(char *buf);
-char *get_current_dir_name(void);
-int fchdir(int fd);
-int chdir(const char *path);
-
-#ifndef __DONT_DEFINE_OPEN__
-int open(const char *pathname, int flags, ...);
-#endif
-
-int creat(const char *pathname, mode_t mode);
-int close(int fd);
-ssize_t read(int fd, void *buf, size_t count);
-ssize_t write(int fd, const void *buf, size_t count);
-off_t lseek(int fd, off_t offset, int whence);
-
-#endif
diff --git a/crt/src/algorithm.c b/crt/src/algorithm.c
deleted file mode 100644 (file)
index c45e1d4..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * algorithm.c
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <string.h>
-
-void qsort(void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*))
-{
-    void *pivot = (void*)((uintptr_t)base + (nmemb / 2) * size);
-    void *temp = __builtin_alloca(size);
-    if (nmemb <= 1) return;
-
-    size_t low = 0;
-    size_t high = nmemb - 1;
-
-    for (;;)
-    {
-        while (compare((void*)((uintptr_t)base + low * size), pivot) < 0) low++;
-        while (compare((void*)((uintptr_t)base + high * size), pivot) > 0) high--;
-        if (low >= high) break;
-
-        memcpy(temp, (void*)((uintptr_t)base + low * size), size);
-        memcpy((void*)((uintptr_t)base + low * size), (void*)((uintptr_t)base + high * size), size);
-        memcpy((void*)((uintptr_t)base + high * size), temp, size);
-    }
-
-    qsort(base, high, size, compare);
-    qsort((void*)((size_t)base + high * size), nmemb - high, size, compare);
-}
-
-void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*))
-{
-    long low = 0;
-    long high = nmemb - 1;
-
-    while (low <= high)
-    {
-        long mid = low + (high - low) / 2;
-        void *current = (void*)((uintptr_t)base + mid * size);
-        int comp = compare(current, key);
-
-        if (comp < 0) low = mid + 1;
-        else if (comp > 0) high = mid - 1;
-        else return current;
-    }
-
-    return NULL;
-}
diff --git a/crt/src/crt0.c b/crt/src/crt0.c
deleted file mode 100644 (file)
index e8a5e7a..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * crt0.c
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <monolithium.h>
-
-int __crt_initialize_heap(void);
-int __crt_initialize_files(process_params_t *params);
-int main(int argc, char **argv);
-
-void process_startup(process_params_t *params)
-{
-    int argc = 1;
-    char *ptr;
-    int space = 1;
-
-    if (__crt_initialize_heap() < 0) syscall_terminate(INVALID_HANDLE, 255);
-    if (__crt_initialize_files(params) < 0) syscall_terminate(INVALID_HANDLE, 255);
-
-    for (ptr = params->command_line; *ptr; ptr++)
-    {
-        if (space != (isspace(*ptr) != 0))
-        {
-            argc++;
-            space = !space;
-        }
-    }
-
-    char **argv = (char**)__builtin_alloca(argc * sizeof(char*));
-    argc = 0;
-
-    for (ptr = strtok(params->command_line, " \t\r\n\v\f"); ptr != NULL; ptr = strtok(NULL, " \t\r\n\v\f"))
-    {
-        if (*ptr) argv[argc++] = ptr;
-    }
-
-    argv[argc] = NULL;
-
-    int exit_code = main(argc, argv);
-    exit(exit_code);
-}
diff --git a/crt/src/ctype.c b/crt/src/ctype.c
deleted file mode 100644 (file)
index 797ff58..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * ctype.c
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <string.h>
-
-int isprint(int c)
-{
-    return c >= 0x20 && c <= 0x7E;
-}
-
-int isdigit(int c)
-{
-    return c >= '0' && c <= '9';
-}
-
-int isxdigit(int c)
-{
-    return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
-}
-
-int isspace(int c)
-{
-    return strchr(" \t\n\v\f\r", c) != NULL;
-}
-
-char tolower(char c)
-{
-    if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
-    return c;
-}
-
-char toupper(char c)
-{
-    if (c >= 'a' && c <= 'z') c -= 'a' - 'A';
-    return c;
-}
diff --git a/crt/src/errno.c b/crt/src/errno.c
deleted file mode 100644 (file)
index 0c63fc8..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * errno.c
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <errno.h>
-#include <monolithium.h>
-
-int errno = 0;
-
-int __crt_translate_error(uint32_t status_code)
-{
-    switch (status_code)
-    {
-    case ERR_NOTFOUND:
-        return ENOENT;
-
-    case ERR_FORBIDDEN:
-        return EACCES;
-
-    case ERR_INVALID:
-        return EINVAL;
-
-    case ERR_EXISTS:
-        return EEXIST;
-
-    case ERR_NOMEMORY:
-        return ENOMEM;
-
-    case ERR_HARDWARE:
-        return EIO;
-
-    case ERR_BUSY:
-        return EAGAIN;
-
-    case ERR_WRITEPROT:
-        return EROFS;
-
-    case ERR_NOSYSCALL:
-        return ENOSYS;
-
-    case ERR_TIMEOUT:
-        return ETIMEDOUT;
-
-    case ERR_BADPTR:
-        return EFAULT;
-
-    case ERR_CANCELED:
-        return ECANCELED;
-
-    case ERR_ISDIR:
-        return EISDIR;
-
-    case ERR_ISNOTDIR:
-        return ENOTDIR;
-
-    case ERR_DISKFULL:
-        return ENOSPC;
-
-    case ERR_BEYOND:
-        return ENXIO;
-
-    case ERR_SMALLBUF:
-        return ETOOSMALL;
-
-    default:
-        return 0;
-    }
-}
diff --git a/crt/src/exit.c b/crt/src/exit.c
deleted file mode 100644 (file)
index 0af3d52..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * exit.c
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <monolithium.h>
-
-static void (*atexit_functions[ATEXIT_MAX])(void);
-static int num_atexit_functions = 0;
-
-int atexit(void (*function)(void))
-{
-    if (num_atexit_functions == ATEXIT_MAX) return -1;
-    atexit_functions[num_atexit_functions++] = function;
-    return 0;
-}
-
-void __attribute__((__noreturn__)) exit(int status)
-{
-    while (num_atexit_functions) atexit_functions[--num_atexit_functions]();
-
-    syscall_terminate(INVALID_HANDLE, status);
-    for (;;);
-}
diff --git a/crt/src/fcntl.c b/crt/src/fcntl.c
deleted file mode 100644 (file)
index a8b7109..0000000
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * fcntl.c
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <monolithium.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define __DONT_DEFINE_OPEN__
-#include <fcntl.h>
-
-#define MAX_OPEN_FILES 4096
-
-static handle_t mutex;
-static struct
-{
-    handle_t handle;
-    int flags;
-    int descriptor_flags;
-    off_t position;
-    size_t size;
-} descriptors[MAX_OPEN_FILES];
-
-handle_t __crt_get_raw_handle(int fd)
-{
-    syscall_wait_mutex(mutex, NO_TIMEOUT);
-    handle_t handle = descriptors[fd].handle;
-    syscall_release_mutex(mutex);
-    return handle;
-}
-
-static inline int __crt_open_handle_at(int fd, handle_t handle, int flags)
-{
-    object_type_t type;
-    sysret_t status = syscall_query_handle(handle, HANDLE_INFO_TYPE, &type, sizeof(type));
-
-    if (status != ERR_SUCCESS || (type != OBJECT_FILE && type != OBJECT_PIPE))
-    {
-        errno = EINVAL;
-        return -1;
-    }
-
-    if (type == OBJECT_FILE)
-    {
-        qword_t real_size;
-        status = syscall_query_file(handle, FILE_INFO_SIZE, &real_size, sizeof(real_size));
-        if (status != ERR_SUCCESS)
-        {
-            errno = __crt_translate_error(status);
-            return -1;
-        }
-
-        if (real_size > (qword_t)((size_t)-1))
-        {
-            errno = EFBIG;
-            return -1;
-        }
-
-        descriptors[fd].descriptor_flags = 0;
-        descriptors[fd].size = (size_t)real_size;
-    }
-    else
-    {
-        descriptors[fd].descriptor_flags = FD_PIPE;
-        descriptors[fd].size = 0;
-    }
-
-    descriptors[fd].handle = handle;
-    descriptors[fd].flags = flags;
-    descriptors[fd].position = 0;
-    return fd;
-}
-
-static inline int __crt_open_handle(handle_t handle, int flags)
-{
-    int fd;
-    syscall_wait_mutex(mutex, NO_TIMEOUT);
-
-    for (fd = 0; fd < MAX_OPEN_FILES; fd++)
-    {
-        if (descriptors[fd].handle == INVALID_HANDLE) break;
-    }
-
-    if (fd == MAX_OPEN_FILES)
-    {
-        errno = EMFILE;
-        return -1;
-    }
-
-    fd = __crt_open_handle_at(fd, handle, flags);
-
-    syscall_release_mutex(mutex);
-    return fd;
-}
-
-int open(const char *pathname, int flags, mode_t mode)
-{
-    handle_t handle;
-    char fullpath[PATH_MAX];
-
-    if (*pathname == '/')
-    {
-        if (strlen(pathname) >= PATH_MAX)
-        {
-            errno = ENAMETOOLONG;
-            return -1;
-        }
-
-        strcpy(fullpath, pathname);
-    }
-    else
-    {
-        getwd(fullpath);
-
-        if (strlen(fullpath) + strlen(pathname) >= PATH_MAX)
-        {
-            errno = ENAMETOOLONG;
-            return -1;
-        }
-
-        strcat(fullpath, pathname);
-    }
-
-    if ((flags & 3) == 3)
-    {
-        errno = EINVAL;
-        return -1;
-    }
-
-    dword_t kernel_flags = FILE_MODE_SHARE_READ | FILE_MODE_SHARE_WRITE;
-    dword_t attributes = 0;
-
-    if ((flags & 3) == O_RDONLY) kernel_flags |= FILE_MODE_READ;
-    else if ((flags & 3) == O_RDONLY) kernel_flags |= FILE_MODE_WRITE;
-    else kernel_flags |= FILE_MODE_READ | FILE_MODE_WRITE;
-
-    if (flags & O_CREAT) kernel_flags |= FILE_MODE_CREATE;
-    if (flags & O_TRUNC) kernel_flags |= FILE_MODE_TRUNCATE;
-
-    sysret_t status = syscall_open_file(fullpath, &handle, kernel_flags, attributes);
-    if (status != ERR_SUCCESS)
-    {
-        errno = __crt_translate_error(status);
-        return -1;
-    }
-
-    int fd = __crt_open_handle(handle, flags);
-    if (fd < 0) syscall_close_object(handle);
-    return fd;
-}
-
-int creat(const char *pathname, mode_t mode)
-{
-    return open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
-}
-
-int close(int fd)
-{
-    int ret = -1;
-    syscall_wait_mutex(mutex, NO_TIMEOUT);
-
-    if (fd < 0 || fd >= MAX_OPEN_FILES || descriptors[fd].handle == INVALID_HANDLE)
-    {
-        errno = EBADF;
-        goto cleanup;
-    }
-
-    syscall_close_object(descriptors[fd].handle);
-    descriptors[fd].handle = INVALID_HANDLE;
-    ret = 0;
-
-cleanup:
-    syscall_release_mutex(mutex);
-    return ret;
-}
-
-ssize_t read(int fd, void *buf, size_t count)
-{
-    syscall_wait_mutex(mutex, NO_TIMEOUT);
-
-    size_t ret;
-    sysret_t status = syscall_read_file(descriptors[fd].handle, buf, descriptors[fd].position, count, &ret);
-
-    descriptors[fd].position += (off_t)ret;
-
-    if (status != ERR_SUCCESS && status != ERR_BEYOND)
-    {
-        errno = __crt_translate_error(status);
-        ret = (off_t)-1;
-    }
-
-    syscall_release_mutex(mutex);
-    return (ssize_t)ret;
-}
-
-ssize_t write(int fd, const void *buf, size_t count)
-{
-    syscall_wait_mutex(mutex, NO_TIMEOUT);
-
-    size_t ret;
-    sysret_t status = syscall_write_file(descriptors[fd].handle, buf, descriptors[fd].position, count, &ret);
-
-    descriptors[fd].position += (off_t)ret;
-
-    if (status != ERR_SUCCESS && status != ERR_BEYOND)
-    {
-        errno = __crt_translate_error(status);
-        ret = (off_t)-1;
-    }
-
-    syscall_release_mutex(mutex);
-    return (ssize_t)ret;
-}
-
-off_t lseek(int fd, off_t offset, int whence)
-{
-    if (whence < SEEK_SET || whence > SEEK_END)
-    {
-        errno = EINVAL;
-        return (off_t)-1;
-    }
-
-    syscall_wait_mutex(mutex, NO_TIMEOUT);
-
-    if (fd < 0 || fd >= MAX_OPEN_FILES || descriptors[fd].handle == INVALID_HANDLE)
-    {
-        errno = EBADF;
-        goto cleanup;
-    }
-
-    if (descriptors[fd].descriptor_flags & FD_PIPE)
-    {
-        errno = ESPIPE;
-        goto cleanup;
-    }
-
-    off_t origin = 0;
-    if (whence == SEEK_CUR) origin = descriptors[fd].position;
-    else if (whence == SEEK_END) origin = descriptors[fd].size;
-
-    off_t ret = origin + offset;
-
-    if ((offset > 0 && ret < origin) || (offset < 0 && ret > origin))
-    {
-        errno = EOVERFLOW;
-        goto cleanup;
-    }
-
-    descriptors[fd].position = ret;
-
-cleanup:
-    syscall_release_mutex(mutex);
-    return ret;
-}
-
-int dup(int oldfd)
-{
-    syscall_wait_mutex(mutex, NO_TIMEOUT);
-
-    handle_t duplicate;
-    int flags = descriptors[oldfd].flags;
-    sysret_t status = syscall_duplicate_handle(INVALID_HANDLE, descriptors[oldfd].handle, INVALID_HANDLE, &duplicate);
-    syscall_release_mutex(mutex);
-
-    if (status != ERR_SUCCESS)
-    {
-        errno = __crt_translate_error(status);
-        return -1;
-    }
-
-    return __crt_open_handle(duplicate, flags);
-}
-
-int dup2(int oldfd, int newfd)
-{
-    int fd = -1;
-    syscall_wait_mutex(mutex, NO_TIMEOUT);
-
-    handle_t duplicate;
-    sysret_t status = syscall_duplicate_handle(INVALID_HANDLE, descriptors[oldfd].handle, INVALID_HANDLE, &duplicate);
-
-    if (status != ERR_SUCCESS)
-    {
-        errno = __crt_translate_error(status);
-        goto cleanup;
-    }
-
-    fd = __crt_open_handle_at(newfd, duplicate, descriptors[oldfd].flags);
-
-cleanup:
-    syscall_release_mutex(mutex);
-    return fd;
-}
-
-int __crt_initialize_files(process_params_t *params)
-{
-    sysret_t ret = syscall_create_mutex(NULL, TRUE, &mutex);
-    if (ret != ERR_SUCCESS) return -1;
-
-    int i;
-    for (i = 0; i < MAX_OPEN_FILES; i++) descriptors[i].handle = INVALID_HANDLE;
-
-    if (params->standard_input != INVALID_HANDLE) __crt_open_handle_at(STDIN_FILENO, params->standard_input, O_RDONLY);
-    if (params->standard_input != INVALID_HANDLE) __crt_open_handle_at(STDOUT_FILENO, params->standard_output, O_WRONLY);
-    if (params->standard_input != INVALID_HANDLE) __crt_open_handle_at(STDERR_FILENO, params->standard_error, O_WRONLY);
-    return 0;
-}
diff --git a/crt/src/io.c b/crt/src/io.c
deleted file mode 100644 (file)
index 2b46167..0000000
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * io.c
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include "io_priv.h"
-
-static list_entry_t open_files;
-
-FILE *stdin  = NULL;
-FILE *stdout = NULL;
-FILE *stderr = NULL;
-
-int fileno_unlocked(FILE *stream)
-{
-    if (stream->fd == -1) errno = EBADF;
-    return stream->fd;
-}
-
-int fileno(FILE *stream)
-{
-    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
-    int ret = fileno_unlocked(stream);
-    syscall_release_mutex(stream->mutex);
-    return ret;
-}
-
-static int __crt_fflush_stream(FILE *stream)
-{
-    if (!stream->buffer) return EOF;
-
-    if (!(stream->flags & FILE_BUFFER_DIR))
-    {
-        stream->buffer_start = stream->buffer_end = 0;
-        stream->flags &= ~FILE_BUFFER_FULL;
-        return 0;
-    }
-
-    if (stream->fd == -1) return 0;
-
-    if (stream->buffer_start < stream->buffer_end)
-    {
-        ssize_t written = write(stream->fd, &stream->buffer[stream->buffer_start], stream->buffer_end - stream->buffer_start);
-        if (written < 0) return EOF;
-
-        stream->buffer_start += written;
-        stream->buffer_start %= stream->buffer_size;
-        if (written) stream->flags &= ~FILE_BUFFER_FULL;
-    }
-    else
-    {
-        if (stream->buffer_start < stream->buffer_size)
-        {
-            ssize_t written = write(stream->fd, &stream->buffer[stream->buffer_start], stream->buffer_size - stream->buffer_start);
-            if (written < 0) return EOF;
-
-            stream->buffer_start += written;
-            stream->buffer_start %= stream->buffer_size;
-            if (written) stream->flags &= ~FILE_BUFFER_FULL;
-        }
-
-        if (stream->buffer_end)
-        {
-            ssize_t written = write(stream->fd, stream->buffer, stream->buffer_end);
-            if (written < 0) return EOF;
-
-            stream->buffer_start += written;
-            stream->buffer_start %= stream->buffer_size;
-            if (written) stream->flags &= ~FILE_BUFFER_FULL;
-        }
-    }
-
-    return 0;
-}
-
-int fflush_unlocked(FILE *stream)
-{
-    if (stream) return __crt_fflush_stream(stream);
-
-    list_entry_t *entry;
-    int result = 0;
-
-    for (entry = open_files.next; entry != &open_files; entry = entry->next)
-    {
-        if (__crt_fflush_stream(CONTAINER_OF(entry, struct __crt_file, link)) == EOF)
-        {
-            result = EOF;
-        }
-    }
-
-    return result;
-}
-
-int fflush(FILE *stream)
-{
-    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
-    int ret = fflush_unlocked(stream);
-    syscall_release_mutex(stream->mutex);
-    return ret;
-}
-
-int setvbuf(FILE *stream, char *buf, int mode, size_t size)
-{
-    int ret = EOF;
-    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
-
-    switch (mode)
-    {
-    case _IONBF:
-        if (fflush_unlocked(stream) == 0)
-        {
-            stream->buffer = NULL;
-            stream->buffer_size = 0;
-            ret = 0;
-        }
-        break;
-
-    case _IOLBF:
-        if (!buf || fflush_unlocked(stream) == 0)
-        {
-            if (buf)
-            {
-                stream->buffer = buf;
-                stream->buffer_size = size;
-            }
-
-            stream->flags |= FILE_BUFFER_LINE;
-            ret = 0;
-        }
-        break;
-
-    case _IOFBF:
-        if (!buf || fflush_unlocked(stream) == 0)
-        {
-            if (buf)
-            {
-                stream->buffer = buf;
-                stream->buffer_size = size;
-            }
-
-            stream->flags &= ~FILE_BUFFER_LINE;
-            ret = 0;
-        }
-        break;
-    }
-
-    syscall_release_mutex(stream->mutex);
-    return ret;
-}
-
-void setbuf(FILE *stream, char *buf)
-{
-    setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
-}
-
-void setbuffer(FILE *stream, char *buf, size_t size)
-{
-    setvbuf(stream, buf, buf ? _IOFBF : _IONBF, size);
-}
-
-void setlinebuf(FILE *stream)
-{
-    setvbuf(stream, NULL, _IOLBF, 0);
-}
-
-inline int fgetc_unlocked(FILE *stream)
-{
-    char c;
-
-    if (!(stream->flags & FILE_READ))
-    {
-        errno = EPERM;
-        return EOF;
-    }
-
-    if (stream->buffer)
-    {
-        if (stream->flags & FILE_BUFFER_DIR)
-        {
-            fflush_unlocked(stream);
-            stream->flags &= ~FILE_BUFFER_DIR;
-        }
-
-        if (stream->buffer_start == stream->buffer_end && !(stream->flags & FILE_BUFFER_FULL))
-        {
-            if (stream->fd == -1) return EOF;
-
-            if (stream->buffer_end < stream->buffer_size)
-            {
-                ssize_t amount = read(stream->fd, &stream->buffer[stream->buffer_end], stream->buffer_size - stream->buffer_end);
-                if (amount < 0) return EOF;
-
-                stream->buffer_end += amount;
-                stream->buffer_end %= stream->buffer_size;
-                if (amount && (stream->buffer_start == stream->buffer_end)) stream->flags |= FILE_BUFFER_FULL;
-            }
-
-            if (stream->buffer_end < stream->buffer_start)
-            {
-                ssize_t amount = read(stream->fd, &stream->buffer[stream->buffer_end], stream->buffer_start - stream->buffer_end);
-                if (amount < 0) return EOF;
-
-                stream->buffer_end += amount;
-                stream->buffer_end %= stream->buffer_size;
-                if (amount && (stream->buffer_start == stream->buffer_end)) stream->flags |= FILE_BUFFER_FULL;
-            }
-        }
-
-        c = stream->buffer[stream->buffer_start];
-        stream->buffer_start++;
-        stream->buffer_end %= stream->buffer_size;
-
-        stream->flags &= ~FILE_BUFFER_FULL;
-    }
-    else
-    {
-        if (read(stream->fd, &c, 1) != 1) c = EOF;
-    }
-
-    return (int)((unsigned int)c);
-}
-
-int fgetc(FILE *stream)
-{
-    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
-    int ret = fgetc_unlocked(stream);
-    syscall_release_mutex(stream->mutex);
-    return ret;
-}
-
-inline int fputc_unlocked(int c, FILE *stream)
-{
-    if (!(stream->flags & FILE_WRITE))
-    {
-        errno = EPERM;
-        return EOF;
-    }
-
-    if (stream->buffer)
-    {
-        if (!(stream->flags & FILE_BUFFER_DIR))
-        {
-            fflush_unlocked(stream);
-            stream->flags |= FILE_BUFFER_DIR;
-        }
-
-        if (stream->flags & FILE_BUFFER_FULL)
-        {
-            errno = ENOSPC;
-            return EOF;
-        }
-
-        stream->buffer[stream->buffer_end] = (uint8_t)c;
-        stream->buffer_end++;
-        stream->buffer_end %= stream->buffer_size;
-
-        if (stream->buffer_start == stream->buffer_end)
-        {
-            stream->flags |= FILE_BUFFER_FULL;
-        }
-
-        if (stream->fd != -1 && ((stream->flags & FILE_BUFFER_FULL) || ((stream->flags & FILE_BUFFER_LINE) && (char)c == '\n')))
-        {
-            fflush_unlocked(stream);
-        }
-    }
-    else
-    {
-        if (write(stream->fd, &c, 1) != 1) return EOF;
-    }
-
-    return 0;
-}
-
-int fputc(int c, FILE *stream)
-{
-    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
-    int ret = fputc_unlocked(c, stream);
-    syscall_release_mutex(stream->mutex);
-    return ret;
-}
-
-char *fgets_unlocked(char *s, int size, FILE *stream)
-{
-    int c;
-    char *ptr = s;
-
-    while (size-- > 0 && (c = fgetc_unlocked(stream)) != EOF)
-    {
-        *ptr++ = (char)c;
-        if (c == '\n') break;
-    }
-
-    return (s != ptr) ? s : NULL;
-}
-
-char *fgets(char *s, int size, FILE *stream)
-{
-    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
-    char *ret = fgets_unlocked(s, size, stream);
-    syscall_release_mutex(stream->mutex);
-    return ret;
-}
-
-int fputs_unlocked(const char *s, FILE *stream)
-{
-    const char *ptr = s;
-    while (*ptr) if (fputc_unlocked(*ptr++, stream) == EOF) return EOF;
-    return 0;
-}
-
-int fputs(const char *s, FILE *stream)
-{
-    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
-    int ret = fputs_unlocked(s, stream);
-    syscall_release_mutex(stream->mutex);
-    return ret;
-}
-
-int ungetc(int c, FILE *stream)
-{
-    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
-
-    if (stream->flags & FILE_BUFFER_DIR)
-    {
-        fflush_unlocked(stream);
-        stream->flags &= ~FILE_BUFFER_DIR;
-    }
-
-    if (stream->buffer_start == 0) stream->buffer_start = stream->buffer_size;
-    stream->buffer_start--;
-
-    stream->buffer[stream->buffer_start] = (uint8_t)c;
-
-    syscall_release_mutex(stream->mutex);
-    return c;
-}
-
-char *gets(char *s)
-{
-    char *ptr = s;
-    int c;
-    while ((c = getchar()) != EOF) *ptr++ = (char)c;
-    return ptr != s ? s : NULL;
-}
-
-int puts(const char *s)
-{
-    if (fputs(s, stdout) == EOF) return EOF;
-    if (fputc('\n', stdout) == EOF) return EOF;
-    return 0;
-}
-
-FILE *fdopen(int fd, const char *mode)
-{
-    FILE *stream = (FILE*)malloc(sizeof(FILE) + BUFSIZ);
-
-    if (stream == NULL)
-    {
-        errno = ENOMEM;
-        return NULL;
-    }
-
-    sysret_t status = syscall_create_mutex(NULL, TRUE, &stream->mutex);
-    if (status != ERR_SUCCESS)
-    {
-        free(stream);
-        errno = __crt_translate_error(status);
-        return NULL;
-    }
-
-    stream->flags = 0;
-
-    const char *ptr;
-    for (ptr = mode; *ptr; ptr++)
-    {
-        switch (*ptr)
-        {
-        case 'r':
-            stream->flags |= FILE_READ;
-            break;
-        case 'w':
-            stream->flags |= FILE_WRITE;
-            break;
-        case 'a':
-            stream->flags |= FILE_APPEND;
-            break;
-        case '+':
-            stream->flags |= FILE_READ | FILE_WRITE;
-            break;
-        }
-    }
-
-    stream->fd = fd;
-
-    char *buffer = (char*)((uintptr_t)stream + sizeof(FILE));
-    setbuf(stream, buffer);
-    return stream;
-}
-
-FILE *fmemopen(void *buf, size_t size, const char *mode)
-{
-    FILE *stream = (FILE*)malloc(sizeof(FILE));
-    if (stream == NULL)
-    {
-        errno = ENOMEM;
-        return NULL;
-    }
-
-    sysret_t status = syscall_create_mutex(NULL, TRUE, &stream->mutex);
-    if (status != ERR_SUCCESS)
-    {
-        free(stream);
-        errno = __crt_translate_error(status);
-        return NULL;
-    }
-
-    stream->flags = 0;
-
-    const char *ptr;
-    for (ptr = mode; *ptr; ptr++)
-    {
-        switch (*ptr)
-        {
-        case 'r':
-            stream->flags |= FILE_READ;
-            break;
-        case 'w':
-            stream->flags |= FILE_WRITE;
-            break;
-        case 'a':
-            stream->flags |= FILE_APPEND;
-            break;
-        case '+':
-            stream->flags |= FILE_READ | FILE_WRITE;
-            break;
-        }
-    }
-
-    stream->fd = -1;
-    stream->buffer = buf;
-    stream->buffer_size = size;
-    stream->buffer_start = stream->buffer_end = 0;
-
-    list_append(&open_files, &stream->link);
-    return stream;
-}
-
-FILE *fopen(const char *pathname, const char *mode)
-{
-    int open_flags = 0;
-
-    const char *ptr;
-    for (ptr = mode; *ptr; ptr++)
-    {
-        switch (*ptr)
-        {
-        case 'r':
-            open_flags = (open_flags & ~3) | O_RDONLY;
-            break;
-        case 'w':
-            open_flags = (open_flags & ~3) | O_WRONLY;
-            break;
-        case 'a':
-            open_flags |= O_APPEND;
-            break;
-        case '+':
-            open_flags = (open_flags & ~3) | O_RDWR;
-            break;
-        }
-    }
-
-    int fd = open(pathname, open_flags);
-    if (fd < 0) return NULL;
-
-    FILE *stream = fdopen(fd, mode);
-    if (!stream) close(fd);
-    return NULL;
-}
-
-int fclose(FILE *stream)
-{
-    fflush(stream);
-    list_remove(&stream->link);
-    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
-
-    if (stream->fd) close(stream->fd);
-
-    syscall_close_object(stream->mutex);
-    free(stream);
-    return 0;
-}
diff --git a/crt/src/io_priv.h b/crt/src/io_priv.h
deleted file mode 100644 (file)
index c5258da..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * io_priv.h
- *
- * Copyright (C) 2018 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _IO_PRIV_H_
-#define _IO_PRIV_H_
-
-#include <monolithium.h>
-
-#define FILE_READ        (1 << 0)
-#define FILE_WRITE       (1 << 1)
-#define FILE_APPEND      (1 << 2)
-#define FILE_BUFFER_LINE (1 << 3)
-#define FILE_BUFFER_DIR  (1 << 4)
-#define FILE_BUFFER_FULL (1 << 31)
-
-struct __crt_file
-{
-    list_entry_t link;
-    handle_t mutex;
-    uint32_t flags;
-
-    int fd;
-
-    char *buffer;
-    size_t buffer_size;
-    size_t buffer_start, buffer_end;
-};
-
-#endif
diff --git a/crt/src/malloc.c b/crt/src/malloc.c
deleted file mode 100644 (file)
index c044c8f..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * heap.c
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <monolithium.h>
-
-#define ALLOCATED (1 << 0)
-
-typedef struct
-{
-    uint32_t magic;
-    uint32_t flags;
-    size_t size;
-} heap_header_t;
-
-__crt_heap_t *__crt_default_heap = NULL;
-
-static void __crt_heap_coalesce(__crt_heap_t *heap)
-{
-    heap_header_t *ptr = (heap_header_t*)heap->base;
-    heap_header_t *previous = NULL;
-
-    while ((uintptr_t)ptr >= (uintptr_t)heap->base && (uintptr_t)ptr < (uintptr_t)heap->base + heap->size)
-    {
-        heap_header_t *next = (heap_header_t*)((uintptr_t)ptr + sizeof(heap_header_t) + ptr->size);
-
-        if (previous && !(previous->flags & ALLOCATED) && !(ptr->flags & ALLOCATED))
-        {
-            if (((uintptr_t)ptr - (uintptr_t)heap->base) == heap->next_offset)
-            {
-                heap->next_offset = (uintptr_t)previous - (uintptr_t)heap->base;
-            }
-
-            previous->size += ptr->size + sizeof(heap_header_t);
-        }
-        else
-        {
-            previous = ptr;
-        }
-
-        ptr = next;
-    }
-}
-
-void *__crt_heap_realloc(__crt_heap_t *heap, void *ptr, size_t alignment, size_t size)
-{
-    if (!alignment || (alignment & (alignment - 1))) return NULL;
-
-    heap->lock_mutex_proc(heap->mutex);
-
-    if (!(heap->flags & __CRT_HEAP_FLAG_READY))
-    {
-        heap_header_t *header = (heap_header_t*)heap->base;
-        header->magic = heap->magic;
-        header->flags = 0;
-        header->size = heap->size - sizeof(heap_header_t);
-
-        heap->flags |= __CRT_HEAP_FLAG_READY;
-    }
-
-    if (!size)
-    {
-        if (ptr)
-        {
-            heap_header_t *header = (heap_header_t*)((uintptr_t)ptr - sizeof(heap_header_t));
-
-            if (header->flags & ALLOCATED)
-            {
-                header->flags &= ~ALLOCATED;
-                __crt_heap_coalesce(heap);
-            }
-            else
-            {
-                heap->problem(__CRT_HEAP_DOUBLE_FREE);
-            }
-        }
-
-        heap->unlock_mutex_proc(heap->mutex);
-        return NULL;
-    }
-
-    heap_header_t *source_block = NULL;
-
-    if (ptr)
-    {
-        heap_header_t *header = (heap_header_t*)((uintptr_t)ptr - sizeof(heap_header_t));
-
-        if (!(header->flags & ALLOCATED) || header->magic != heap->magic)
-        {
-            heap->problem(__CRT_HEAP_BAD_POINTER);
-            heap->unlock_mutex_proc(heap->mutex);
-            return NULL;
-        }
-
-        if (size > header->size)
-        {
-             heap_header_t *next = (heap_header_t*)((uintptr_t)ptr + header->size);
-
-             if (!(next->flags & ALLOCATED) && (header->size + next->size + sizeof(heap_header_t)) >= size)
-             {
-                 if (((uintptr_t)next - (uintptr_t)heap->base) == heap->next_offset)
-                 {
-                     heap->next_offset = (uintptr_t)header - (uintptr_t)heap->base;
-                 }
-
-                 header->size += next->size + sizeof(heap_header_t);
-                 if (heap->flags & __CRT_HEAP_FLAG_ZEROFILL) memset(next, 0, size - header->size - size);
-             }
-             else
-             {
-                 source_block = header;
-             }
-        }
-
-        if (size < (header->size - sizeof(heap_header_t)))
-        {
-            heap_header_t *new_block = (heap_header_t*)((uintptr_t)ptr + size);
-            new_block->magic = heap->magic;
-            new_block->flags = 0;
-            new_block->size = header->size - size - sizeof(heap_header_t);
-            header->size = size;
-            __crt_heap_coalesce(heap);
-        }
-
-        if (!source_block)
-        {
-            heap->unlock_mutex_proc(heap->mutex);
-            return ptr;
-        }
-    }
-
-    heap_header_t *hole = NULL;
-
-    if (heap->flags & __CRT_HEAP_FLAG_BESTFIT)
-    {
-        heap_header_t *current = (heap_header_t*)heap->base;
-        size_t minimum_size;
-
-        while ((uintptr_t)current < (uintptr_t)heap->base + heap->size)
-        {
-            if (current->magic != heap->magic)
-            {
-                heap->problem(__CRT_HEAP_CORRUPTED);
-                heap->unlock_mutex_proc(heap->mutex);
-                return NULL;
-            }
-
-            if (!(current->flags & ALLOCATED))
-            {
-                uintptr_t current_start = (uintptr_t)current + sizeof(heap_header_t);
-                uintptr_t aligned_start = (current_start + alignment - 1) & ~(alignment - 1);
-                size_t padding = aligned_start - current_start;
-
-                if (current->size > padding)
-                {
-                    size_t adjusted_size = current->size - padding;
-
-                    if (adjusted_size >= size && (!hole || adjusted_size < minimum_size))
-                    {
-                        hole = current;
-                        minimum_size = adjusted_size;
-                    }
-                }
-            }
-
-            heap_header_t *next = (heap_header_t*)((uintptr_t)current + sizeof(heap_header_t) + current->size);
-
-            if ((uintptr_t)next <= (uintptr_t)current)
-            {
-                heap->problem(__CRT_HEAP_CORRUPTED);
-                heap->unlock_mutex_proc(heap->mutex);
-                return NULL;
-            }
-
-            current = next;
-        }
-    }
-    else
-    {
-        uintptr_t offset = heap->next_offset;
-        int cycles = 0;
-
-        do
-        {
-            heap_header_t *current = (heap_header_t*)(heap->base + offset);
-
-            if (current->magic != heap->magic)
-            {
-                heap->problem(__CRT_HEAP_CORRUPTED);
-                heap->unlock_mutex_proc(heap->mutex);
-                return NULL;
-            }
-
-            if (!(current->flags & ALLOCATED))
-            {
-                uintptr_t current_start = (uintptr_t)current + sizeof(heap_header_t);
-                uintptr_t aligned_start = (current_start + alignment - 1) & ~(alignment - 1);
-                size_t padding = aligned_start - current_start;
-
-                if (current->size >= padding && (current->size - padding) >= size)
-                {
-                    hole = current;
-                    break;
-                }
-            }
-
-            offset += sizeof(heap_header_t) + current->size;
-            if (offset > heap->size)
-            {
-                offset = 0;
-                if (++cycles > 1)
-                {
-                    heap->problem(__CRT_HEAP_CORRUPTED);
-                    heap->unlock_mutex_proc(heap->mutex);
-                    return NULL;
-                }
-            }
-        }
-        while (offset != heap->next_offset);
-
-        heap->next_offset = offset;
-    }
-
-    if (!hole)
-    {
-        heap->problem(__CRT_HEAP_OUT_OF_MEMORY);
-        heap->unlock_mutex_proc(heap->mutex);
-        return NULL;
-    }
-
-    int coalesce = 0;
-    uintptr_t start_address = (uintptr_t)hole + sizeof(heap_header_t);
-    uintptr_t aligned_start = (start_address + alignment - 1) & ~(alignment - 1);
-    size_t padding = aligned_start - start_address;
-
-    if (padding > sizeof(heap_header_t))
-    {
-        heap_header_t *new_block = (heap_header_t*)(aligned_start - sizeof(heap_header_t));
-        new_block->magic = heap->magic;
-        new_block->flags = 0;
-        new_block->size = hole->size - padding;
-        hole->size -= padding + sizeof(heap_header_t);
-
-        hole = new_block;
-        coalesce = 1;
-    }
-    else if (padding)
-    {
-        heap_header_t *previous = (heap_header_t*)heap->base;
-
-        while ((uintptr_t)previous < (uintptr_t)heap->base + heap->size)
-        {
-            heap_header_t *next = (heap_header_t*)((uintptr_t)previous + sizeof(heap_header_t) + previous->size);
-            if (next == hole) break;
-
-            if ((uintptr_t)next <= (uintptr_t)previous)
-            {
-                heap->problem(__CRT_HEAP_CORRUPTED);
-                heap->unlock_mutex_proc(heap->mutex);
-                return NULL;
-            }
-
-            previous = next;
-        }
-
-        if ((uintptr_t)previous < (uintptr_t)heap->base
-            || (uintptr_t)previous >= (uintptr_t)heap->base + heap->size
-            || previous->magic != heap->magic)
-        {
-            heap->problem(__CRT_HEAP_CORRUPTED);
-            heap->unlock_mutex_proc(heap->mutex);
-            return NULL;
-        }
-
-        previous->size += padding;
-
-        heap_header_t *new_block = (heap_header_t*)(aligned_start - sizeof(heap_header_t));
-        memmove(new_block, hole, sizeof(heap_header_t));
-        if (heap->next_offset == (uintptr_t)hole - (uintptr_t)heap->base) heap->next_offset += padding;
-
-        hole = new_block;
-        hole->size -= padding;
-    }
-
-    hole->flags |= ALLOCATED;
-
-    if (hole->size > sizeof(heap_header_t) && size < (hole->size - sizeof(heap_header_t)))
-    {
-        heap_header_t *new_block = (heap_header_t*)((uintptr_t)hole + size + sizeof(heap_header_t));
-        new_block->magic = heap->magic;
-        new_block->flags = 0;
-        new_block->size = hole->size - size - sizeof(heap_header_t);
-        hole->size = size;
-        coalesce = 1;
-    }
-
-    void *destination = (void*)((uintptr_t)hole + sizeof(heap_header_t));
-    if (heap->flags & __CRT_HEAP_FLAG_ZEROFILL) memset(destination, 0, size);
-
-    if (source_block)
-    {
-        void *source = (void*)((uintptr_t)source_block + sizeof(heap_header_t));
-        memcpy(destination, source, source_block->size);
-        source_block->flags &= ~ALLOCATED;
-        coalesce = 1;
-    }
-
-    if (coalesce) __crt_heap_coalesce(heap);
-    heap->unlock_mutex_proc(heap->mutex);
-    return destination;
-}
-
-void *aligned_alloc(size_t alignment, size_t size)
-{
-    return __crt_heap_realloc(__crt_default_heap, NULL, alignment, size);
-}
-
-void *realloc(void *ptr, size_t size)
-{
-    return __crt_heap_realloc(__crt_default_heap, ptr, sizeof(long), size);
-}
-
-void *malloc(size_t size)
-{
-    return __crt_heap_realloc(__crt_default_heap, NULL, sizeof(long), size);
-}
-
-void free(void *ptr)
-{
-    __crt_heap_realloc(__crt_default_heap, ptr, sizeof(long), 0);
-}
-
-void *calloc(size_t nmemb, size_t size)
-{
-    void *ptr = malloc(nmemb * size);
-    if (!ptr) return NULL;
-
-    memset(ptr, 0, nmemb * size);
-    return ptr;
-}
-
-static void __crt_heap_lock(void *mutex)
-{
-    syscall_wait_mutex((handle_t)mutex, NO_TIMEOUT);
-}
-
-static void __crt_heap_unlock(void *mutex)
-{
-    syscall_release_mutex((handle_t)mutex);
-}
-
-static void __crt_heap_problem(int problem)
-{
-    // TODO
-}
-
-int __crt_initialize_heap(void)
-{
-    static __crt_heap_t heap;
-
-    heap.magic             = 0x70616548;
-    heap.base              = NULL;
-    heap.size              = 0x10000000;
-    heap.flags             = 0;
-    heap.next_offset       = 0;
-    heap.lock_mutex_proc   = __crt_heap_lock;
-    heap.unlock_mutex_proc = __crt_heap_unlock;
-    heap.problem           = __crt_heap_problem;
-
-    sysret_t status = syscall_create_mutex(NULL, TRUE, (handle_t*)&heap.mutex);
-    if (status != ERR_SUCCESS) return -1;
-
-    status = syscall_alloc_memory(INVALID_HANDLE, &heap.base, heap.size, MEMORY_BLOCK_ACCESSIBLE | MEMORY_BLOCK_WRITABLE);
-    if (status != ERR_SUCCESS) return -1;
-
-    __crt_default_heap = &heap;
-    return 0;
-}
diff --git a/crt/src/numconv.c b/crt/src/numconv.c
deleted file mode 100644 (file)
index 2b425e1..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * numconv.c
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#define DEFINE_XTOA(t, p, s)                                            \
-    char *p##toa(t value, char *str, int base)                          \
-    {                                                                   \
-        char *ptr = str;                                                \
-        if (base < 2 || base > 36) return NULL;                         \
-                                                                        \
-        if (value == 0##s)                                              \
-        {                                                               \
-            *ptr++ = '0';                                               \
-            *ptr++ = '\0';                                              \
-            return str;                                                 \
-        }                                                               \
-                                                                        \
-        if (value < 0##s)                                               \
-        {                                                               \
-            *ptr++ = '-';                                               \
-            value = -value;                                             \
-        }                                                               \
-                                                                        \
-        t temp;                                                         \
-        for (temp = value; temp > 0##s; temp /= (t)base) ptr++;         \
-        *ptr = '\0';                                                    \
-                                                                        \
-        while (value > 0##s)                                            \
-        {                                                               \
-            *--ptr = all_digits[value % (t)base];                       \
-            value /= (t)base;                                           \
-        }                                                               \
-                                                                        \
-        return str;                                                     \
-    }                                                                   \
-                                                                        \
-    char *u##p##toa(unsigned t value, char *str, int base)              \
-    {                                                                   \
-        char *ptr = str;                                                \
-        if (base < 2 || base > 36) return NULL;                         \
-                                                                        \
-        if (value == 0U##s)                                             \
-        {                                                               \
-            *ptr++ = '0';                                               \
-            *ptr++ = '\0';                                              \
-            return str;                                                 \
-        }                                                               \
-                                                                        \
-        unsigned t temp;                                                \
-        for (temp = value; temp > 0U##s; temp /= (unsigned t)base) ptr++; \
-        *ptr = '\0';                                                    \
-                                                                        \
-        while (value > 0U##s)                                           \
-        {                                                               \
-            *--ptr = all_digits[value % (unsigned t)base];              \
-            value /= (unsigned t)base;                                  \
-        }                                                               \
-                                                                        \
-        return str;                                                     \
-    }
-
-#define DEFINE_ATOX(t, n, p, s)                                         \
-    t ato##p(const char *str)                                           \
-    {                                                                   \
-        return strto##p(str, NULL, 10);                                 \
-    }                                                                   \
-                                                                        \
-    t strto##p(const char *str, char **endptr, int base)                \
-    {                                                                   \
-        const char *ptr;                                                \
-        t result = 0##s;                                                \
-        int overflow = 0, negative = 0;                                 \
-                                                                        \
-        if (base < 2 || base > 36) return 0;                            \
-                                                                        \
-        switch (*str)                                                   \
-        {                                                               \
-        case '-':                                                       \
-            negative = 1;                                               \
-        case '+':                                                       \
-            str++;                                                      \
-            break;                                                      \
-        }                                                               \
-                                                                        \
-        for (ptr = str; *ptr; ptr++)                                    \
-        {                                                               \
-            char *digit_ptr = strchr(all_digits, toupper(*ptr));        \
-            if (digit_ptr == NULL) break;                               \
-                                                                        \
-            t digit = (t)(digit_ptr - all_digits);                      \
-            if (digit >= base) break;                                   \
-                                                                        \
-            t new_result = result * (t)base + digit;                    \
-            if (new_result < result) overflow = 1;                      \
-            result = new_result;                                        \
-        }                                                               \
-                                                                        \
-        if (overflow)                                                   \
-        {                                                               \
-            errno = ERANGE;                                             \
-            return negative ? n##_MIN : n##_MAX;                        \
-        }                                                               \
-                                                                        \
-        if (negative) result = -result;                                 \
-        if (endptr) *endptr = (char*)ptr;                               \
-        return result;                                                  \
-    }                                                                   \
-                                                                        \
-    unsigned t strtou##p(const char *str, char **endptr, int base)      \
-    {                                                                   \
-        const char *ptr;                                                \
-        unsigned t result = 0UL;                                        \
-        int overflow = 0;                                               \
-                                                                        \
-        if (base < 2 || base > 36) return 0;                            \
-                                                                        \
-        for (ptr = str; *ptr; ptr++)                                    \
-        {                                                               \
-            char *digit_ptr = strchr(all_digits, toupper(*ptr));        \
-            if (digit_ptr == NULL) break;                               \
-                                                                        \
-            unsigned t digit = (unsigned t)(digit_ptr - all_digits);    \
-            if (digit >= base) break;                                   \
-                                                                        \
-            unsigned t new_result = result * (unsigned t)base + digit;  \
-            if (new_result < result) overflow = 1;                      \
-            result = new_result;                                        \
-        }                                                               \
-                                                                        \
-        if (overflow)                                                   \
-        {                                                               \
-            errno = ERANGE;                                             \
-            return U##n##_MAX;                                          \
-        }                                                               \
-                                                                        \
-        if (endptr) *endptr = (char*)ptr;                               \
-        return result;                                                  \
-    }
-
-static const char all_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-DEFINE_XTOA(int, i, );
-DEFINE_XTOA(long, l, L);
-DEFINE_XTOA(long long, ll, LL);
-
-DEFINE_ATOX(long, LONG, l, L);
-DEFINE_ATOX(long long, LLONG, ll, LL);
-
-int atoi(const char *str)
-{
-    return (int)strtol(str, NULL, 10);
-}
diff --git a/crt/src/printf.c b/crt/src/printf.c
deleted file mode 100644 (file)
index 57a83d8..0000000
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * printf.c
- *
- * Copyright (C) 2018 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <monolithium.h>
-#include "io_priv.h"
-
-#define __CRT_PRINTF_FLAG_ALIGN_LEFT         (1 << 0)
-#define __CRT_PRINTF_FLAG_PLUS               (1 << 1)
-#define __CRT_PRINTF_FLAG_SPACE              (1 << 2)
-#define __CRT_PRINTF_FLAG_EXTRA              (1 << 3)
-#define __CRT_PRINTF_FLAG_ZERO_PAD           (1 << 4)
-#define __CRT_PRINTF_FLAG_EXTERNAL_WIDTH     (1 << 5)
-#define __CRT_PRINTF_FLAG_EXTERNAL_PRECISION (1 << 6)
-#define __CRT_PRINTF_FLAG_DEFAULT_WIDTH      (1 << 7)
-#define __CRT_PRINTF_FLAG_DEFAULT_PRECISION  (1 << 8)
-
-typedef struct
-{
-    FILE *stream;
-    char *string;
-    size_t size;
-} __crt_stream_or_string_t;
-
-static int __crt_strputc(__crt_stream_or_string_t *str, char c)
-{
-    if (str->stream)
-    {
-        return fputc_unlocked(c, str->stream) != EOF;
-    }
-    else
-    {
-        if (str->size > 1)
-        {
-            *str->string++ = c;
-            str->size--;
-        }
-
-        return 1;
-    }
-}
-
-static int __crt_strputs(__crt_stream_or_string_t *str, const char *s)
-{
-    if (str->stream)
-    {
-        return fputs_unlocked(s, str->stream) != EOF ? strlen(s) : 0;
-    }
-    else
-    {
-        int length = strlen(s);
-
-        if (str->size > 1)
-        {
-            strncpy(str->string, s, str->size - 1);
-
-            if (length < str->size)
-            {
-                str->string += length;
-                str->size -= length;
-            }
-            else
-            {
-                str->string += str->size - 1;
-                str->size = 0;
-            }
-        }
-
-        return length;
-    }
-}
-
-static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *format, va_list ap)
-{
-    int ret = 0;
-    if (str->stream) syscall_wait_mutex(str->stream->mutex, NO_TIMEOUT);
-
-    const char *ptr;
-    for (ptr = format; *ptr; ptr++)
-    {
-        if (*ptr == '%')
-        {
-            unsigned long flags = 0;
-            unsigned int width = 0, precision = 0;
-
-            ptr++;
-
-            while (*ptr)
-            {
-                if (*ptr == '-') flags |= __CRT_PRINTF_FLAG_ALIGN_LEFT;
-                else if (*ptr == '+') flags |= __CRT_PRINTF_FLAG_PLUS;
-                else if (*ptr == ' ') flags |= __CRT_PRINTF_FLAG_SPACE;
-                else if (*ptr == '#') flags |= __CRT_PRINTF_FLAG_EXTRA;
-                else if (*ptr == '0') flags |= __CRT_PRINTF_FLAG_ZERO_PAD;
-                else break;
-
-                ptr++;
-            }
-
-            if (*ptr == '*') flags |= __CRT_PRINTF_FLAG_EXTERNAL_WIDTH;
-            else if (isdigit(*ptr)) width = strtoul(ptr, (char**)&ptr, 10);
-            else flags |= __CRT_PRINTF_FLAG_DEFAULT_WIDTH;
-
-            if (*ptr == '.')
-            {
-                ptr++;
-                if (*ptr == '*') flags |= __CRT_PRINTF_FLAG_EXTERNAL_PRECISION;
-                else if (isdigit(*ptr)) precision = strtoul(ptr, (char**)&ptr, 10);
-                else flags |= __CRT_PRINTF_FLAG_DEFAULT_PRECISION;
-            }
-            else
-            {
-                flags |= __CRT_PRINTF_FLAG_DEFAULT_PRECISION;
-            }
-
-            int variable_size = 0;
-
-            if (*ptr == 'h')
-            {
-                variable_size--;
-
-                if (*++ptr == 'h')
-                {
-                    variable_size--;
-                    ptr++;
-                }
-            }
-            else if (*ptr == 'l')
-            {
-                variable_size++;
-
-                if (*++ptr == 'l')
-                {
-                    variable_size++;
-                    ptr++;
-                }
-            }
-
-            const char *data = NULL;
-            char buffer[512];
-            int radix = 10;
-
-            switch (*ptr)
-            {
-            case 's':
-                data = va_arg(ap, const char*);
-                break;
-
-            case 'c':
-                data = buffer;
-                buffer[0] = (char)va_arg(ap, int);
-                buffer[1] = '\0';
-                break;
-
-            case 'd':
-            case 'i':
-                if (flags & __CRT_PRINTF_FLAG_DEFAULT_WIDTH) width = 0;
-                if (flags & __CRT_PRINTF_FLAG_DEFAULT_PRECISION) precision = 1;
-                data = buffer;
-
-                switch (variable_size)
-                {
-                case -2: itoa((char)va_arg(ap, int), buffer, 10); break;
-                case -1: itoa((short)va_arg(ap, int), buffer, 10); break;
-                case  0: itoa(va_arg(ap, int), buffer, 10); break;
-                case  1: ltoa(va_arg(ap, long), buffer, 10); break;
-                case  2: lltoa(va_arg(ap, long long), buffer, 10); break;
-                }
-                break;
-
-            case 'o':
-                radix = 8;
-                goto read_variable;
-            case 'x':
-            case 'X':
-                radix = 16;
-            case 'u':
-            read_variable:
-                if (flags & __CRT_PRINTF_FLAG_DEFAULT_WIDTH) width = 0;
-                if (flags & __CRT_PRINTF_FLAG_DEFAULT_PRECISION) precision = 1;
-                data = buffer;
-
-                switch (variable_size)
-                {
-                case -2: uitoa((unsigned char)va_arg(ap, unsigned int), buffer, radix); break;
-                case -1: uitoa((unsigned short)va_arg(ap, unsigned int), buffer, radix); break;
-                case  0: uitoa(va_arg(ap, unsigned int), buffer, radix); break;
-                case  1: ultoa(va_arg(ap, unsigned long), buffer, radix); break;
-                case  2: ulltoa(va_arg(ap, unsigned long long), buffer, radix); break;
-                }
-                break;
-
-            case '%':
-                data = buffer;
-                strcpy(buffer, "%");
-                break;
-            }
-
-            if (flags & __CRT_PRINTF_FLAG_EXTERNAL_WIDTH) width = va_arg(ap, unsigned int);
-            if (flags & __CRT_PRINTF_FLAG_EXTERNAL_PRECISION) precision = va_arg(ap, unsigned int);
-
-            int length = strlen(data);
-            char padding = (flags &__CRT_PRINTF_FLAG_ZERO_PAD) ? '0' : ' ';
-
-            switch (*ptr)
-            {
-            case 's':
-                if (!(flags & __CRT_PRINTF_FLAG_ALIGN_LEFT))
-                {
-                    while (length < width)
-                    {
-                        ret += __crt_strputc(str, padding);
-                        length++;
-                    }
-                }
-
-                if (precision)
-                {
-                    while (*data && precision > 0)
-                    {
-                        ret += __crt_strputc(str, *data++);
-                        precision--;
-                    }
-                }
-                else
-                {
-                    ret += __crt_strputs(str, data ? data : "(null)");
-                }
-                break;
-
-            case 'd':
-            case 'i':
-            case 'o':
-            case 'u':
-            case 'x':
-            case 'X':
-                if (flags & (__CRT_PRINTF_FLAG_PLUS | __CRT_PRINTF_FLAG_SPACE))
-                {
-                    if (*data == '-')
-                    {
-                        ret += __crt_strputc(str, '-');
-                        data++;
-                    }
-                    else
-                    {
-                        ret += __crt_strputc(str, (flags & __CRT_PRINTF_FLAG_PLUS) ? '+' : ' ');
-                        length++;
-                    }
-                }
-
-                if (!(flags & __CRT_PRINTF_FLAG_ALIGN_LEFT) && width > precision)
-                {
-                    while (length < width - precision)
-                    {
-                        ret += __crt_strputc(str, padding);
-                        length++;
-                    }
-
-                    while (length < width)
-                    {
-                        ret += __crt_strputc(str, '0');
-                        length++;
-                    }
-                }
-                else
-                {
-                    while (length < precision)
-                    {
-                        ret += __crt_strputc(str, '0');
-                        length++;
-                    }
-                }
-
-                ret += __crt_strputs(str, data);
-                break;
-            }
-
-            while (length < width)
-            {
-                ret += __crt_strputc(str, padding);
-                length++;
-            }
-        }
-        else
-        {
-            ret += __crt_strputc(str, *ptr);
-        }
-    }
-
-    if (str->string) *str->string = '\0';
-    if (str->stream) syscall_release_mutex(str->stream->mutex);
-    return ret;
-}
-
-int vsnprintf(char *string, size_t size, const char *format, va_list ap)
-{
-    __crt_stream_or_string_t str = { .stream = NULL, .string = string, .size = size };
-    return __crt_vstrprintf(&str, format, ap);
-}
-
-int vsprintf(char *str, const char *format, va_list ap)
-{
-    return vsnprintf(str, -1, format, ap);
-}
-
-int vprintf(const char *format, va_list ap)
-{
-    return vfprintf(stdout, format, ap);
-}
-
-int vfprintf(FILE *stream, const char *format, va_list ap)
-{
-    __crt_stream_or_string_t str = { .stream = stream, .string = NULL, .size = 0 };
-    return __crt_vstrprintf(&str, format, ap);
-}
-
-int fprintf(FILE *stream, const char *format, ...)
-{
-    va_list ap;
-    va_start(ap, format);
-    int ret = vfprintf(stream, format, ap);
-    va_end(ap);
-    return ret;
-}
-
-int snprintf(char *str, size_t size, const char *format, ...)
-{
-    va_list ap;
-    va_start(ap, format);
-    int ret = vsnprintf(str, size, format, ap);
-    va_end(ap);
-    return ret;
-}
-
-int sprintf(char *str, const char *format, ...)
-{
-    va_list ap;
-    va_start(ap, format);
-    int ret = vsprintf(str, format, ap);
-    va_end(ap);
-    return ret;
-}
-
-int printf(const char *format, ...)
-{
-    va_list ap;
-    va_start(ap, format);
-    int ret = vprintf(format, ap);
-    va_end(ap);
-    return ret;
-}
diff --git a/crt/src/setjmp.c b/crt/src/setjmp.c
deleted file mode 100644 (file)
index 646af24..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * setjmp.c
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <setjmp.h>
-#include <monolithium.h>
-
-int setjmp(jmp_buf env)
-{
-    syscall_query_thread(INVALID_HANDLE, THREAD_CPU_STATE_INFO, &env->state, sizeof(env->state));
-    return env->val;
-}
-
-int longjmp(jmp_buf env, int val)
-{
-    env->val = val ? val : 1;
-    syscall_set_thread(INVALID_HANDLE, THREAD_CPU_STATE_INFO, &env->state, sizeof(env->state));
-    return -1;
-}
diff --git a/crt/src/string.c b/crt/src/string.c
deleted file mode 100644 (file)
index 176ae65..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * string.c
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-char *strcpy(char *destination, const char *source)
-{
-    while (*source != 0) *(destination++) = *(source++);
-    *destination = 0;
-    return destination;
-}
-
-char *strncpy(char *destination, const char *source, uint32_t num)
-{
-    char *ptr = destination;
-    while ((num--) && (*source)) *(ptr++) = *(source++);
-    *ptr = 0;
-    return destination;
-}
-
-int strcmp(const char *str1, const char *str2)
-{
-    while (*str1 || *str2)
-    {
-        if (*str1 != *str2) break;
-        str1++;
-        str2++;
-    }
-
-    if (*str1 < *str2) return -1;
-    else if (*str1 > *str2) return 1;
-    else return 0;
-}
-
-int stricmp(const char *str1, const char *str2)
-{
-    while (*str1 || *str2)
-    {
-        if (tolower(*str1) != tolower(*str2)) break;
-        str1++;
-        str2++;
-    }
-    if (*str1 < *str2) return -1;
-    else if (*str1 > *str2) return 1;
-    else return 0;
-}
-
-int strncmp(const char *str1, const char *str2, size_t n)
-{
-    int i;
-
-    for (i = 0; i < n; i++)
-    {
-        if (str1[i] < str2[i]) return -1;
-        else if (str1[i] > str2[i]) return 1;
-        if (str1[i] == 0 || str2[i] == 0) break;
-    }
-
-    return 0;
-}
-
-char *strstr(const char *haystack, const char *needle)
-{
-    while (*haystack)
-    {
-        const char *s1 = haystack;
-        const char *s2 = needle;
-        int found = 1;
-
-        while (*s2)
-        {
-            if (*s1++ != *s2++)
-            {
-                found = 0;
-                break;
-            }
-        }
-
-        if (found) return (char*)haystack;
-        haystack++;
-    }
-
-    return NULL;
-}
-
-char *strchr(const char *str, char c)
-{
-    while ((*str != 0) && (*str != c)) str++;
-    if (*str == c) return (char*)str;
-    else return NULL;
-}
-
-char *strrchr(const char *str, char c)
-{
-    char *ret = NULL;
-
-    while (*str != 0)
-    {
-        if (*str == c) ret = (char*)str;
-        str++;
-    }
-
-    return ret;
-}
-
-char *strcat(char *destination, const char *source)
-{
-    strcpy(strchr(destination, '\0'), source);
-    return destination;
-}
-
-char *strncat(char *destination, const char *source, size_t n)
-{
-    char *ptr = strchr(destination, 0);
-    while ((n--) && (*source)) *(ptr++) = *(source++);
-    *ptr = 0;
-    return destination;
-}
-
-char *strdup(const char *source)
-{
-    char *destination = (char*)malloc(strlen(source) + 1);
-    if (destination) strcpy(destination, source);
-    return destination;
-}
-
-char *strtok_r(char *str, const char *delimiters, char **endptr)
-{
-    if (str == NULL) str = *endptr;
-    char *start = str;
-
-    while (*str != 0)
-    {
-        if (strchr(delimiters, *str) != NULL)
-        {
-            *str = 0;
-            *endptr = str + 1;
-            return start;
-        }
-
-        str++;
-    }
-
-    *endptr = str;
-    return start != str ? start : NULL;
-}
-
-char *strtok(char *str, const char *delimiters)
-{
-    static char *endptr;
-    return strtok_r(str, delimiters, &endptr);
-}
-
-size_t strlen(const char *str)
-{
-    int ret = 0;
-    while (str[ret] != 0) ret++;
-    return ret;
-}
-
-void strrev(char *str)
-{
-    size_t i, j = strlen(str) - 1;
-
-    while (i < j)
-    {
-        int t = str[i];
-        str[i] = str[j];
-        str[j] = t;
-
-        i++;
-        j--;
-    }
-}
-
-void memset(void *ptr, int value, size_t n)
-{
-    uint8_t *ptr_byte = (uint8_t*)ptr;
-    value &= 0xFF;
-    uint32_t tile = value | (value << 8) | (value << 16) | (value << 24);
-
-    if (n >> 2)
-    {
-        asm volatile ("cld\n"
-                      "rep stosl\n"
-                      : "=D"(ptr_byte)
-                      : "D"(ptr_byte), "a"(tile), "c"(n >> 2)
-                      : "cc");
-    }
-
-    switch (n & 3)
-    {
-    case 3:
-        *ptr_byte++ = value;
-    case 2:
-        *ptr_byte++ = value;
-    case 1:
-        *ptr_byte++ = value;
-    }
-}
-
-void memcpy(void *destination, const void *source, size_t n)
-{
-    uint8_t *src_byte = (uint8_t*)source;
-    uint8_t *dest_byte = (uint8_t*)destination;
-    if (!n) return;
-
-    if (n >> 2)
-    {
-        asm volatile ("cld\n"
-                      "rep movsl\n"
-                      : "=D"(dest_byte), "=S"(src_byte)
-                      : "D"(destination), "S"(source), "c"(n >> 2)
-                      : "cc", "memory");
-    }
-
-    switch (n & 3)
-    {
-    case 3:
-        *dest_byte++ = *src_byte++;
-    case 2:
-        *dest_byte++ = *src_byte++;
-    case 1:
-        *dest_byte++ = *src_byte++;
-    }
-}
-
-void memmove(void *destination, const void *source, size_t n)
-{
-    if (!n) return;
-
-    if (destination < source)
-    {
-        uint8_t *src_byte = (uint8_t*)source;
-        uint8_t *dest_byte = (uint8_t*)destination;
-
-        if (n >> 2)
-        {
-            asm volatile ("cld\n"
-                          "rep movsl\n"
-                          : "=D"(dest_byte), "=S"(src_byte)
-                          : "D"(destination), "S"(source), "c"(n >> 2)
-                          : "cc", "memory");
-        }
-
-        switch (n & 3)
-        {
-        case 3:
-            *dest_byte++ = *src_byte++;
-        case 2:
-            *dest_byte++ = *src_byte++;
-        case 1:
-            *dest_byte++ = *src_byte++;
-        }
-    }
-    else if (destination > source)
-    {
-        uint8_t *src_byte = (uint8_t*)source + n;
-        uint8_t *dest_byte = (uint8_t*)destination + n;
-
-        switch (n & 3)
-        {
-        case 3:
-            *--dest_byte = *--src_byte;
-        case 2:
-            *--dest_byte = *--src_byte;
-        case 1:
-            *--dest_byte = *--src_byte;
-        }
-
-        if (n >> 2)
-        {
-            asm volatile ("std\n"
-                          "rep movsl\n"
-                          :
-                          : "D"(dest_byte - 4), "S"(src_byte - 4), "c"(n >> 2)
-                          : "cc", "memory");
-        }
-    }
-}
-
-int memcmp(const void *mem1, const void *mem2, size_t n)
-{
-    uint32_t flags;
-
-    asm volatile ("cld\n"
-                  "repz cmpsb\n"
-                  "pushfl\n"
-                  "popl %0\n"
-                  : "=r"(flags)
-                  : "S"(mem1), "D"(mem2), "c"(n)
-                  : "cc");
-
-    if (flags & 0x40) return 0;
-    else return (flags & 1) ? 1 : -1;
-}
diff --git a/crt/src/wd.c b/crt/src/wd.c
deleted file mode 100644 (file)
index ed0029a..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * wc.c
- *
- * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <monolithium.h>
-
-handle_t __crt_get_raw_handle(int fd);
-
-static char *wd_path = NULL;
-
-char *getcwd(char *buf, size_t size)
-{
-    return strncpy(buf, wd_path, size);
-}
-
-char *getwd(char *buf)
-{
-    return strcpy(buf, wd_path);
-}
-
-char *get_current_dir_name(void)
-{
-    return strdup(wd_path);
-}
-
-int fchdir(int fd)
-{
-    char path[MAX_PATH];
-    handle_t handle = __crt_get_raw_handle(fd);
-
-    sysret_t ret = syscall_query_file(handle, FILE_INFO_NAME, path, sizeof(path));
-
-    if (ret != ERR_SUCCESS)
-    {
-        switch (ret)
-        {
-        case ERR_FORBIDDEN:
-            errno = EACCES;
-
-        default:
-            errno = __crt_translate_error(ret);
-        }
-
-        return -1;
-    }
-
-    if (wd_path)
-    {
-        free(wd_path);
-        wd_path = NULL;
-    }
-
-    wd_path = strdup(path);
-    return 0;
-}
-
-int chdir(const char *path)
-{
-    int fd = open(path, O_RDONLY, 0);
-    if (fd < 0) return -1;
-
-    int ret = fchdir(fd);
-    close(fd);
-    return ret;
-}
index 02b76bc72e47744ad21d5f5c7bb518e3faeff9e0..f14a10f89d66c8259db5a74478e0f55fe308ebf3 100644 (file)
@@ -21,7 +21,7 @@
 DEBUG := yes
 
 # Flags
-CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I include -I ../../kernel/include -I ../../crt/include
+CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I include -I ../../kernel/include -I ../../libraries/mlcrt/include
 ASMFLAGS := -felf
 
 LINK_WITH_LIBGCC := yes
@@ -29,6 +29,6 @@ LINK_WITH_LIBGCC := yes
 # Input and output files
 SOURCES = $(shell find $(SRCDIR) -type f -name \*.c)
 
-OUTPUT_DRIVER := acpica.drv
+OUTPUT_DRIVER := ../bin/acpica.drv
 
 -include ../../common.mk
index 9d2004a1ae4a332fb7a9dcfeaf589aa03dcd7f9f..5b5698e236c41a8d6ef9dcfd298a19ee3404d452 100644 (file)
 DEBUG := yes
 
 # Flags
-CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../crt/include
+CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../libraries/mlcrt/include
 ASMFLAGS := -felf
 
 # Input and output files
 SOURCES = $(wildcard $(SRCDIR)/*.c) $(wildcard $(SRCDIR)/*.asm)
 
-OUTPUT_DRIVER := fatfs.drv
+OUTPUT_DRIVER := ../bin/fatfs.drv
 
 -include ../../common.mk
index 0a68fda030cd52e3dd27e18d03e6af23d8bd3390..7670174b5d4c5acf66e7ce954d93cd720e6b66d2 100644 (file)
 DEBUG := yes
 
 # Flags
-CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../crt/include
+CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../libraries/mlcrt/include
 ASMFLAGS := -felf
 
 # Input and output files
 SOURCES = $(wildcard $(SRCDIR)/*.c) $(wildcard $(SRCDIR)/*.asm)
 
-OUTPUT_DRIVER := floppy.drv
+OUTPUT_DRIVER := ../bin/floppy.drv
 
 -include ../../common.mk
index 2607f9ba489bec63f1336e67310852964bc37919..dc1137b61fa283e5279c03ee105fe6716a8ff62d 100644 (file)
 DEBUG := yes
 
 # Flags
-CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../crt/include
+CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../libraries/mlcrt/include
 ASMFLAGS := -felf
 
 # Input and output files
 SOURCES = $(wildcard $(SRCDIR)/*.c) $(wildcard $(SRCDIR)/*.asm)
 
-OUTPUT_DRIVER := ps2.drv
+OUTPUT_DRIVER := ../bin/ps2.drv
 
 -include ../../common.mk
index 6ff6af271222f1be20cb593086c0b50a5d2ce0d3..dd2c10b98ca525be86473a0911931a4a9e609b3e 100644 (file)
 DEBUG := yes
 
 # Flags
-CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../crt/include
+CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../libraries/mlcrt/include
 ASMFLAGS := -felf
 
 # Input and output files
 SOURCES = $(wildcard $(SRCDIR)/*.c) $(wildcard $(SRCDIR)/*.asm)
 
-OUTPUT_DRIVER := ramfs.drv
+OUTPUT_DRIVER := ../bin/ramfs.drv
 
 -include ../../common.mk
index 480d147a9da6b4e6cd1c3d125ce77142e4e949b3..af132e001e7fb6a0287e6dd3fa76dae137584abd 100644 (file)
 DEBUG := yes
 
 # Flags
-CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../crt/include
+CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../libraries/mlcrt/include
 ASMFLAGS := -felf
 
 # Input and output files
 SOURCES = $(wildcard $(SRCDIR)/*.c) $(wildcard $(SRCDIR)/*.asm)
 
-OUTPUT_DRIVER := serial.drv
+OUTPUT_DRIVER := ../bin/serial.drv
 
 -include ../../common.mk
index 5d3270453c6ff566a2fe13229955b62519a41efe..41ea8c90901ebc2e67be10d8139be29ac578cdd0 100644 (file)
 DEBUG := yes
 
 # Flags
-CFLAGS = -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../crt/include
+CFLAGS = -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../libraries/mlcrt/include
 ASMFLAGS = -felf
 
 # Input and output files
 SOURCES = $(wildcard $(SRCDIR)/*.c) $(wildcard $(SRCDIR)/*.asm)
 
-OUTPUT_DRIVER := speaker.drv
+OUTPUT_DRIVER := ../bin/speaker.drv
 
 -include ../../common.mk
index 3d5b486cc1b6ae6351e713314b7caf90ef1c6ee4..826f70ab77f83d8145bc9564644e2941ad366853 100644 (file)
 DEBUG := yes
 
 # Flags
-CFLAGS = -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../crt/include
+CFLAGS = -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I ../.. -I ../../kernel/include -I ../../libraries/mlcrt/include
 ASMFLAGS = -felf
 
 # Input and output files
 SOURCES = $(wildcard $(SRCDIR)/*.c) $(wildcard $(SRCDIR)/*.asm)
 
-OUTPUT_DRIVER := vesa.drv
+OUTPUT_DRIVER := ../bin/vesa.drv
 
 -include ../../common.mk
index e0593b39b2cbdb5ce00c00e7cbe606c473dff432..0e80f8e14c4cb915c3808d9eeaa4679c52ff9aa3 100644 (file)
@@ -21,9 +21,9 @@
 DEBUG := yes
 
 # Flags
-CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I include -I .. -I ../crt/include
+CFLAGS   := -Wall -Werror -Wno-strict-aliasing -ffreestanding -nostdlib -I include -I .. -I ../libraries/mlcrt/include
 ASMFLAGS := -felf
-LDFLAGS  := -T link.ld -L ../crt -lmlcrt
+LDFLAGS  := -T link.ld -L ../libraries/bin -lmlcrt
 
 LINK_WITH_LIBGCC := yes
 
index bb8f488a30c53b7259834d11bb6a01ba0860bd69..48ec6811a9703a840e66d85face946f0a0531b2d 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <common.h>
 #include <lock.h>
-#include <crt/include/malloc.h>
+#include <libraries/mlcrt/include/malloc.h>
 
 #define SYSTEM_HEAP_START    0x90000000
 #define SYSTEM_HEAP_END      (EVICTABLE_HEAP_START - 1)
diff --git a/libraries/.gitignore b/libraries/.gitignore
new file mode 100644 (file)
index 0000000..ba077a4
--- /dev/null
@@ -0,0 +1 @@
+bin
diff --git a/libraries/Makefile b/libraries/Makefile
new file mode 100644 (file)
index 0000000..79703ca
--- /dev/null
@@ -0,0 +1,26 @@
+#
+# Makefile
+#
+# Copyright (C) 2018 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+all:
+       $(MAKE) -C mlcrt all
+       $(MAKE) -C mlsys all
+
+clean:
+       $(MAKE) -C mlcrt clean
+       $(MAKE) -C mlsys clean
diff --git a/libraries/mlcrt/.gitignore b/libraries/mlcrt/.gitignore
new file mode 100644 (file)
index 0000000..55a8867
--- /dev/null
@@ -0,0 +1,9 @@
+*
+
+# Include the following files:
+!.gitignore
+!Makefile
+!src
+!src/*
+!include
+!include/*
diff --git a/libraries/mlcrt/Makefile b/libraries/mlcrt/Makefile
new file mode 100644 (file)
index 0000000..be94cc2
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# Makefile
+#
+# Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Settings
+DEBUG = yes
+
+# Flags
+CFLAGS   := -Wall -Werror -ffreestanding -nostdlib -fPIC -I include -I ../../sdk
+ASMFLAGS := -felf
+
+# Input and output files
+SOURCES =  $(wildcard $(SRCDIR)/*.c)
+SOURCES += $(wildcard $(SRCDIR)/*.asm)
+
+OUTPUT_STATIC_LIB = ../bin/libmlcrt.a
+
+-include ../../common.mk
diff --git a/libraries/mlcrt/include/ctype.h b/libraries/mlcrt/include/ctype.h
new file mode 100644 (file)
index 0000000..e3c3b1b
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * ctype.h
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CTYPE_H_
+#define _CTYPE_H_
+
+int isprint(int c);
+int isdigit(int c);
+int isxdigit(int c);
+int isspace(int c);
+char tolower(char c);
+char toupper(char c);
+
+#endif
diff --git a/libraries/mlcrt/include/errno.h b/libraries/mlcrt/include/errno.h
new file mode 100644 (file)
index 0000000..c0ffe70
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * errno.h
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ERRNO_H_
+#define _ERRNO_H_
+
+#include <stdint.h>
+
+#define EPERM        1
+#define ENOENT       2
+#define ESRCH        3
+#define EINTR        4
+#define EIO          5
+#define ENXIO        6
+#define E2BIG        7
+#define ENOEXEC      8
+#define EBADF        9
+#define ECHILD       10
+#define EAGAIN       11
+#define ENOMEM       12
+#define EACCES       13
+#define EFAULT       14
+#define EBUSY        16
+#define EEXIST       17
+#define EXDEV        18
+#define ENODEV       19
+#define ENOTDIR      20
+#define EISDIR       21
+#define EINVAL       22
+#define ENFILE       23
+#define EMFILE       24
+#define ENOTTY       25
+#define EFBIG        27
+#define ENOSPC       28
+#define ESPIPE       29
+#define EROFS        30
+#define EMLINK       31
+#define EPIPE        32
+#define EDOM         33
+#define ERANGE       34
+#define EDEADLK      36
+#define EDEADLOCK    EDEADLK
+#define ENAMETOOLONG 38
+#define ENOLCK       39
+#define ENOSYS       40
+#define ENOTEMPTY    41
+#define EILSEQ       42
+#define ECANCELED    43
+#define ETIMEDOUT    44
+#define ETOOSMALL    45
+#define EOVERFLOW    46
+
+extern int errno;
+
+int __crt_translate_error(uint32_t status_code);
+
+#endif
+
diff --git a/libraries/mlcrt/include/fcntl.h b/libraries/mlcrt/include/fcntl.h
new file mode 100644 (file)
index 0000000..5f373a5
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * fcntl.h
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _FCNTL_H_
+#define _FCNTL_H_
+
+#include <unistd.h>
+#include <stdlib.h>
+
+#define FD_CLOEXEC (1 << 0)
+#define FD_PIPE    (1 << 1)
+
+#endif
diff --git a/libraries/mlcrt/include/malloc.h b/libraries/mlcrt/include/malloc.h
new file mode 100644 (file)
index 0000000..b3001e8
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * malloc.h
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _MALLOC_H_
+#define _MALLOC_H_
+
+#define __CRT_HEAP_FLAG_READY    (1 << 0)
+#define __CRT_HEAP_FLAG_ZEROFILL (1 << 1)
+#define __CRT_HEAP_FLAG_BESTFIT  (1 << 2)
+
+enum
+{
+    __CRT_HEAP_CORRUPTED,
+    __CRT_HEAP_DOUBLE_FREE,
+    __CRT_HEAP_BAD_POINTER,
+    __CRT_HEAP_OUT_OF_MEMORY,
+};
+
+typedef struct
+{
+    uint32_t magic;
+    void *base;
+    size_t size;
+    uint32_t flags;
+    uintptr_t next_offset;
+    void *mutex;
+    void (*lock_mutex_proc)(void*);
+    void (*unlock_mutex_proc)(void*);
+    void (*problem)(int);
+} __crt_heap_t;
+
+void *malloc(size_t size);
+void free(void *ptr);
+void *calloc(size_t nmemb, size_t size);
+void *realloc(void *ptr, size_t size);
+
+#endif
diff --git a/libraries/mlcrt/include/setjmp.h b/libraries/mlcrt/include/setjmp.h
new file mode 100644 (file)
index 0000000..0c1dad2
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * setjmp.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SETJMP_H_
+#define _SETJMP_H_
+
+#include <stddef.h>
+#include <monolithium.h>
+
+typedef struct
+{
+    int val;
+    thread_state_t state;
+} jmp_buf[1];
+
+int setjmp(jmp_buf env);
+int longjmp(jmp_buf env, int val);
+
+#endif
diff --git a/libraries/mlcrt/include/stdio.h b/libraries/mlcrt/include/stdio.h
new file mode 100644 (file)
index 0000000..467956d
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * stdio.h
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _STDIO_H_
+#define _STDIO_H_
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+#define EOF -1
+
+#define getc(s) fgetc(s)
+#define getchar() fgetc(stdin)
+#define putc(c, s) fputc(c, s)
+#define putchar(c) fputc(c, stdout)
+
+#define getc_unlocked(s) fgetc_unlocked(s)
+#define getchar_unlocked() fgetc_unlocked(stdin)
+#define putc_unlocked(c, s) fputc_unlocked(c, s)
+#define putchar_unlocked(c) fputc(c, stdout)
+
+struct __crt_file;
+typedef struct __crt_file FILE;
+
+extern FILE *stdin;
+extern FILE *stdout;
+extern FILE *stderr;
+
+int fgetc(FILE *stream);
+int fputc(int c, FILE *stream);
+char *fgets(char *s, int size, FILE *stream);
+int fputs(const char *s, FILE *stream);
+int ungetc(int c, FILE *stream);
+char *gets(char *s);
+int puts(const char *s);
+
+int fgetc_unlocked(FILE *stream);
+int fputc_unlocked(int c, FILE *stream);
+char *fgets_unlocked(char *s, int size, FILE *stream);
+int fputs_unlocked(const char *s, FILE *stream);
+
+FILE *fopen(const char *pathname, const char *mode);
+FILE *fdopen(int fd, const char *mode);
+FILE *fmemopen(void *buf, size_t size, const char *mode);
+int fclose(FILE *stream);
+
+#define BUFSIZ 4096
+#define _IOFBF 0
+#define _IOLBF 1
+#define _IONBF 2
+
+int setvbuf(FILE *stream, char *buf, int mode, size_t size);
+void setbuf(FILE *stream, char *buf);
+void setbuffer(FILE *stream, char *buf, size_t size);
+void setlinebuf(FILE *stream);
+
+int printf(const char *format, ...);
+int fprintf(FILE *stream, const char *format, ...);
+int dprintf(int fd, const char *format, ...);
+int sprintf(char *str, const char *format, ...);
+int snprintf(char *str, size_t size, const char *format, ...);
+int vprintf(const char *format, va_list ap);
+int vfprintf(FILE *stream, const char *format, va_list ap);
+int vdprintf(int fd, const char *format, va_list ap);
+int vsprintf(char *str, const char *format, va_list ap);
+int vsnprintf(char *str, size_t size, const char *format, va_list ap);
+
+
+#endif
diff --git a/libraries/mlcrt/include/stdlib.h b/libraries/mlcrt/include/stdlib.h
new file mode 100644 (file)
index 0000000..f1a9524
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * stdlib.h
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _STDLIB_H_
+#define _STDLIB_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <malloc.h>
+#include <errno.h>
+
+char *itoa(int value, char *str, int base);
+char *ltoa(long value, char *str, int base);
+char *lltoa(long long value, char *str, int base);
+char *uitoa(unsigned int value, char *str, int base);
+char *ultoa(unsigned long value, char *str, int base);
+char *ulltoa(unsigned long long value, char *str, int base);
+int atoi(const char *str);
+long atol(const char *str);
+long long atoll(const char *str);
+long strtol(const char *str, char **endptr, int base);
+long long strtoll(const char *str, char **endptr, int base);
+unsigned long strtoul(const char *str, char **endptr, int base);
+unsigned long long strtoull(const char *str, char **endptr, int base);
+
+void qsort(void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*));
+void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*));
+
+#define ATEXIT_MAX 32
+
+int atexit(void (*function)(void));
+void __attribute__((__noreturn__)) exit(int status);
+
+typedef uint32_t pid_t;
+
+pid_t getpid(void);
+pid_t getppid(void);
+pid_t fork(void);
+
+#endif
diff --git a/libraries/mlcrt/include/string.h b/libraries/mlcrt/include/string.h
new file mode 100644 (file)
index 0000000..9bc9057
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * string.h
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _STRING_H_
+#define _STRING_H_
+
+#include <stddef.h>
+#include <stdint.h>
+#include <limits.h>
+#include <ctype.h>
+
+char *strcpy(char *destination, const char *source);
+char *strncpy(char *destination, const char *source, size_t n);
+int strcmp(const char *str1, const char *str2);
+int stricmp(const char *str1, const char *str2);
+int strncmp(const char *str1, const char *str2, size_t n);
+char *strstr(const char *haystack, const char *needle);
+char *strchr(const char *str, char c);
+char *strrchr(const char *str, char c);
+char *strcat(char *destination, const char *source);
+char *strncat(char *destination, const char *source, size_t n);
+char *strdup(const char *source);
+char *strtok(char *str, const char *delimiters);
+char *strtok_r(char *str, const char *delimiters, char **endptr);
+size_t strlen(const char *str);
+void strrev(char *str);
+void memset(void *ptr, int value, size_t n);
+void memcpy(void *destination, const void *source, size_t n);
+void memmove(void *destination, const void *source, size_t n);
+int memcmp(const void *mem1, const void *mem2, size_t n);
+
+#endif
diff --git a/libraries/mlcrt/include/unistd.h b/libraries/mlcrt/include/unistd.h
new file mode 100644 (file)
index 0000000..a1f1b8a
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * unistd.h
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _UNISTD_H_
+#define _UNISTD_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#define PATH_MAX 16384
+
+#define STDIN_FILENO  0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+
+#define O_RDONLY   0
+#define O_WRONLY   1
+#define O_RDWR     2
+#define O_CREAT    (1 << 6)
+#define O_EXCL     (1 << 7)
+#define O_TRUNC    (1 << 9)
+#define O_APPEND   (1 << 10)
+#define O_NONBLOCK (1 << 11)
+
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+
+typedef uint16_t mode_t;
+
+typedef ptrdiff_t off_t;
+typedef ptrdiff_t ssize_t;
+
+char *getcwd(char *buf, size_t size);
+char *getwd(char *buf);
+char *get_current_dir_name(void);
+int fchdir(int fd);
+int chdir(const char *path);
+
+#ifndef __DONT_DEFINE_OPEN__
+int open(const char *pathname, int flags, ...);
+#endif
+
+int creat(const char *pathname, mode_t mode);
+int close(int fd);
+ssize_t read(int fd, void *buf, size_t count);
+ssize_t write(int fd, const void *buf, size_t count);
+off_t lseek(int fd, off_t offset, int whence);
+
+#endif
diff --git a/libraries/mlcrt/src/algorithm.c b/libraries/mlcrt/src/algorithm.c
new file mode 100644 (file)
index 0000000..c45e1d4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * algorithm.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+
+void qsort(void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*))
+{
+    void *pivot = (void*)((uintptr_t)base + (nmemb / 2) * size);
+    void *temp = __builtin_alloca(size);
+    if (nmemb <= 1) return;
+
+    size_t low = 0;
+    size_t high = nmemb - 1;
+
+    for (;;)
+    {
+        while (compare((void*)((uintptr_t)base + low * size), pivot) < 0) low++;
+        while (compare((void*)((uintptr_t)base + high * size), pivot) > 0) high--;
+        if (low >= high) break;
+
+        memcpy(temp, (void*)((uintptr_t)base + low * size), size);
+        memcpy((void*)((uintptr_t)base + low * size), (void*)((uintptr_t)base + high * size), size);
+        memcpy((void*)((uintptr_t)base + high * size), temp, size);
+    }
+
+    qsort(base, high, size, compare);
+    qsort((void*)((size_t)base + high * size), nmemb - high, size, compare);
+}
+
+void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compare)(const void*, const void*))
+{
+    long low = 0;
+    long high = nmemb - 1;
+
+    while (low <= high)
+    {
+        long mid = low + (high - low) / 2;
+        void *current = (void*)((uintptr_t)base + mid * size);
+        int comp = compare(current, key);
+
+        if (comp < 0) low = mid + 1;
+        else if (comp > 0) high = mid - 1;
+        else return current;
+    }
+
+    return NULL;
+}
diff --git a/libraries/mlcrt/src/crt0.c b/libraries/mlcrt/src/crt0.c
new file mode 100644 (file)
index 0000000..e8a5e7a
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * crt0.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <monolithium.h>
+
+int __crt_initialize_heap(void);
+int __crt_initialize_files(process_params_t *params);
+int main(int argc, char **argv);
+
+void process_startup(process_params_t *params)
+{
+    int argc = 1;
+    char *ptr;
+    int space = 1;
+
+    if (__crt_initialize_heap() < 0) syscall_terminate(INVALID_HANDLE, 255);
+    if (__crt_initialize_files(params) < 0) syscall_terminate(INVALID_HANDLE, 255);
+
+    for (ptr = params->command_line; *ptr; ptr++)
+    {
+        if (space != (isspace(*ptr) != 0))
+        {
+            argc++;
+            space = !space;
+        }
+    }
+
+    char **argv = (char**)__builtin_alloca(argc * sizeof(char*));
+    argc = 0;
+
+    for (ptr = strtok(params->command_line, " \t\r\n\v\f"); ptr != NULL; ptr = strtok(NULL, " \t\r\n\v\f"))
+    {
+        if (*ptr) argv[argc++] = ptr;
+    }
+
+    argv[argc] = NULL;
+
+    int exit_code = main(argc, argv);
+    exit(exit_code);
+}
diff --git a/libraries/mlcrt/src/ctype.c b/libraries/mlcrt/src/ctype.c
new file mode 100644 (file)
index 0000000..797ff58
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * ctype.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+
+int isprint(int c)
+{
+    return c >= 0x20 && c <= 0x7E;
+}
+
+int isdigit(int c)
+{
+    return c >= '0' && c <= '9';
+}
+
+int isxdigit(int c)
+{
+    return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
+}
+
+int isspace(int c)
+{
+    return strchr(" \t\n\v\f\r", c) != NULL;
+}
+
+char tolower(char c)
+{
+    if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
+    return c;
+}
+
+char toupper(char c)
+{
+    if (c >= 'a' && c <= 'z') c -= 'a' - 'A';
+    return c;
+}
diff --git a/libraries/mlcrt/src/errno.c b/libraries/mlcrt/src/errno.c
new file mode 100644 (file)
index 0000000..0c63fc8
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * errno.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+#include <monolithium.h>
+
+int errno = 0;
+
+int __crt_translate_error(uint32_t status_code)
+{
+    switch (status_code)
+    {
+    case ERR_NOTFOUND:
+        return ENOENT;
+
+    case ERR_FORBIDDEN:
+        return EACCES;
+
+    case ERR_INVALID:
+        return EINVAL;
+
+    case ERR_EXISTS:
+        return EEXIST;
+
+    case ERR_NOMEMORY:
+        return ENOMEM;
+
+    case ERR_HARDWARE:
+        return EIO;
+
+    case ERR_BUSY:
+        return EAGAIN;
+
+    case ERR_WRITEPROT:
+        return EROFS;
+
+    case ERR_NOSYSCALL:
+        return ENOSYS;
+
+    case ERR_TIMEOUT:
+        return ETIMEDOUT;
+
+    case ERR_BADPTR:
+        return EFAULT;
+
+    case ERR_CANCELED:
+        return ECANCELED;
+
+    case ERR_ISDIR:
+        return EISDIR;
+
+    case ERR_ISNOTDIR:
+        return ENOTDIR;
+
+    case ERR_DISKFULL:
+        return ENOSPC;
+
+    case ERR_BEYOND:
+        return ENXIO;
+
+    case ERR_SMALLBUF:
+        return ETOOSMALL;
+
+    default:
+        return 0;
+    }
+}
diff --git a/libraries/mlcrt/src/exit.c b/libraries/mlcrt/src/exit.c
new file mode 100644 (file)
index 0000000..0af3d52
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * exit.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <monolithium.h>
+
+static void (*atexit_functions[ATEXIT_MAX])(void);
+static int num_atexit_functions = 0;
+
+int atexit(void (*function)(void))
+{
+    if (num_atexit_functions == ATEXIT_MAX) return -1;
+    atexit_functions[num_atexit_functions++] = function;
+    return 0;
+}
+
+void __attribute__((__noreturn__)) exit(int status)
+{
+    while (num_atexit_functions) atexit_functions[--num_atexit_functions]();
+
+    syscall_terminate(INVALID_HANDLE, status);
+    for (;;);
+}
diff --git a/libraries/mlcrt/src/fcntl.c b/libraries/mlcrt/src/fcntl.c
new file mode 100644 (file)
index 0000000..a8b7109
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * fcntl.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <monolithium.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define __DONT_DEFINE_OPEN__
+#include <fcntl.h>
+
+#define MAX_OPEN_FILES 4096
+
+static handle_t mutex;
+static struct
+{
+    handle_t handle;
+    int flags;
+    int descriptor_flags;
+    off_t position;
+    size_t size;
+} descriptors[MAX_OPEN_FILES];
+
+handle_t __crt_get_raw_handle(int fd)
+{
+    syscall_wait_mutex(mutex, NO_TIMEOUT);
+    handle_t handle = descriptors[fd].handle;
+    syscall_release_mutex(mutex);
+    return handle;
+}
+
+static inline int __crt_open_handle_at(int fd, handle_t handle, int flags)
+{
+    object_type_t type;
+    sysret_t status = syscall_query_handle(handle, HANDLE_INFO_TYPE, &type, sizeof(type));
+
+    if (status != ERR_SUCCESS || (type != OBJECT_FILE && type != OBJECT_PIPE))
+    {
+        errno = EINVAL;
+        return -1;
+    }
+
+    if (type == OBJECT_FILE)
+    {
+        qword_t real_size;
+        status = syscall_query_file(handle, FILE_INFO_SIZE, &real_size, sizeof(real_size));
+        if (status != ERR_SUCCESS)
+        {
+            errno = __crt_translate_error(status);
+            return -1;
+        }
+
+        if (real_size > (qword_t)((size_t)-1))
+        {
+            errno = EFBIG;
+            return -1;
+        }
+
+        descriptors[fd].descriptor_flags = 0;
+        descriptors[fd].size = (size_t)real_size;
+    }
+    else
+    {
+        descriptors[fd].descriptor_flags = FD_PIPE;
+        descriptors[fd].size = 0;
+    }
+
+    descriptors[fd].handle = handle;
+    descriptors[fd].flags = flags;
+    descriptors[fd].position = 0;
+    return fd;
+}
+
+static inline int __crt_open_handle(handle_t handle, int flags)
+{
+    int fd;
+    syscall_wait_mutex(mutex, NO_TIMEOUT);
+
+    for (fd = 0; fd < MAX_OPEN_FILES; fd++)
+    {
+        if (descriptors[fd].handle == INVALID_HANDLE) break;
+    }
+
+    if (fd == MAX_OPEN_FILES)
+    {
+        errno = EMFILE;
+        return -1;
+    }
+
+    fd = __crt_open_handle_at(fd, handle, flags);
+
+    syscall_release_mutex(mutex);
+    return fd;
+}
+
+int open(const char *pathname, int flags, mode_t mode)
+{
+    handle_t handle;
+    char fullpath[PATH_MAX];
+
+    if (*pathname == '/')
+    {
+        if (strlen(pathname) >= PATH_MAX)
+        {
+            errno = ENAMETOOLONG;
+            return -1;
+        }
+
+        strcpy(fullpath, pathname);
+    }
+    else
+    {
+        getwd(fullpath);
+
+        if (strlen(fullpath) + strlen(pathname) >= PATH_MAX)
+        {
+            errno = ENAMETOOLONG;
+            return -1;
+        }
+
+        strcat(fullpath, pathname);
+    }
+
+    if ((flags & 3) == 3)
+    {
+        errno = EINVAL;
+        return -1;
+    }
+
+    dword_t kernel_flags = FILE_MODE_SHARE_READ | FILE_MODE_SHARE_WRITE;
+    dword_t attributes = 0;
+
+    if ((flags & 3) == O_RDONLY) kernel_flags |= FILE_MODE_READ;
+    else if ((flags & 3) == O_RDONLY) kernel_flags |= FILE_MODE_WRITE;
+    else kernel_flags |= FILE_MODE_READ | FILE_MODE_WRITE;
+
+    if (flags & O_CREAT) kernel_flags |= FILE_MODE_CREATE;
+    if (flags & O_TRUNC) kernel_flags |= FILE_MODE_TRUNCATE;
+
+    sysret_t status = syscall_open_file(fullpath, &handle, kernel_flags, attributes);
+    if (status != ERR_SUCCESS)
+    {
+        errno = __crt_translate_error(status);
+        return -1;
+    }
+
+    int fd = __crt_open_handle(handle, flags);
+    if (fd < 0) syscall_close_object(handle);
+    return fd;
+}
+
+int creat(const char *pathname, mode_t mode)
+{
+    return open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
+}
+
+int close(int fd)
+{
+    int ret = -1;
+    syscall_wait_mutex(mutex, NO_TIMEOUT);
+
+    if (fd < 0 || fd >= MAX_OPEN_FILES || descriptors[fd].handle == INVALID_HANDLE)
+    {
+        errno = EBADF;
+        goto cleanup;
+    }
+
+    syscall_close_object(descriptors[fd].handle);
+    descriptors[fd].handle = INVALID_HANDLE;
+    ret = 0;
+
+cleanup:
+    syscall_release_mutex(mutex);
+    return ret;
+}
+
+ssize_t read(int fd, void *buf, size_t count)
+{
+    syscall_wait_mutex(mutex, NO_TIMEOUT);
+
+    size_t ret;
+    sysret_t status = syscall_read_file(descriptors[fd].handle, buf, descriptors[fd].position, count, &ret);
+
+    descriptors[fd].position += (off_t)ret;
+
+    if (status != ERR_SUCCESS && status != ERR_BEYOND)
+    {
+        errno = __crt_translate_error(status);
+        ret = (off_t)-1;
+    }
+
+    syscall_release_mutex(mutex);
+    return (ssize_t)ret;
+}
+
+ssize_t write(int fd, const void *buf, size_t count)
+{
+    syscall_wait_mutex(mutex, NO_TIMEOUT);
+
+    size_t ret;
+    sysret_t status = syscall_write_file(descriptors[fd].handle, buf, descriptors[fd].position, count, &ret);
+
+    descriptors[fd].position += (off_t)ret;
+
+    if (status != ERR_SUCCESS && status != ERR_BEYOND)
+    {
+        errno = __crt_translate_error(status);
+        ret = (off_t)-1;
+    }
+
+    syscall_release_mutex(mutex);
+    return (ssize_t)ret;
+}
+
+off_t lseek(int fd, off_t offset, int whence)
+{
+    if (whence < SEEK_SET || whence > SEEK_END)
+    {
+        errno = EINVAL;
+        return (off_t)-1;
+    }
+
+    syscall_wait_mutex(mutex, NO_TIMEOUT);
+
+    if (fd < 0 || fd >= MAX_OPEN_FILES || descriptors[fd].handle == INVALID_HANDLE)
+    {
+        errno = EBADF;
+        goto cleanup;
+    }
+
+    if (descriptors[fd].descriptor_flags & FD_PIPE)
+    {
+        errno = ESPIPE;
+        goto cleanup;
+    }
+
+    off_t origin = 0;
+    if (whence == SEEK_CUR) origin = descriptors[fd].position;
+    else if (whence == SEEK_END) origin = descriptors[fd].size;
+
+    off_t ret = origin + offset;
+
+    if ((offset > 0 && ret < origin) || (offset < 0 && ret > origin))
+    {
+        errno = EOVERFLOW;
+        goto cleanup;
+    }
+
+    descriptors[fd].position = ret;
+
+cleanup:
+    syscall_release_mutex(mutex);
+    return ret;
+}
+
+int dup(int oldfd)
+{
+    syscall_wait_mutex(mutex, NO_TIMEOUT);
+
+    handle_t duplicate;
+    int flags = descriptors[oldfd].flags;
+    sysret_t status = syscall_duplicate_handle(INVALID_HANDLE, descriptors[oldfd].handle, INVALID_HANDLE, &duplicate);
+    syscall_release_mutex(mutex);
+
+    if (status != ERR_SUCCESS)
+    {
+        errno = __crt_translate_error(status);
+        return -1;
+    }
+
+    return __crt_open_handle(duplicate, flags);
+}
+
+int dup2(int oldfd, int newfd)
+{
+    int fd = -1;
+    syscall_wait_mutex(mutex, NO_TIMEOUT);
+
+    handle_t duplicate;
+    sysret_t status = syscall_duplicate_handle(INVALID_HANDLE, descriptors[oldfd].handle, INVALID_HANDLE, &duplicate);
+
+    if (status != ERR_SUCCESS)
+    {
+        errno = __crt_translate_error(status);
+        goto cleanup;
+    }
+
+    fd = __crt_open_handle_at(newfd, duplicate, descriptors[oldfd].flags);
+
+cleanup:
+    syscall_release_mutex(mutex);
+    return fd;
+}
+
+int __crt_initialize_files(process_params_t *params)
+{
+    sysret_t ret = syscall_create_mutex(NULL, TRUE, &mutex);
+    if (ret != ERR_SUCCESS) return -1;
+
+    int i;
+    for (i = 0; i < MAX_OPEN_FILES; i++) descriptors[i].handle = INVALID_HANDLE;
+
+    if (params->standard_input != INVALID_HANDLE) __crt_open_handle_at(STDIN_FILENO, params->standard_input, O_RDONLY);
+    if (params->standard_input != INVALID_HANDLE) __crt_open_handle_at(STDOUT_FILENO, params->standard_output, O_WRONLY);
+    if (params->standard_input != INVALID_HANDLE) __crt_open_handle_at(STDERR_FILENO, params->standard_error, O_WRONLY);
+    return 0;
+}
diff --git a/libraries/mlcrt/src/io.c b/libraries/mlcrt/src/io.c
new file mode 100644 (file)
index 0000000..2b46167
--- /dev/null
@@ -0,0 +1,508 @@
+/*
+ * io.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include "io_priv.h"
+
+static list_entry_t open_files;
+
+FILE *stdin  = NULL;
+FILE *stdout = NULL;
+FILE *stderr = NULL;
+
+int fileno_unlocked(FILE *stream)
+{
+    if (stream->fd == -1) errno = EBADF;
+    return stream->fd;
+}
+
+int fileno(FILE *stream)
+{
+    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
+    int ret = fileno_unlocked(stream);
+    syscall_release_mutex(stream->mutex);
+    return ret;
+}
+
+static int __crt_fflush_stream(FILE *stream)
+{
+    if (!stream->buffer) return EOF;
+
+    if (!(stream->flags & FILE_BUFFER_DIR))
+    {
+        stream->buffer_start = stream->buffer_end = 0;
+        stream->flags &= ~FILE_BUFFER_FULL;
+        return 0;
+    }
+
+    if (stream->fd == -1) return 0;
+
+    if (stream->buffer_start < stream->buffer_end)
+    {
+        ssize_t written = write(stream->fd, &stream->buffer[stream->buffer_start], stream->buffer_end - stream->buffer_start);
+        if (written < 0) return EOF;
+
+        stream->buffer_start += written;
+        stream->buffer_start %= stream->buffer_size;
+        if (written) stream->flags &= ~FILE_BUFFER_FULL;
+    }
+    else
+    {
+        if (stream->buffer_start < stream->buffer_size)
+        {
+            ssize_t written = write(stream->fd, &stream->buffer[stream->buffer_start], stream->buffer_size - stream->buffer_start);
+            if (written < 0) return EOF;
+
+            stream->buffer_start += written;
+            stream->buffer_start %= stream->buffer_size;
+            if (written) stream->flags &= ~FILE_BUFFER_FULL;
+        }
+
+        if (stream->buffer_end)
+        {
+            ssize_t written = write(stream->fd, stream->buffer, stream->buffer_end);
+            if (written < 0) return EOF;
+
+            stream->buffer_start += written;
+            stream->buffer_start %= stream->buffer_size;
+            if (written) stream->flags &= ~FILE_BUFFER_FULL;
+        }
+    }
+
+    return 0;
+}
+
+int fflush_unlocked(FILE *stream)
+{
+    if (stream) return __crt_fflush_stream(stream);
+
+    list_entry_t *entry;
+    int result = 0;
+
+    for (entry = open_files.next; entry != &open_files; entry = entry->next)
+    {
+        if (__crt_fflush_stream(CONTAINER_OF(entry, struct __crt_file, link)) == EOF)
+        {
+            result = EOF;
+        }
+    }
+
+    return result;
+}
+
+int fflush(FILE *stream)
+{
+    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
+    int ret = fflush_unlocked(stream);
+    syscall_release_mutex(stream->mutex);
+    return ret;
+}
+
+int setvbuf(FILE *stream, char *buf, int mode, size_t size)
+{
+    int ret = EOF;
+    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
+
+    switch (mode)
+    {
+    case _IONBF:
+        if (fflush_unlocked(stream) == 0)
+        {
+            stream->buffer = NULL;
+            stream->buffer_size = 0;
+            ret = 0;
+        }
+        break;
+
+    case _IOLBF:
+        if (!buf || fflush_unlocked(stream) == 0)
+        {
+            if (buf)
+            {
+                stream->buffer = buf;
+                stream->buffer_size = size;
+            }
+
+            stream->flags |= FILE_BUFFER_LINE;
+            ret = 0;
+        }
+        break;
+
+    case _IOFBF:
+        if (!buf || fflush_unlocked(stream) == 0)
+        {
+            if (buf)
+            {
+                stream->buffer = buf;
+                stream->buffer_size = size;
+            }
+
+            stream->flags &= ~FILE_BUFFER_LINE;
+            ret = 0;
+        }
+        break;
+    }
+
+    syscall_release_mutex(stream->mutex);
+    return ret;
+}
+
+void setbuf(FILE *stream, char *buf)
+{
+    setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
+}
+
+void setbuffer(FILE *stream, char *buf, size_t size)
+{
+    setvbuf(stream, buf, buf ? _IOFBF : _IONBF, size);
+}
+
+void setlinebuf(FILE *stream)
+{
+    setvbuf(stream, NULL, _IOLBF, 0);
+}
+
+inline int fgetc_unlocked(FILE *stream)
+{
+    char c;
+
+    if (!(stream->flags & FILE_READ))
+    {
+        errno = EPERM;
+        return EOF;
+    }
+
+    if (stream->buffer)
+    {
+        if (stream->flags & FILE_BUFFER_DIR)
+        {
+            fflush_unlocked(stream);
+            stream->flags &= ~FILE_BUFFER_DIR;
+        }
+
+        if (stream->buffer_start == stream->buffer_end && !(stream->flags & FILE_BUFFER_FULL))
+        {
+            if (stream->fd == -1) return EOF;
+
+            if (stream->buffer_end < stream->buffer_size)
+            {
+                ssize_t amount = read(stream->fd, &stream->buffer[stream->buffer_end], stream->buffer_size - stream->buffer_end);
+                if (amount < 0) return EOF;
+
+                stream->buffer_end += amount;
+                stream->buffer_end %= stream->buffer_size;
+                if (amount && (stream->buffer_start == stream->buffer_end)) stream->flags |= FILE_BUFFER_FULL;
+            }
+
+            if (stream->buffer_end < stream->buffer_start)
+            {
+                ssize_t amount = read(stream->fd, &stream->buffer[stream->buffer_end], stream->buffer_start - stream->buffer_end);
+                if (amount < 0) return EOF;
+
+                stream->buffer_end += amount;
+                stream->buffer_end %= stream->buffer_size;
+                if (amount && (stream->buffer_start == stream->buffer_end)) stream->flags |= FILE_BUFFER_FULL;
+            }
+        }
+
+        c = stream->buffer[stream->buffer_start];
+        stream->buffer_start++;
+        stream->buffer_end %= stream->buffer_size;
+
+        stream->flags &= ~FILE_BUFFER_FULL;
+    }
+    else
+    {
+        if (read(stream->fd, &c, 1) != 1) c = EOF;
+    }
+
+    return (int)((unsigned int)c);
+}
+
+int fgetc(FILE *stream)
+{
+    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
+    int ret = fgetc_unlocked(stream);
+    syscall_release_mutex(stream->mutex);
+    return ret;
+}
+
+inline int fputc_unlocked(int c, FILE *stream)
+{
+    if (!(stream->flags & FILE_WRITE))
+    {
+        errno = EPERM;
+        return EOF;
+    }
+
+    if (stream->buffer)
+    {
+        if (!(stream->flags & FILE_BUFFER_DIR))
+        {
+            fflush_unlocked(stream);
+            stream->flags |= FILE_BUFFER_DIR;
+        }
+
+        if (stream->flags & FILE_BUFFER_FULL)
+        {
+            errno = ENOSPC;
+            return EOF;
+        }
+
+        stream->buffer[stream->buffer_end] = (uint8_t)c;
+        stream->buffer_end++;
+        stream->buffer_end %= stream->buffer_size;
+
+        if (stream->buffer_start == stream->buffer_end)
+        {
+            stream->flags |= FILE_BUFFER_FULL;
+        }
+
+        if (stream->fd != -1 && ((stream->flags & FILE_BUFFER_FULL) || ((stream->flags & FILE_BUFFER_LINE) && (char)c == '\n')))
+        {
+            fflush_unlocked(stream);
+        }
+    }
+    else
+    {
+        if (write(stream->fd, &c, 1) != 1) return EOF;
+    }
+
+    return 0;
+}
+
+int fputc(int c, FILE *stream)
+{
+    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
+    int ret = fputc_unlocked(c, stream);
+    syscall_release_mutex(stream->mutex);
+    return ret;
+}
+
+char *fgets_unlocked(char *s, int size, FILE *stream)
+{
+    int c;
+    char *ptr = s;
+
+    while (size-- > 0 && (c = fgetc_unlocked(stream)) != EOF)
+    {
+        *ptr++ = (char)c;
+        if (c == '\n') break;
+    }
+
+    return (s != ptr) ? s : NULL;
+}
+
+char *fgets(char *s, int size, FILE *stream)
+{
+    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
+    char *ret = fgets_unlocked(s, size, stream);
+    syscall_release_mutex(stream->mutex);
+    return ret;
+}
+
+int fputs_unlocked(const char *s, FILE *stream)
+{
+    const char *ptr = s;
+    while (*ptr) if (fputc_unlocked(*ptr++, stream) == EOF) return EOF;
+    return 0;
+}
+
+int fputs(const char *s, FILE *stream)
+{
+    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
+    int ret = fputs_unlocked(s, stream);
+    syscall_release_mutex(stream->mutex);
+    return ret;
+}
+
+int ungetc(int c, FILE *stream)
+{
+    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
+
+    if (stream->flags & FILE_BUFFER_DIR)
+    {
+        fflush_unlocked(stream);
+        stream->flags &= ~FILE_BUFFER_DIR;
+    }
+
+    if (stream->buffer_start == 0) stream->buffer_start = stream->buffer_size;
+    stream->buffer_start--;
+
+    stream->buffer[stream->buffer_start] = (uint8_t)c;
+
+    syscall_release_mutex(stream->mutex);
+    return c;
+}
+
+char *gets(char *s)
+{
+    char *ptr = s;
+    int c;
+    while ((c = getchar()) != EOF) *ptr++ = (char)c;
+    return ptr != s ? s : NULL;
+}
+
+int puts(const char *s)
+{
+    if (fputs(s, stdout) == EOF) return EOF;
+    if (fputc('\n', stdout) == EOF) return EOF;
+    return 0;
+}
+
+FILE *fdopen(int fd, const char *mode)
+{
+    FILE *stream = (FILE*)malloc(sizeof(FILE) + BUFSIZ);
+
+    if (stream == NULL)
+    {
+        errno = ENOMEM;
+        return NULL;
+    }
+
+    sysret_t status = syscall_create_mutex(NULL, TRUE, &stream->mutex);
+    if (status != ERR_SUCCESS)
+    {
+        free(stream);
+        errno = __crt_translate_error(status);
+        return NULL;
+    }
+
+    stream->flags = 0;
+
+    const char *ptr;
+    for (ptr = mode; *ptr; ptr++)
+    {
+        switch (*ptr)
+        {
+        case 'r':
+            stream->flags |= FILE_READ;
+            break;
+        case 'w':
+            stream->flags |= FILE_WRITE;
+            break;
+        case 'a':
+            stream->flags |= FILE_APPEND;
+            break;
+        case '+':
+            stream->flags |= FILE_READ | FILE_WRITE;
+            break;
+        }
+    }
+
+    stream->fd = fd;
+
+    char *buffer = (char*)((uintptr_t)stream + sizeof(FILE));
+    setbuf(stream, buffer);
+    return stream;
+}
+
+FILE *fmemopen(void *buf, size_t size, const char *mode)
+{
+    FILE *stream = (FILE*)malloc(sizeof(FILE));
+    if (stream == NULL)
+    {
+        errno = ENOMEM;
+        return NULL;
+    }
+
+    sysret_t status = syscall_create_mutex(NULL, TRUE, &stream->mutex);
+    if (status != ERR_SUCCESS)
+    {
+        free(stream);
+        errno = __crt_translate_error(status);
+        return NULL;
+    }
+
+    stream->flags = 0;
+
+    const char *ptr;
+    for (ptr = mode; *ptr; ptr++)
+    {
+        switch (*ptr)
+        {
+        case 'r':
+            stream->flags |= FILE_READ;
+            break;
+        case 'w':
+            stream->flags |= FILE_WRITE;
+            break;
+        case 'a':
+            stream->flags |= FILE_APPEND;
+            break;
+        case '+':
+            stream->flags |= FILE_READ | FILE_WRITE;
+            break;
+        }
+    }
+
+    stream->fd = -1;
+    stream->buffer = buf;
+    stream->buffer_size = size;
+    stream->buffer_start = stream->buffer_end = 0;
+
+    list_append(&open_files, &stream->link);
+    return stream;
+}
+
+FILE *fopen(const char *pathname, const char *mode)
+{
+    int open_flags = 0;
+
+    const char *ptr;
+    for (ptr = mode; *ptr; ptr++)
+    {
+        switch (*ptr)
+        {
+        case 'r':
+            open_flags = (open_flags & ~3) | O_RDONLY;
+            break;
+        case 'w':
+            open_flags = (open_flags & ~3) | O_WRONLY;
+            break;
+        case 'a':
+            open_flags |= O_APPEND;
+            break;
+        case '+':
+            open_flags = (open_flags & ~3) | O_RDWR;
+            break;
+        }
+    }
+
+    int fd = open(pathname, open_flags);
+    if (fd < 0) return NULL;
+
+    FILE *stream = fdopen(fd, mode);
+    if (!stream) close(fd);
+    return NULL;
+}
+
+int fclose(FILE *stream)
+{
+    fflush(stream);
+    list_remove(&stream->link);
+    syscall_wait_mutex(stream->mutex, NO_TIMEOUT);
+
+    if (stream->fd) close(stream->fd);
+
+    syscall_close_object(stream->mutex);
+    free(stream);
+    return 0;
+}
diff --git a/libraries/mlcrt/src/io_priv.h b/libraries/mlcrt/src/io_priv.h
new file mode 100644 (file)
index 0000000..c5258da
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * io_priv.h
+ *
+ * Copyright (C) 2018 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _IO_PRIV_H_
+#define _IO_PRIV_H_
+
+#include <monolithium.h>
+
+#define FILE_READ        (1 << 0)
+#define FILE_WRITE       (1 << 1)
+#define FILE_APPEND      (1 << 2)
+#define FILE_BUFFER_LINE (1 << 3)
+#define FILE_BUFFER_DIR  (1 << 4)
+#define FILE_BUFFER_FULL (1 << 31)
+
+struct __crt_file
+{
+    list_entry_t link;
+    handle_t mutex;
+    uint32_t flags;
+
+    int fd;
+
+    char *buffer;
+    size_t buffer_size;
+    size_t buffer_start, buffer_end;
+};
+
+#endif
diff --git a/libraries/mlcrt/src/malloc.c b/libraries/mlcrt/src/malloc.c
new file mode 100644 (file)
index 0000000..c044c8f
--- /dev/null
@@ -0,0 +1,395 @@
+/*
+ * heap.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <monolithium.h>
+
+#define ALLOCATED (1 << 0)
+
+typedef struct
+{
+    uint32_t magic;
+    uint32_t flags;
+    size_t size;
+} heap_header_t;
+
+__crt_heap_t *__crt_default_heap = NULL;
+
+static void __crt_heap_coalesce(__crt_heap_t *heap)
+{
+    heap_header_t *ptr = (heap_header_t*)heap->base;
+    heap_header_t *previous = NULL;
+
+    while ((uintptr_t)ptr >= (uintptr_t)heap->base && (uintptr_t)ptr < (uintptr_t)heap->base + heap->size)
+    {
+        heap_header_t *next = (heap_header_t*)((uintptr_t)ptr + sizeof(heap_header_t) + ptr->size);
+
+        if (previous && !(previous->flags & ALLOCATED) && !(ptr->flags & ALLOCATED))
+        {
+            if (((uintptr_t)ptr - (uintptr_t)heap->base) == heap->next_offset)
+            {
+                heap->next_offset = (uintptr_t)previous - (uintptr_t)heap->base;
+            }
+
+            previous->size += ptr->size + sizeof(heap_header_t);
+        }
+        else
+        {
+            previous = ptr;
+        }
+
+        ptr = next;
+    }
+}
+
+void *__crt_heap_realloc(__crt_heap_t *heap, void *ptr, size_t alignment, size_t size)
+{
+    if (!alignment || (alignment & (alignment - 1))) return NULL;
+
+    heap->lock_mutex_proc(heap->mutex);
+
+    if (!(heap->flags & __CRT_HEAP_FLAG_READY))
+    {
+        heap_header_t *header = (heap_header_t*)heap->base;
+        header->magic = heap->magic;
+        header->flags = 0;
+        header->size = heap->size - sizeof(heap_header_t);
+
+        heap->flags |= __CRT_HEAP_FLAG_READY;
+    }
+
+    if (!size)
+    {
+        if (ptr)
+        {
+            heap_header_t *header = (heap_header_t*)((uintptr_t)ptr - sizeof(heap_header_t));
+
+            if (header->flags & ALLOCATED)
+            {
+                header->flags &= ~ALLOCATED;
+                __crt_heap_coalesce(heap);
+            }
+            else
+            {
+                heap->problem(__CRT_HEAP_DOUBLE_FREE);
+            }
+        }
+
+        heap->unlock_mutex_proc(heap->mutex);
+        return NULL;
+    }
+
+    heap_header_t *source_block = NULL;
+
+    if (ptr)
+    {
+        heap_header_t *header = (heap_header_t*)((uintptr_t)ptr - sizeof(heap_header_t));
+
+        if (!(header->flags & ALLOCATED) || header->magic != heap->magic)
+        {
+            heap->problem(__CRT_HEAP_BAD_POINTER);
+            heap->unlock_mutex_proc(heap->mutex);
+            return NULL;
+        }
+
+        if (size > header->size)
+        {
+             heap_header_t *next = (heap_header_t*)((uintptr_t)ptr + header->size);
+
+             if (!(next->flags & ALLOCATED) && (header->size + next->size + sizeof(heap_header_t)) >= size)
+             {
+                 if (((uintptr_t)next - (uintptr_t)heap->base) == heap->next_offset)
+                 {
+                     heap->next_offset = (uintptr_t)header - (uintptr_t)heap->base;
+                 }
+
+                 header->size += next->size + sizeof(heap_header_t);
+                 if (heap->flags & __CRT_HEAP_FLAG_ZEROFILL) memset(next, 0, size - header->size - size);
+             }
+             else
+             {
+                 source_block = header;
+             }
+        }
+
+        if (size < (header->size - sizeof(heap_header_t)))
+        {
+            heap_header_t *new_block = (heap_header_t*)((uintptr_t)ptr + size);
+            new_block->magic = heap->magic;
+            new_block->flags = 0;
+            new_block->size = header->size - size - sizeof(heap_header_t);
+            header->size = size;
+            __crt_heap_coalesce(heap);
+        }
+
+        if (!source_block)
+        {
+            heap->unlock_mutex_proc(heap->mutex);
+            return ptr;
+        }
+    }
+
+    heap_header_t *hole = NULL;
+
+    if (heap->flags & __CRT_HEAP_FLAG_BESTFIT)
+    {
+        heap_header_t *current = (heap_header_t*)heap->base;
+        size_t minimum_size;
+
+        while ((uintptr_t)current < (uintptr_t)heap->base + heap->size)
+        {
+            if (current->magic != heap->magic)
+            {
+                heap->problem(__CRT_HEAP_CORRUPTED);
+                heap->unlock_mutex_proc(heap->mutex);
+                return NULL;
+            }
+
+            if (!(current->flags & ALLOCATED))
+            {
+                uintptr_t current_start = (uintptr_t)current + sizeof(heap_header_t);
+                uintptr_t aligned_start = (current_start + alignment - 1) & ~(alignment - 1);
+                size_t padding = aligned_start - current_start;
+
+                if (current->size > padding)
+                {
+                    size_t adjusted_size = current->size - padding;
+
+                    if (adjusted_size >= size && (!hole || adjusted_size < minimum_size))
+                    {
+                        hole = current;
+                        minimum_size = adjusted_size;
+                    }
+                }
+            }
+
+            heap_header_t *next = (heap_header_t*)((uintptr_t)current + sizeof(heap_header_t) + current->size);
+
+            if ((uintptr_t)next <= (uintptr_t)current)
+            {
+                heap->problem(__CRT_HEAP_CORRUPTED);
+                heap->unlock_mutex_proc(heap->mutex);
+                return NULL;
+            }
+
+            current = next;
+        }
+    }
+    else
+    {
+        uintptr_t offset = heap->next_offset;
+        int cycles = 0;
+
+        do
+        {
+            heap_header_t *current = (heap_header_t*)(heap->base + offset);
+
+            if (current->magic != heap->magic)
+            {
+                heap->problem(__CRT_HEAP_CORRUPTED);
+                heap->unlock_mutex_proc(heap->mutex);
+                return NULL;
+            }
+
+            if (!(current->flags & ALLOCATED))
+            {
+                uintptr_t current_start = (uintptr_t)current + sizeof(heap_header_t);
+                uintptr_t aligned_start = (current_start + alignment - 1) & ~(alignment - 1);
+                size_t padding = aligned_start - current_start;
+
+                if (current->size >= padding && (current->size - padding) >= size)
+                {
+                    hole = current;
+                    break;
+                }
+            }
+
+            offset += sizeof(heap_header_t) + current->size;
+            if (offset > heap->size)
+            {
+                offset = 0;
+                if (++cycles > 1)
+                {
+                    heap->problem(__CRT_HEAP_CORRUPTED);
+                    heap->unlock_mutex_proc(heap->mutex);
+                    return NULL;
+                }
+            }
+        }
+        while (offset != heap->next_offset);
+
+        heap->next_offset = offset;
+    }
+
+    if (!hole)
+    {
+        heap->problem(__CRT_HEAP_OUT_OF_MEMORY);
+        heap->unlock_mutex_proc(heap->mutex);
+        return NULL;
+    }
+
+    int coalesce = 0;
+    uintptr_t start_address = (uintptr_t)hole + sizeof(heap_header_t);
+    uintptr_t aligned_start = (start_address + alignment - 1) & ~(alignment - 1);
+    size_t padding = aligned_start - start_address;
+
+    if (padding > sizeof(heap_header_t))
+    {
+        heap_header_t *new_block = (heap_header_t*)(aligned_start - sizeof(heap_header_t));
+        new_block->magic = heap->magic;
+        new_block->flags = 0;
+        new_block->size = hole->size - padding;
+        hole->size -= padding + sizeof(heap_header_t);
+
+        hole = new_block;
+        coalesce = 1;
+    }
+    else if (padding)
+    {
+        heap_header_t *previous = (heap_header_t*)heap->base;
+
+        while ((uintptr_t)previous < (uintptr_t)heap->base + heap->size)
+        {
+            heap_header_t *next = (heap_header_t*)((uintptr_t)previous + sizeof(heap_header_t) + previous->size);
+            if (next == hole) break;
+
+            if ((uintptr_t)next <= (uintptr_t)previous)
+            {
+                heap->problem(__CRT_HEAP_CORRUPTED);
+                heap->unlock_mutex_proc(heap->mutex);
+                return NULL;
+            }
+
+            previous = next;
+        }
+
+        if ((uintptr_t)previous < (uintptr_t)heap->base
+            || (uintptr_t)previous >= (uintptr_t)heap->base + heap->size
+            || previous->magic != heap->magic)
+        {
+            heap->problem(__CRT_HEAP_CORRUPTED);
+            heap->unlock_mutex_proc(heap->mutex);
+            return NULL;
+        }
+
+        previous->size += padding;
+
+        heap_header_t *new_block = (heap_header_t*)(aligned_start - sizeof(heap_header_t));
+        memmove(new_block, hole, sizeof(heap_header_t));
+        if (heap->next_offset == (uintptr_t)hole - (uintptr_t)heap->base) heap->next_offset += padding;
+
+        hole = new_block;
+        hole->size -= padding;
+    }
+
+    hole->flags |= ALLOCATED;
+
+    if (hole->size > sizeof(heap_header_t) && size < (hole->size - sizeof(heap_header_t)))
+    {
+        heap_header_t *new_block = (heap_header_t*)((uintptr_t)hole + size + sizeof(heap_header_t));
+        new_block->magic = heap->magic;
+        new_block->flags = 0;
+        new_block->size = hole->size - size - sizeof(heap_header_t);
+        hole->size = size;
+        coalesce = 1;
+    }
+
+    void *destination = (void*)((uintptr_t)hole + sizeof(heap_header_t));
+    if (heap->flags & __CRT_HEAP_FLAG_ZEROFILL) memset(destination, 0, size);
+
+    if (source_block)
+    {
+        void *source = (void*)((uintptr_t)source_block + sizeof(heap_header_t));
+        memcpy(destination, source, source_block->size);
+        source_block->flags &= ~ALLOCATED;
+        coalesce = 1;
+    }
+
+    if (coalesce) __crt_heap_coalesce(heap);
+    heap->unlock_mutex_proc(heap->mutex);
+    return destination;
+}
+
+void *aligned_alloc(size_t alignment, size_t size)
+{
+    return __crt_heap_realloc(__crt_default_heap, NULL, alignment, size);
+}
+
+void *realloc(void *ptr, size_t size)
+{
+    return __crt_heap_realloc(__crt_default_heap, ptr, sizeof(long), size);
+}
+
+void *malloc(size_t size)
+{
+    return __crt_heap_realloc(__crt_default_heap, NULL, sizeof(long), size);
+}
+
+void free(void *ptr)
+{
+    __crt_heap_realloc(__crt_default_heap, ptr, sizeof(long), 0);
+}
+
+void *calloc(size_t nmemb, size_t size)
+{
+    void *ptr = malloc(nmemb * size);
+    if (!ptr) return NULL;
+
+    memset(ptr, 0, nmemb * size);
+    return ptr;
+}
+
+static void __crt_heap_lock(void *mutex)
+{
+    syscall_wait_mutex((handle_t)mutex, NO_TIMEOUT);
+}
+
+static void __crt_heap_unlock(void *mutex)
+{
+    syscall_release_mutex((handle_t)mutex);
+}
+
+static void __crt_heap_problem(int problem)
+{
+    // TODO
+}
+
+int __crt_initialize_heap(void)
+{
+    static __crt_heap_t heap;
+
+    heap.magic             = 0x70616548;
+    heap.base              = NULL;
+    heap.size              = 0x10000000;
+    heap.flags             = 0;
+    heap.next_offset       = 0;
+    heap.lock_mutex_proc   = __crt_heap_lock;
+    heap.unlock_mutex_proc = __crt_heap_unlock;
+    heap.problem           = __crt_heap_problem;
+
+    sysret_t status = syscall_create_mutex(NULL, TRUE, (handle_t*)&heap.mutex);
+    if (status != ERR_SUCCESS) return -1;
+
+    status = syscall_alloc_memory(INVALID_HANDLE, &heap.base, heap.size, MEMORY_BLOCK_ACCESSIBLE | MEMORY_BLOCK_WRITABLE);
+    if (status != ERR_SUCCESS) return -1;
+
+    __crt_default_heap = &heap;
+    return 0;
+}
diff --git a/libraries/mlcrt/src/numconv.c b/libraries/mlcrt/src/numconv.c
new file mode 100644 (file)
index 0000000..2b425e1
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * numconv.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#define DEFINE_XTOA(t, p, s)                                            \
+    char *p##toa(t value, char *str, int base)                          \
+    {                                                                   \
+        char *ptr = str;                                                \
+        if (base < 2 || base > 36) return NULL;                         \
+                                                                        \
+        if (value == 0##s)                                              \
+        {                                                               \
+            *ptr++ = '0';                                               \
+            *ptr++ = '\0';                                              \
+            return str;                                                 \
+        }                                                               \
+                                                                        \
+        if (value < 0##s)                                               \
+        {                                                               \
+            *ptr++ = '-';                                               \
+            value = -value;                                             \
+        }                                                               \
+                                                                        \
+        t temp;                                                         \
+        for (temp = value; temp > 0##s; temp /= (t)base) ptr++;         \
+        *ptr = '\0';                                                    \
+                                                                        \
+        while (value > 0##s)                                            \
+        {                                                               \
+            *--ptr = all_digits[value % (t)base];                       \
+            value /= (t)base;                                           \
+        }                                                               \
+                                                                        \
+        return str;                                                     \
+    }                                                                   \
+                                                                        \
+    char *u##p##toa(unsigned t value, char *str, int base)              \
+    {                                                                   \
+        char *ptr = str;                                                \
+        if (base < 2 || base > 36) return NULL;                         \
+                                                                        \
+        if (value == 0U##s)                                             \
+        {                                                               \
+            *ptr++ = '0';                                               \
+            *ptr++ = '\0';                                              \
+            return str;                                                 \
+        }                                                               \
+                                                                        \
+        unsigned t temp;                                                \
+        for (temp = value; temp > 0U##s; temp /= (unsigned t)base) ptr++; \
+        *ptr = '\0';                                                    \
+                                                                        \
+        while (value > 0U##s)                                           \
+        {                                                               \
+            *--ptr = all_digits[value % (unsigned t)base];              \
+            value /= (unsigned t)base;                                  \
+        }                                                               \
+                                                                        \
+        return str;                                                     \
+    }
+
+#define DEFINE_ATOX(t, n, p, s)                                         \
+    t ato##p(const char *str)                                           \
+    {                                                                   \
+        return strto##p(str, NULL, 10);                                 \
+    }                                                                   \
+                                                                        \
+    t strto##p(const char *str, char **endptr, int base)                \
+    {                                                                   \
+        const char *ptr;                                                \
+        t result = 0##s;                                                \
+        int overflow = 0, negative = 0;                                 \
+                                                                        \
+        if (base < 2 || base > 36) return 0;                            \
+                                                                        \
+        switch (*str)                                                   \
+        {                                                               \
+        case '-':                                                       \
+            negative = 1;                                               \
+        case '+':                                                       \
+            str++;                                                      \
+            break;                                                      \
+        }                                                               \
+                                                                        \
+        for (ptr = str; *ptr; ptr++)                                    \
+        {                                                               \
+            char *digit_ptr = strchr(all_digits, toupper(*ptr));        \
+            if (digit_ptr == NULL) break;                               \
+                                                                        \
+            t digit = (t)(digit_ptr - all_digits);                      \
+            if (digit >= base) break;                                   \
+                                                                        \
+            t new_result = result * (t)base + digit;                    \
+            if (new_result < result) overflow = 1;                      \
+            result = new_result;                                        \
+        }                                                               \
+                                                                        \
+        if (overflow)                                                   \
+        {                                                               \
+            errno = ERANGE;                                             \
+            return negative ? n##_MIN : n##_MAX;                        \
+        }                                                               \
+                                                                        \
+        if (negative) result = -result;                                 \
+        if (endptr) *endptr = (char*)ptr;                               \
+        return result;                                                  \
+    }                                                                   \
+                                                                        \
+    unsigned t strtou##p(const char *str, char **endptr, int base)      \
+    {                                                                   \
+        const char *ptr;                                                \
+        unsigned t result = 0UL;                                        \
+        int overflow = 0;                                               \
+                                                                        \
+        if (base < 2 || base > 36) return 0;                            \
+                                                                        \
+        for (ptr = str; *ptr; ptr++)                                    \
+        {                                                               \
+            char *digit_ptr = strchr(all_digits, toupper(*ptr));        \
+            if (digit_ptr == NULL) break;                               \
+                                                                        \
+            unsigned t digit = (unsigned t)(digit_ptr - all_digits);    \
+            if (digit >= base) break;                                   \
+                                                                        \
+            unsigned t new_result = result * (unsigned t)base + digit;  \
+            if (new_result < result) overflow = 1;                      \
+            result = new_result;                                        \
+        }                                                               \
+                                                                        \
+        if (overflow)                                                   \
+        {                                                               \
+            errno = ERANGE;                                             \
+            return U##n##_MAX;                                          \
+        }                                                               \
+                                                                        \
+        if (endptr) *endptr = (char*)ptr;                               \
+        return result;                                                  \
+    }
+
+static const char all_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+DEFINE_XTOA(int, i, );
+DEFINE_XTOA(long, l, L);
+DEFINE_XTOA(long long, ll, LL);
+
+DEFINE_ATOX(long, LONG, l, L);
+DEFINE_ATOX(long long, LLONG, ll, LL);
+
+int atoi(const char *str)
+{
+    return (int)strtol(str, NULL, 10);
+}
diff --git a/libraries/mlcrt/src/printf.c b/libraries/mlcrt/src/printf.c
new file mode 100644 (file)
index 0000000..57a83d8
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+ * printf.c
+ *
+ * Copyright (C) 2018 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <monolithium.h>
+#include "io_priv.h"
+
+#define __CRT_PRINTF_FLAG_ALIGN_LEFT         (1 << 0)
+#define __CRT_PRINTF_FLAG_PLUS               (1 << 1)
+#define __CRT_PRINTF_FLAG_SPACE              (1 << 2)
+#define __CRT_PRINTF_FLAG_EXTRA              (1 << 3)
+#define __CRT_PRINTF_FLAG_ZERO_PAD           (1 << 4)
+#define __CRT_PRINTF_FLAG_EXTERNAL_WIDTH     (1 << 5)
+#define __CRT_PRINTF_FLAG_EXTERNAL_PRECISION (1 << 6)
+#define __CRT_PRINTF_FLAG_DEFAULT_WIDTH      (1 << 7)
+#define __CRT_PRINTF_FLAG_DEFAULT_PRECISION  (1 << 8)
+
+typedef struct
+{
+    FILE *stream;
+    char *string;
+    size_t size;
+} __crt_stream_or_string_t;
+
+static int __crt_strputc(__crt_stream_or_string_t *str, char c)
+{
+    if (str->stream)
+    {
+        return fputc_unlocked(c, str->stream) != EOF;
+    }
+    else
+    {
+        if (str->size > 1)
+        {
+            *str->string++ = c;
+            str->size--;
+        }
+
+        return 1;
+    }
+}
+
+static int __crt_strputs(__crt_stream_or_string_t *str, const char *s)
+{
+    if (str->stream)
+    {
+        return fputs_unlocked(s, str->stream) != EOF ? strlen(s) : 0;
+    }
+    else
+    {
+        int length = strlen(s);
+
+        if (str->size > 1)
+        {
+            strncpy(str->string, s, str->size - 1);
+
+            if (length < str->size)
+            {
+                str->string += length;
+                str->size -= length;
+            }
+            else
+            {
+                str->string += str->size - 1;
+                str->size = 0;
+            }
+        }
+
+        return length;
+    }
+}
+
+static inline int __crt_vstrprintf(__crt_stream_or_string_t *str, const char *format, va_list ap)
+{
+    int ret = 0;
+    if (str->stream) syscall_wait_mutex(str->stream->mutex, NO_TIMEOUT);
+
+    const char *ptr;
+    for (ptr = format; *ptr; ptr++)
+    {
+        if (*ptr == '%')
+        {
+            unsigned long flags = 0;
+            unsigned int width = 0, precision = 0;
+
+            ptr++;
+
+            while (*ptr)
+            {
+                if (*ptr == '-') flags |= __CRT_PRINTF_FLAG_ALIGN_LEFT;
+                else if (*ptr == '+') flags |= __CRT_PRINTF_FLAG_PLUS;
+                else if (*ptr == ' ') flags |= __CRT_PRINTF_FLAG_SPACE;
+                else if (*ptr == '#') flags |= __CRT_PRINTF_FLAG_EXTRA;
+                else if (*ptr == '0') flags |= __CRT_PRINTF_FLAG_ZERO_PAD;
+                else break;
+
+                ptr++;
+            }
+
+            if (*ptr == '*') flags |= __CRT_PRINTF_FLAG_EXTERNAL_WIDTH;
+            else if (isdigit(*ptr)) width = strtoul(ptr, (char**)&ptr, 10);
+            else flags |= __CRT_PRINTF_FLAG_DEFAULT_WIDTH;
+
+            if (*ptr == '.')
+            {
+                ptr++;
+                if (*ptr == '*') flags |= __CRT_PRINTF_FLAG_EXTERNAL_PRECISION;
+                else if (isdigit(*ptr)) precision = strtoul(ptr, (char**)&ptr, 10);
+                else flags |= __CRT_PRINTF_FLAG_DEFAULT_PRECISION;
+            }
+            else
+            {
+                flags |= __CRT_PRINTF_FLAG_DEFAULT_PRECISION;
+            }
+
+            int variable_size = 0;
+
+            if (*ptr == 'h')
+            {
+                variable_size--;
+
+                if (*++ptr == 'h')
+                {
+                    variable_size--;
+                    ptr++;
+                }
+            }
+            else if (*ptr == 'l')
+            {
+                variable_size++;
+
+                if (*++ptr == 'l')
+                {
+                    variable_size++;
+                    ptr++;
+                }
+            }
+
+            const char *data = NULL;
+            char buffer[512];
+            int radix = 10;
+
+            switch (*ptr)
+            {
+            case 's':
+                data = va_arg(ap, const char*);
+                break;
+
+            case 'c':
+                data = buffer;
+                buffer[0] = (char)va_arg(ap, int);
+                buffer[1] = '\0';
+                break;
+
+            case 'd':
+            case 'i':
+                if (flags & __CRT_PRINTF_FLAG_DEFAULT_WIDTH) width = 0;
+                if (flags & __CRT_PRINTF_FLAG_DEFAULT_PRECISION) precision = 1;
+                data = buffer;
+
+                switch (variable_size)
+                {
+                case -2: itoa((char)va_arg(ap, int), buffer, 10); break;
+                case -1: itoa((short)va_arg(ap, int), buffer, 10); break;
+                case  0: itoa(va_arg(ap, int), buffer, 10); break;
+                case  1: ltoa(va_arg(ap, long), buffer, 10); break;
+                case  2: lltoa(va_arg(ap, long long), buffer, 10); break;
+                }
+                break;
+
+            case 'o':
+                radix = 8;
+                goto read_variable;
+            case 'x':
+            case 'X':
+                radix = 16;
+            case 'u':
+            read_variable:
+                if (flags & __CRT_PRINTF_FLAG_DEFAULT_WIDTH) width = 0;
+                if (flags & __CRT_PRINTF_FLAG_DEFAULT_PRECISION) precision = 1;
+                data = buffer;
+
+                switch (variable_size)
+                {
+                case -2: uitoa((unsigned char)va_arg(ap, unsigned int), buffer, radix); break;
+                case -1: uitoa((unsigned short)va_arg(ap, unsigned int), buffer, radix); break;
+                case  0: uitoa(va_arg(ap, unsigned int), buffer, radix); break;
+                case  1: ultoa(va_arg(ap, unsigned long), buffer, radix); break;
+                case  2: ulltoa(va_arg(ap, unsigned long long), buffer, radix); break;
+                }
+                break;
+
+            case '%':
+                data = buffer;
+                strcpy(buffer, "%");
+                break;
+            }
+
+            if (flags & __CRT_PRINTF_FLAG_EXTERNAL_WIDTH) width = va_arg(ap, unsigned int);
+            if (flags & __CRT_PRINTF_FLAG_EXTERNAL_PRECISION) precision = va_arg(ap, unsigned int);
+
+            int length = strlen(data);
+            char padding = (flags &__CRT_PRINTF_FLAG_ZERO_PAD) ? '0' : ' ';
+
+            switch (*ptr)
+            {
+            case 's':
+                if (!(flags & __CRT_PRINTF_FLAG_ALIGN_LEFT))
+                {
+                    while (length < width)
+                    {
+                        ret += __crt_strputc(str, padding);
+                        length++;
+                    }
+                }
+
+                if (precision)
+                {
+                    while (*data && precision > 0)
+                    {
+                        ret += __crt_strputc(str, *data++);
+                        precision--;
+                    }
+                }
+                else
+                {
+                    ret += __crt_strputs(str, data ? data : "(null)");
+                }
+                break;
+
+            case 'd':
+            case 'i':
+            case 'o':
+            case 'u':
+            case 'x':
+            case 'X':
+                if (flags & (__CRT_PRINTF_FLAG_PLUS | __CRT_PRINTF_FLAG_SPACE))
+                {
+                    if (*data == '-')
+                    {
+                        ret += __crt_strputc(str, '-');
+                        data++;
+                    }
+                    else
+                    {
+                        ret += __crt_strputc(str, (flags & __CRT_PRINTF_FLAG_PLUS) ? '+' : ' ');
+                        length++;
+                    }
+                }
+
+                if (!(flags & __CRT_PRINTF_FLAG_ALIGN_LEFT) && width > precision)
+                {
+                    while (length < width - precision)
+                    {
+                        ret += __crt_strputc(str, padding);
+                        length++;
+                    }
+
+                    while (length < width)
+                    {
+                        ret += __crt_strputc(str, '0');
+                        length++;
+                    }
+                }
+                else
+                {
+                    while (length < precision)
+                    {
+                        ret += __crt_strputc(str, '0');
+                        length++;
+                    }
+                }
+
+                ret += __crt_strputs(str, data);
+                break;
+            }
+
+            while (length < width)
+            {
+                ret += __crt_strputc(str, padding);
+                length++;
+            }
+        }
+        else
+        {
+            ret += __crt_strputc(str, *ptr);
+        }
+    }
+
+    if (str->string) *str->string = '\0';
+    if (str->stream) syscall_release_mutex(str->stream->mutex);
+    return ret;
+}
+
+int vsnprintf(char *string, size_t size, const char *format, va_list ap)
+{
+    __crt_stream_or_string_t str = { .stream = NULL, .string = string, .size = size };
+    return __crt_vstrprintf(&str, format, ap);
+}
+
+int vsprintf(char *str, const char *format, va_list ap)
+{
+    return vsnprintf(str, -1, format, ap);
+}
+
+int vprintf(const char *format, va_list ap)
+{
+    return vfprintf(stdout, format, ap);
+}
+
+int vfprintf(FILE *stream, const char *format, va_list ap)
+{
+    __crt_stream_or_string_t str = { .stream = stream, .string = NULL, .size = 0 };
+    return __crt_vstrprintf(&str, format, ap);
+}
+
+int fprintf(FILE *stream, const char *format, ...)
+{
+    va_list ap;
+    va_start(ap, format);
+    int ret = vfprintf(stream, format, ap);
+    va_end(ap);
+    return ret;
+}
+
+int snprintf(char *str, size_t size, const char *format, ...)
+{
+    va_list ap;
+    va_start(ap, format);
+    int ret = vsnprintf(str, size, format, ap);
+    va_end(ap);
+    return ret;
+}
+
+int sprintf(char *str, const char *format, ...)
+{
+    va_list ap;
+    va_start(ap, format);
+    int ret = vsprintf(str, format, ap);
+    va_end(ap);
+    return ret;
+}
+
+int printf(const char *format, ...)
+{
+    va_list ap;
+    va_start(ap, format);
+    int ret = vprintf(format, ap);
+    va_end(ap);
+    return ret;
+}
diff --git a/libraries/mlcrt/src/setjmp.c b/libraries/mlcrt/src/setjmp.c
new file mode 100644 (file)
index 0000000..646af24
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * setjmp.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <setjmp.h>
+#include <monolithium.h>
+
+int setjmp(jmp_buf env)
+{
+    syscall_query_thread(INVALID_HANDLE, THREAD_CPU_STATE_INFO, &env->state, sizeof(env->state));
+    return env->val;
+}
+
+int longjmp(jmp_buf env, int val)
+{
+    env->val = val ? val : 1;
+    syscall_set_thread(INVALID_HANDLE, THREAD_CPU_STATE_INFO, &env->state, sizeof(env->state));
+    return -1;
+}
diff --git a/libraries/mlcrt/src/string.c b/libraries/mlcrt/src/string.c
new file mode 100644 (file)
index 0000000..176ae65
--- /dev/null
@@ -0,0 +1,314 @@
+/*
+ * string.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+char *strcpy(char *destination, const char *source)
+{
+    while (*source != 0) *(destination++) = *(source++);
+    *destination = 0;
+    return destination;
+}
+
+char *strncpy(char *destination, const char *source, uint32_t num)
+{
+    char *ptr = destination;
+    while ((num--) && (*source)) *(ptr++) = *(source++);
+    *ptr = 0;
+    return destination;
+}
+
+int strcmp(const char *str1, const char *str2)
+{
+    while (*str1 || *str2)
+    {
+        if (*str1 != *str2) break;
+        str1++;
+        str2++;
+    }
+
+    if (*str1 < *str2) return -1;
+    else if (*str1 > *str2) return 1;
+    else return 0;
+}
+
+int stricmp(const char *str1, const char *str2)
+{
+    while (*str1 || *str2)
+    {
+        if (tolower(*str1) != tolower(*str2)) break;
+        str1++;
+        str2++;
+    }
+    if (*str1 < *str2) return -1;
+    else if (*str1 > *str2) return 1;
+    else return 0;
+}
+
+int strncmp(const char *str1, const char *str2, size_t n)
+{
+    int i;
+
+    for (i = 0; i < n; i++)
+    {
+        if (str1[i] < str2[i]) return -1;
+        else if (str1[i] > str2[i]) return 1;
+        if (str1[i] == 0 || str2[i] == 0) break;
+    }
+
+    return 0;
+}
+
+char *strstr(const char *haystack, const char *needle)
+{
+    while (*haystack)
+    {
+        const char *s1 = haystack;
+        const char *s2 = needle;
+        int found = 1;
+
+        while (*s2)
+        {
+            if (*s1++ != *s2++)
+            {
+                found = 0;
+                break;
+            }
+        }
+
+        if (found) return (char*)haystack;
+        haystack++;
+    }
+
+    return NULL;
+}
+
+char *strchr(const char *str, char c)
+{
+    while ((*str != 0) && (*str != c)) str++;
+    if (*str == c) return (char*)str;
+    else return NULL;
+}
+
+char *strrchr(const char *str, char c)
+{
+    char *ret = NULL;
+
+    while (*str != 0)
+    {
+        if (*str == c) ret = (char*)str;
+        str++;
+    }
+
+    return ret;
+}
+
+char *strcat(char *destination, const char *source)
+{
+    strcpy(strchr(destination, '\0'), source);
+    return destination;
+}
+
+char *strncat(char *destination, const char *source, size_t n)
+{
+    char *ptr = strchr(destination, 0);
+    while ((n--) && (*source)) *(ptr++) = *(source++);
+    *ptr = 0;
+    return destination;
+}
+
+char *strdup(const char *source)
+{
+    char *destination = (char*)malloc(strlen(source) + 1);
+    if (destination) strcpy(destination, source);
+    return destination;
+}
+
+char *strtok_r(char *str, const char *delimiters, char **endptr)
+{
+    if (str == NULL) str = *endptr;
+    char *start = str;
+
+    while (*str != 0)
+    {
+        if (strchr(delimiters, *str) != NULL)
+        {
+            *str = 0;
+            *endptr = str + 1;
+            return start;
+        }
+
+        str++;
+    }
+
+    *endptr = str;
+    return start != str ? start : NULL;
+}
+
+char *strtok(char *str, const char *delimiters)
+{
+    static char *endptr;
+    return strtok_r(str, delimiters, &endptr);
+}
+
+size_t strlen(const char *str)
+{
+    int ret = 0;
+    while (str[ret] != 0) ret++;
+    return ret;
+}
+
+void strrev(char *str)
+{
+    size_t i, j = strlen(str) - 1;
+
+    while (i < j)
+    {
+        int t = str[i];
+        str[i] = str[j];
+        str[j] = t;
+
+        i++;
+        j--;
+    }
+}
+
+void memset(void *ptr, int value, size_t n)
+{
+    uint8_t *ptr_byte = (uint8_t*)ptr;
+    value &= 0xFF;
+    uint32_t tile = value | (value << 8) | (value << 16) | (value << 24);
+
+    if (n >> 2)
+    {
+        asm volatile ("cld\n"
+                      "rep stosl\n"
+                      : "=D"(ptr_byte)
+                      : "D"(ptr_byte), "a"(tile), "c"(n >> 2)
+                      : "cc");
+    }
+
+    switch (n & 3)
+    {
+    case 3:
+        *ptr_byte++ = value;
+    case 2:
+        *ptr_byte++ = value;
+    case 1:
+        *ptr_byte++ = value;
+    }
+}
+
+void memcpy(void *destination, const void *source, size_t n)
+{
+    uint8_t *src_byte = (uint8_t*)source;
+    uint8_t *dest_byte = (uint8_t*)destination;
+    if (!n) return;
+
+    if (n >> 2)
+    {
+        asm volatile ("cld\n"
+                      "rep movsl\n"
+                      : "=D"(dest_byte), "=S"(src_byte)
+                      : "D"(destination), "S"(source), "c"(n >> 2)
+                      : "cc", "memory");
+    }
+
+    switch (n & 3)
+    {
+    case 3:
+        *dest_byte++ = *src_byte++;
+    case 2:
+        *dest_byte++ = *src_byte++;
+    case 1:
+        *dest_byte++ = *src_byte++;
+    }
+}
+
+void memmove(void *destination, const void *source, size_t n)
+{
+    if (!n) return;
+
+    if (destination < source)
+    {
+        uint8_t *src_byte = (uint8_t*)source;
+        uint8_t *dest_byte = (uint8_t*)destination;
+
+        if (n >> 2)
+        {
+            asm volatile ("cld\n"
+                          "rep movsl\n"
+                          : "=D"(dest_byte), "=S"(src_byte)
+                          : "D"(destination), "S"(source), "c"(n >> 2)
+                          : "cc", "memory");
+        }
+
+        switch (n & 3)
+        {
+        case 3:
+            *dest_byte++ = *src_byte++;
+        case 2:
+            *dest_byte++ = *src_byte++;
+        case 1:
+            *dest_byte++ = *src_byte++;
+        }
+    }
+    else if (destination > source)
+    {
+        uint8_t *src_byte = (uint8_t*)source + n;
+        uint8_t *dest_byte = (uint8_t*)destination + n;
+
+        switch (n & 3)
+        {
+        case 3:
+            *--dest_byte = *--src_byte;
+        case 2:
+            *--dest_byte = *--src_byte;
+        case 1:
+            *--dest_byte = *--src_byte;
+        }
+
+        if (n >> 2)
+        {
+            asm volatile ("std\n"
+                          "rep movsl\n"
+                          :
+                          : "D"(dest_byte - 4), "S"(src_byte - 4), "c"(n >> 2)
+                          : "cc", "memory");
+        }
+    }
+}
+
+int memcmp(const void *mem1, const void *mem2, size_t n)
+{
+    uint32_t flags;
+
+    asm volatile ("cld\n"
+                  "repz cmpsb\n"
+                  "pushfl\n"
+                  "popl %0\n"
+                  : "=r"(flags)
+                  : "S"(mem1), "D"(mem2), "c"(n)
+                  : "cc");
+
+    if (flags & 0x40) return 0;
+    else return (flags & 1) ? 1 : -1;
+}
diff --git a/libraries/mlcrt/src/wd.c b/libraries/mlcrt/src/wd.c
new file mode 100644 (file)
index 0000000..ed0029a
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * wc.c
+ *
+ * Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <monolithium.h>
+
+handle_t __crt_get_raw_handle(int fd);
+
+static char *wd_path = NULL;
+
+char *getcwd(char *buf, size_t size)
+{
+    return strncpy(buf, wd_path, size);
+}
+
+char *getwd(char *buf)
+{
+    return strcpy(buf, wd_path);
+}
+
+char *get_current_dir_name(void)
+{
+    return strdup(wd_path);
+}
+
+int fchdir(int fd)
+{
+    char path[MAX_PATH];
+    handle_t handle = __crt_get_raw_handle(fd);
+
+    sysret_t ret = syscall_query_file(handle, FILE_INFO_NAME, path, sizeof(path));
+
+    if (ret != ERR_SUCCESS)
+    {
+        switch (ret)
+        {
+        case ERR_FORBIDDEN:
+            errno = EACCES;
+
+        default:
+            errno = __crt_translate_error(ret);
+        }
+
+        return -1;
+    }
+
+    if (wd_path)
+    {
+        free(wd_path);
+        wd_path = NULL;
+    }
+
+    wd_path = strdup(path);
+    return 0;
+}
+
+int chdir(const char *path)
+{
+    int fd = open(path, O_RDONLY, 0);
+    if (fd < 0) return -1;
+
+    int ret = fchdir(fd);
+    close(fd);
+    return ret;
+}
diff --git a/libraries/mlsys/.gitignore b/libraries/mlsys/.gitignore
new file mode 100644 (file)
index 0000000..b3c20b3
--- /dev/null
@@ -0,0 +1,11 @@
+*
+
+# Include the following files:
+!.gitignore
+!Makefile
+!gen_wrappers.awk
+!src
+!src/*
+
+# Exclude generated files:
+src/wrappers.c
diff --git a/libraries/mlsys/Makefile b/libraries/mlsys/Makefile
new file mode 100644 (file)
index 0000000..e936659
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# Makefile
+#
+# Copyright (C) 2016 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Settings
+DEBUG := yes
+
+CFLAGS   := -Wall -Werror -ffreestanding -nostdlib -fPIC -I ../..
+ASMFLAGS := -felf
+
+# Input and output files
+SOURCES = $(wildcard $(SRCDIR)/*.c) $(wildcard $(SRCDIR)/*.asm)
+
+OUTPUT_STATIC_LIB  := ../bin/libmlsys.a
+OUTPUT_DYNAMIC_LIB := ../bin/mlsys.dyn
+
+-include ../../common.mk
diff --git a/libraries/mlsys/src/syscall.asm b/libraries/mlsys/src/syscall.asm
new file mode 100644 (file)
index 0000000..0958e14
--- /dev/null
@@ -0,0 +1,30 @@
+;
+; syscall.asm
+;
+; Copyright (C) 2016 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+;
+; This program is free software: you can redistribute it and/or modify
+; it under the terms of the GNU Affero General Public License as
+; published by the Free Software Foundation, either version 3 of the
+; License, or (at your option) any later version.
+;
+; This program is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+; GNU Affero General Public License for more details.
+;
+; You should have received a copy of the GNU Affero General Public License
+; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+;
+
+bits 32
+
+global syscall
+
+syscall:                    push ebp
+                            mov ebp, esp
+                            mov eax, [ebp + 8]
+                            lea edx, [ebp + 12]
+                            int 0xE5
+                            leave
+                            ret
diff --git a/library/.gitignore b/library/.gitignore
deleted file mode 100644 (file)
index b3c20b3..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-*
-
-# Include the following files:
-!.gitignore
-!Makefile
-!gen_wrappers.awk
-!src
-!src/*
-
-# Exclude generated files:
-src/wrappers.c
diff --git a/library/Makefile b/library/Makefile
deleted file mode 100644 (file)
index 4dc3cb3..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Makefile
-#
-# Copyright (C) 2016 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-# Settings
-DEBUG := yes
-
-CFLAGS   := -Wall -Werror -ffreestanding -nostdlib -fPIC -I ..
-ASMFLAGS := -felf
-
-# Input and output files
-SOURCES = $(wildcard $(SRCDIR)/*.c) $(wildcard $(SRCDIR)/*.asm)
-
-OUTPUT_STATIC_LIB  := libmlsys.a
-OUTPUT_DYNAMIC_LIB := mlsys.dyn
-
--include ../common.mk
diff --git a/library/src/syscall.asm b/library/src/syscall.asm
deleted file mode 100644 (file)
index 0958e14..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-;
-; syscall.asm
-;
-; Copyright (C) 2016 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
-;
-; This program is free software: you can redistribute it and/or modify
-; it under the terms of the GNU Affero General Public License as
-; published by the Free Software Foundation, either version 3 of the
-; License, or (at your option) any later version.
-;
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-; GNU Affero General Public License for more details.
-;
-; You should have received a copy of the GNU Affero General Public License
-; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-;
-
-bits 32
-
-global syscall
-
-syscall:                    push ebp
-                            mov ebp, esp
-                            mov eax, [ebp + 8]
-                            lea edx, [ebp + 12]
-                            int 0xE5
-                            leave
-                            ret
diff --git a/manager/.gitignore b/manager/.gitignore
deleted file mode 100644 (file)
index f4f4f75..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-*
-
-# Include the following files:
-!.gitignore
-!Makefile
-!src
-!src/*
diff --git a/manager/Makefile b/manager/Makefile
deleted file mode 100644 (file)
index 8aa4b7e..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Makefile
-#
-# Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-
-# Settings
-DEBUG := yes
-
-# Flags
-CFLAGS   += -Wall -Werror -ffreestanding -nostdlib -I ../sdk -I ../crt/include
-ASMFLAGS += -felf
-LDFLAGS  += -L ../library -L ../crt -lmlcrt -lmlsys
-
-LINK_WITH_LIBGCC := yes
-
-# Input and output files
-SOURCES =  $(wildcard $(SRCDIR)/*.c)
-SOURCES += $(wildcard $(SRCDIR)/servers/*.c)
-SOURCES += $(wildcard $(SRCDIR)/*.asm)
-
-OUTPUT_PROGRAM := manager
-
--include ../common.mk
diff --git a/manager/src/start.c b/manager/src/start.c
deleted file mode 100644 (file)
index 28944be..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <syscalls.h>
-#include <process.h>
-
-int process_startup(process_params_t *parameters)
-{
-    for (;;);
-    return 0;
-}
diff --git a/programs/.gitignore b/programs/.gitignore
new file mode 100644 (file)
index 0000000..ba077a4
--- /dev/null
@@ -0,0 +1 @@
+bin
diff --git a/programs/Makefile b/programs/Makefile
new file mode 100644 (file)
index 0000000..11de2ab
--- /dev/null
@@ -0,0 +1,24 @@
+#
+# Makefile
+#
+# Copyright (C) 2018 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+all:
+       $(MAKE) -C manager all
+clean:
+       $(MAKE) -C manager clean
+
diff --git a/programs/manager/.gitignore b/programs/manager/.gitignore
new file mode 100644 (file)
index 0000000..f4f4f75
--- /dev/null
@@ -0,0 +1,7 @@
+*
+
+# Include the following files:
+!.gitignore
+!Makefile
+!src
+!src/*
diff --git a/programs/manager/Makefile b/programs/manager/Makefile
new file mode 100644 (file)
index 0000000..5970cd3
--- /dev/null
@@ -0,0 +1,37 @@
+#
+# Makefile
+#
+# Copyright (C) 2017 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Settings
+DEBUG := yes
+
+# Flags
+CFLAGS   += -Wall -Werror -ffreestanding -nostdlib -I ../../sdk -I ../../libraries/mlcrt/include
+ASMFLAGS += -felf
+LDFLAGS  += -L ../../libraries/bin -lmlcrt -lmlsys
+
+LINK_WITH_LIBGCC := yes
+
+# Input and output files
+SOURCES =  $(wildcard $(SRCDIR)/*.c)
+SOURCES += $(wildcard $(SRCDIR)/servers/*.c)
+SOURCES += $(wildcard $(SRCDIR)/*.asm)
+
+OUTPUT_PROGRAM := ../bin/manager
+
+-include ../../common.mk
diff --git a/programs/manager/src/start.c b/programs/manager/src/start.c
new file mode 100644 (file)
index 0000000..28944be
--- /dev/null
@@ -0,0 +1,8 @@
+#include <syscalls.h>
+#include <process.h>
+
+int process_startup(process_params_t *parameters)
+{
+    for (;;);
+    return 0;
+}