Merge remote-tracking branch 'Userspace/master'

This commit is contained in:
EnderIce2
2024-11-20 05:02:06 +02:00
104 changed files with 11117 additions and 1 deletions

View File

@@ -0,0 +1,29 @@
#include <ctype.h>
#include <sys/types.h> // For PUBLIC
PUBLIC int tolower(int c)
{
if (c >= 'A' && c <= 'Z')
{
c -= 'A';
c += 'a';
}
return c;
}
PUBLIC int toupper(int c)
{
if (c >= 'a' && c <= 'z')
{
c -= 'a';
c += 'A';
}
return c;
}
PUBLIC int isspace(int c)
{
return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f' || c == '\v';
}

View File

@@ -0,0 +1,10 @@
#include <errno.h>
#include <sys/types.h> // For PUBLIC
int __local_stub_errno = 0;
PUBLIC int *__errno_location(void)
{
return &__local_stub_errno;
}

View File

@@ -0,0 +1,132 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <fennix/syscall.h>
#include <sys/types.h> // For PUBLIC
PUBLIC FILE *stdin = NULL;
PUBLIC FILE *stdout = NULL;
PUBLIC FILE *stderr = NULL;
PUBLIC FILE *freopen(const char *filename, const char *mode, FILE *stream)
{
errno = ENOSYS;
return NULL;
}
PUBLIC FILE *fopen(const char *filename, const char *mode)
{
int fd = syscall2(sc_open, (uint64_t)filename, (uint64_t)mode);
if (fd < 0)
return NULL;
FILE *FilePtr = malloc(sizeof(FILE));
FilePtr->_fileno = fd;
return FilePtr;
}
PUBLIC size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
if (ptr == NULL || stream == NULL || size == 0 || nmemb == 0)
{
errno = EINVAL;
return 0;
}
syscall3(sc_lseek, stream->_fileno, stream->_offset, SEEK_SET);
return syscall3(sc_read, (uint64_t)stream->_fileno, (uint64_t)ptr, size * nmemb);
}
PUBLIC size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
if (ptr == NULL || stream == NULL || size == 0 || nmemb == 0)
{
errno = EINVAL;
return 0;
}
syscall3(sc_lseek, stream->_fileno, stream->_offset, SEEK_SET);
return syscall3(sc_write, (uint64_t)stream->_fileno, (uint64_t)ptr, size * nmemb);
}
PUBLIC int fclose(FILE *fp)
{
if (fp == NULL)
{
errno = EINVAL;
return EOF;
}
return syscall1(sc_close, fp->_fileno);
}
PUBLIC off_t fseek(FILE *stream, off_t offset, int whence)
{
if (stream == NULL || whence < 0 || whence > 2)
{
errno = EINVAL;
return -1;
}
off_t new_offset = syscall3(sc_lseek, stream->_fileno, offset, whence);
if (new_offset < 0)
return -1;
stream->_offset = new_offset;
return new_offset;
}
PUBLIC long ftell(FILE *stream)
{
return stream->_offset;
}
PUBLIC int fflush(FILE *stream)
{
if (stream == NULL)
{
errno = EINVAL;
return EOF;
}
errno = ENOSYS;
return EOF;
}
PUBLIC int fprintf(FILE *stream, const char *format, ...)
{
if (stream == NULL || format == NULL)
{
errno = EINVAL;
return -1;
}
va_list args;
va_start(args, format);
const int ret = vfprintf(stream, format, args);
va_end(args);
return ret;
}
PUBLIC void setbuf(FILE *stream, char *buf)
{
}
PUBLIC int vfprintf(FILE *stream, const char *format, va_list arg)
{
return 0;
}
PUBLIC int vsscanf(const char *s, const char *format, va_list arg)
{
}
PUBLIC int sscanf(const char *s, const char *format, ...)
{
va_list args;
va_start(args, format);
const int ret = vsscanf(s, format, args);
va_end(args);
return ret;
}

View File

@@ -0,0 +1,9 @@
#include <stdio.h>
#include <stdarg.h>
#include <fennix/syscall.h>
#include <sys/types.h> // For PUBLIC
PUBLIC int fgetc(FILE *stream)
{
}

View File

@@ -0,0 +1,34 @@
#include <stdio.h>
#include <stdarg.h>
#include <fennix/syscall.h>
#include <sys/types.h> // For PUBLIC
PUBLIC int fputc(int c, FILE *stream)
{
// FIXME
// if (stream == NULL)
// {
// errno = EBADF;
// return EOF;
// }
char str[2] = {c, '\0'};
// return syscall3(sys_KernelCTL, KCTL_PRINT, str, 0);
}
PUBLIC int putc(int c, FILE *stream) { return fputc(c, stream); }
PUBLIC int fputs(const char *s, FILE *stream)
{
for (int i = 0; s[i] != '\0'; i++)
fputc(s[i], stream);
}
PUBLIC int puts(const char *s)
{
for (int i = 0; s[i] != '\0'; i++)
fputc(s[i], stdout);
}
PUBLIC int putchar(int c) { return fputc(c, stdout); }
PUBLIC void perror(const char *s) { fputs(s, stderr); }

View File

@@ -0,0 +1,87 @@
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <fennix/syscall.h>
#include "../mem/liballoc_1_1.h"
PUBLIC void abort(void)
{
syscall1(sc_exit, -0xAB057);
while (1)
;
}
PUBLIC int atexit(void (*function)(void))
{
return 1;
}
PUBLIC void exit(int status)
{
_exit(status);
}
PUBLIC int atoi(const char *nptr)
{
uint64_t Length = strlen((char *)nptr);
if (nptr)
while (nptr[Length] != '\0')
++Length;
uint64_t OutBuffer = 0;
uint64_t Power = 1;
for (uint64_t i = Length; i > 0; --i)
{
OutBuffer += (nptr[i - 1] - 48) * Power;
Power *= 10;
}
return OutBuffer;
}
PUBLIC char **environ = NULL;
PUBLIC char *getenv(const char *name)
{
char **env = environ;
if (env == NULL)
return NULL;
size_t len = strlen(name);
while (*env != NULL)
{
if ((strncmp(*env, name, len) == 0) && ((*env)[len] == '='))
return &(*env)[len + 1];
++env;
}
}
PUBLIC void *malloc(size_t Size) { return PREFIX(malloc)(Size); }
PUBLIC void *realloc(void *Address, size_t Size) { return PREFIX(realloc)(Address, Size); }
PUBLIC void *calloc(size_t Count, size_t Size) { return PREFIX(calloc)(Count, Size); }
PUBLIC void free(void *Address)
{
PREFIX(free)
(Address);
}
PUBLIC int system(const char *command)
{
return -1;
}
PUBLIC double atof(const char *nptr)
{
// FIXME: This is a very bad implementation of atof.
uint64_t Length = strlen((char *)nptr);
if (nptr)
while (nptr[Length] != '\0')
++Length;
double OutBuffer = 0;
double Power = 1;
for (uint64_t i = Length; i > 0; --i)
{
OutBuffer += (nptr[i - 1] - 48) * Power;
Power *= 10;
}
return OutBuffer;
}

View File

@@ -0,0 +1,17 @@
#include <spawn.h>
int posix_spawn(pid_t *pid, const char *path,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[],
char *const envp[])
{
}
int posix_spawnp(pid_t *pid, const char *file,
const posix_spawn_file_actions_t *file_actions,
const posix_spawnattr_t *attrp,
char *const argv[],
char *const envp[])
{
}

View File

@@ -0,0 +1,13 @@
#include <stdio.h>
#include "../../../Kernel/syscalls.h"
void __libc_init_std(void)
{
/* FIXME: Temporal workaround */
// int IsCritical = syscall1(_KernelCTL, 6 /* KCTL_IS_CRITICAL */);
}
void __libc_fini_std(void)
{
}

View File

@@ -0,0 +1,346 @@
#include <stddef.h>
#include <sys/types.h> // For PUBLIC
/* Some of the functions are from musl library */
/* https://www.musl-libc.org/ */
/*
Copyright © 2005-2020 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
PUBLIC void *memcpy(void *dest, const void *src, size_t n)
{
unsigned char *d = dest;
const unsigned char *s = src;
#ifdef __GNUC__
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define LS >>
#define RS <<
#else
#define LS <<
#define RS >>
#endif
typedef uint32_t __attribute__((__may_alias__)) u32;
uint32_t w, x;
for (; (uintptr_t)s % 4 && n; n--)
*d++ = *s++;
if ((uintptr_t)d % 4 == 0)
{
for (; n >= 16; s += 16, d += 16, n -= 16)
{
*(u32 *)(d + 0) = *(u32 *)(s + 0);
*(u32 *)(d + 4) = *(u32 *)(s + 4);
*(u32 *)(d + 8) = *(u32 *)(s + 8);
*(u32 *)(d + 12) = *(u32 *)(s + 12);
}
if (n & 8)
{
*(u32 *)(d + 0) = *(u32 *)(s + 0);
*(u32 *)(d + 4) = *(u32 *)(s + 4);
d += 8;
s += 8;
}
if (n & 4)
{
*(u32 *)(d + 0) = *(u32 *)(s + 0);
d += 4;
s += 4;
}
if (n & 2)
{
*d++ = *s++;
*d++ = *s++;
}
if (n & 1)
{
*d = *s;
}
return dest;
}
if (n >= 32)
{
switch ((uintptr_t)d % 4)
{
case 1:
{
w = *(u32 *)s;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
n -= 3;
for (; n >= 17; s += 16, d += 16, n -= 16)
{
x = *(u32 *)(s + 1);
*(u32 *)(d + 0) = (w LS 24) | (x RS 8);
w = *(u32 *)(s + 5);
*(u32 *)(d + 4) = (x LS 24) | (w RS 8);
x = *(u32 *)(s + 9);
*(u32 *)(d + 8) = (w LS 24) | (x RS 8);
w = *(u32 *)(s + 13);
*(u32 *)(d + 12) = (x LS 24) | (w RS 8);
}
break;
}
case 2:
{
w = *(u32 *)s;
*d++ = *s++;
*d++ = *s++;
n -= 2;
for (; n >= 18; s += 16, d += 16, n -= 16)
{
x = *(u32 *)(s + 2);
*(u32 *)(d + 0) = (w LS 16) | (x RS 16);
w = *(u32 *)(s + 6);
*(u32 *)(d + 4) = (x LS 16) | (w RS 16);
x = *(u32 *)(s + 10);
*(u32 *)(d + 8) = (w LS 16) | (x RS 16);
w = *(u32 *)(s + 14);
*(u32 *)(d + 12) = (x LS 16) | (w RS 16);
}
break;
}
case 3:
{
w = *(u32 *)s;
*d++ = *s++;
n -= 1;
for (; n >= 19; s += 16, d += 16, n -= 16)
{
x = *(u32 *)(s + 3);
*(u32 *)(d + 0) = (w LS 8) | (x RS 24);
w = *(u32 *)(s + 7);
*(u32 *)(d + 4) = (x LS 8) | (w RS 24);
x = *(u32 *)(s + 11);
*(u32 *)(d + 8) = (w LS 8) | (x RS 24);
w = *(u32 *)(s + 15);
*(u32 *)(d + 12) = (x LS 8) | (w RS 24);
}
break;
}
default:
break;
}
}
if (n & 16)
{
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (n & 8)
{
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (n & 4)
{
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
}
if (n & 2)
{
*d++ = *s++;
*d++ = *s++;
}
if (n & 1)
{
*d = *s;
}
return dest;
#endif
for (; n; n--)
*d++ = *s++;
return dest;
}
PUBLIC void *memset(void *dest, int c, size_t n)
{
unsigned char *s = dest;
size_t k;
if (!n)
return dest;
s[0] = c;
s[n - 1] = c;
if (n <= 2)
return dest;
s[1] = c;
s[2] = c;
s[n - 2] = c;
s[n - 3] = c;
if (n <= 6)
return dest;
s[3] = c;
s[n - 4] = c;
if (n <= 8)
return dest;
k = -(uintptr_t)s & 3;
s += k;
n -= k;
n &= -4;
#ifdef __GNUC__
typedef uint32_t __attribute__((__may_alias__)) u32;
typedef uint64_t __attribute__((__may_alias__)) u64;
u32 c32 = ((u32)-1) / 255 * (unsigned char)c;
*(u32 *)(s + 0) = c32;
*(u32 *)(s + n - 4) = c32;
if (n <= 8)
return dest;
*(u32 *)(s + 4) = c32;
*(u32 *)(s + 8) = c32;
*(u32 *)(s + n - 12) = c32;
*(u32 *)(s + n - 8) = c32;
if (n <= 24)
return dest;
*(u32 *)(s + 12) = c32;
*(u32 *)(s + 16) = c32;
*(u32 *)(s + 20) = c32;
*(u32 *)(s + 24) = c32;
*(u32 *)(s + n - 28) = c32;
*(u32 *)(s + n - 24) = c32;
*(u32 *)(s + n - 20) = c32;
*(u32 *)(s + n - 16) = c32;
k = 24 + ((uintptr_t)s & 4);
s += k;
n -= k;
u64 c64 = c32 | ((u64)c32 << 32);
for (; n >= 32; n -= 32, s += 32)
{
*(u64 *)(s + 0) = c64;
*(u64 *)(s + 8) = c64;
*(u64 *)(s + 16) = c64;
*(u64 *)(s + 24) = c64;
}
#else
for (; n; n--, s++)
*s = c;
#endif
return dest;
}
PUBLIC void *memmove(void *dest, const void *src, size_t n)
{
#ifdef __GNUC__
typedef __attribute__((__may_alias__)) size_t WT;
#define WS (sizeof(WT))
#endif
char *d = dest;
const char *s = src;
if (d == s)
return d;
if ((uintptr_t)s - (uintptr_t)d - n <= -2 * n)
return memcpy(d, s, n);
if (d < s)
{
#ifdef __GNUC__
if ((uintptr_t)s % WS == (uintptr_t)d % WS)
{
while ((uintptr_t)d % WS)
{
if (!n--)
return dest;
*d++ = *s++;
}
for (; n >= WS; n -= WS, d += WS, s += WS)
*(WT *)d = *(WT *)s;
}
#endif
for (; n; n--)
*d++ = *s++;
}
else
{
#ifdef __GNUC__
if ((uintptr_t)s % WS == (uintptr_t)d % WS)
{
while ((uintptr_t)(d + n) % WS)
{
if (!n--)
return dest;
d[n] = s[n];
}
while (n >= WS)
n -= WS, *(WT *)(d + n) = *(WT *)(s + n);
}
#endif
while (n)
n--, d[n] = s[n];
}
return dest;
}

View File

@@ -0,0 +1,125 @@
#include <string.h>
#include "../../mem/liballoc_1_1.h"
PUBLIC size_t strlen(const char *str)
{
long unsigned i = 0;
if (str)
while (str[i] != '\0')
++i;
return i;
}
PUBLIC int strcmp(const char *l, const char *r)
{
for (; *l == *r && *l; l++, r++)
;
return *(unsigned char *)l - *(unsigned char *)r;
}
PUBLIC int strncmp(const char *s1, const char *s2, size_t n)
{
for (size_t i = 0; i < n; i++)
{
char c1 = s1[i], c2 = s2[i];
if (c1 != c2)
return c1 - c2;
if (!c1)
return 0;
}
return 0;
}
PUBLIC int strcasecmp(const char *s1, const char *s2)
{
const unsigned char *p1 = (const unsigned char *)s1;
const unsigned char *p2 = (const unsigned char *)s2;
int result;
if (p1 == p2)
return 0;
while ((result = tolower(*p1) - tolower(*p2++)) == 0)
if (*p1++ == '\0')
break;
return result;
}
PUBLIC int strncasecmp(const char *string1, const char *string2, size_t count)
{
if (count)
{
const unsigned char *s1 = (const unsigned char *)string1;
const unsigned char *s2 = (const unsigned char *)string2;
int result;
do
{
if ((result = tolower(*s1) - tolower(*s2++)) != 0 || !*s1++)
break;
} while (--count);
return result;
}
return 0;
}
PUBLIC char *strstr(const char *haystack, const char *needle)
{
const char *a = haystack, *b = needle;
while (1)
{
if (!*b)
return (char *)haystack;
if (!*a)
return NULL;
if (*a++ != *b++)
{
a = ++haystack;
b = needle;
}
}
}
PUBLIC char *strncpy(char *destination, const char *source, unsigned long num)
{
if (destination == NULL)
return NULL;
char *ptr = destination;
while (*source && num--)
{
*destination = *source;
destination++;
source++;
}
*destination = '\0';
return ptr;
}
PUBLIC char *strdup(const char *s)
{
char *buf = (char *)__malloc(strlen((char *)s) + 1);
strncpy(buf, s, strlen(s) + 1);
return buf;
}
PUBLIC char *strchr(char const *s, int c)
{
size_t len = strlen(s);
for (size_t i = 0; i < len; i++)
if (s[i] == c)
return (char *)s + i;
return NULL;
}
PUBLIC char *strrchr(char const *s, int c)
{
size_t len = strlen(s);
size_t pos = len;
while (s[pos] != c && pos-- != 0)
;
if (pos == len)
return NULL;
return (char *)s + pos;
}

View File

@@ -0,0 +1,14 @@
#include <sys/wait.h>
PUBLIC pid_t wait(int *wstatus)
{
return waitpid(-1, &wstatus, 0);
}
PUBLIC pid_t waitpid(pid_t pid, int *wstatus, int options)
{
}
PUBLIC int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)
{
}

View File

@@ -0,0 +1,18 @@
#include <sys/stat.h>
#include <sys/types.h> // For PUBLIC
PUBLIC int mkdir(const char *path, mode_t mode)
{
return 0;
}
PUBLIC int remove(const char *pathname)
{
return 0;
}
PUBLIC int rename(const char *oldpath, const char *newpath)
{
return 0;
}

View File

@@ -0,0 +1,51 @@
#include <unistd.h>
#include <stddef.h>
#include <errno.h>
#include "../../../Kernel/syscalls.h"
PUBLIC int execl(const char *pathname, const char *arg, ...)
{
errno = ENOSYS;
return -1;
}
PUBLIC int execlp(const char *file, const char *arg, ...)
{
errno = ENOSYS;
return -1;
}
PUBLIC int execle(const char *pathname, const char *arg, ...)
{
errno = ENOSYS;
return -1;
}
PUBLIC int execv(const char *pathname, char *const argv[])
{
errno = ENOSYS;
return -1;
}
PUBLIC int execvp(const char *file, char *const argv[])
{
errno = ENOSYS;
return -1;
}
PUBLIC int execvpe(const char *file, char *const argv[], char *const envp[])
{
errno = ENOSYS;
return -1;
}
PUBLIC int execve(const char *pathname, char *const argv[], char *const envp[])
{
errno = ENOSYS;
return -1;
}
PUBLIC pid_t fork(void)
{
return syscall0(sc_fork);
}

View File

@@ -0,0 +1,14 @@
#include <unistd.h>
#include <stddef.h>
#include <errno.h>
#include "../../../Kernel/syscalls.h"
PUBLIC unsigned int sleep(unsigned int seconds)
{
// return syscall1(sys_Sleep, seconds * 1000000);
}
PUBLIC int usleep(useconds_t usec)
{
// return syscall1(sys_Sleep, usec);
}