mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-08-26 21:44:59 +00:00
Merge remote-tracking branch 'Userspace/master'
This commit is contained in:
29
Userspace/libc/src/std/ctype.c
Normal file
29
Userspace/libc/src/std/ctype.c
Normal 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';
|
||||
}
|
10
Userspace/libc/src/std/errno.c
Normal file
10
Userspace/libc/src/std/errno.c
Normal 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;
|
||||
}
|
132
Userspace/libc/src/std/io/file.c
Normal file
132
Userspace/libc/src/std/io/file.c
Normal 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;
|
||||
}
|
9
Userspace/libc/src/std/io/get.c
Normal file
9
Userspace/libc/src/std/io/get.c
Normal 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)
|
||||
{
|
||||
}
|
34
Userspace/libc/src/std/io/put.c
Normal file
34
Userspace/libc/src/std/io/put.c
Normal 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); }
|
87
Userspace/libc/src/std/lib.c
Normal file
87
Userspace/libc/src/std/lib.c
Normal 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;
|
||||
}
|
17
Userspace/libc/src/std/spawn.c
Normal file
17
Userspace/libc/src/std/spawn.c
Normal 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[])
|
||||
{
|
||||
}
|
13
Userspace/libc/src/std/std_init.c
Normal file
13
Userspace/libc/src/std/std_init.c
Normal 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)
|
||||
{
|
||||
}
|
346
Userspace/libc/src/std/string/memop.c
Normal file
346
Userspace/libc/src/std/string/memop.c
Normal 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;
|
||||
}
|
125
Userspace/libc/src/std/string/string.c
Normal file
125
Userspace/libc/src/std/string/string.c
Normal 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;
|
||||
}
|
14
Userspace/libc/src/std/sys/wait.c
Normal file
14
Userspace/libc/src/std/sys/wait.c
Normal 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)
|
||||
{
|
||||
}
|
18
Userspace/libc/src/std/sys_stat.c
Normal file
18
Userspace/libc/src/std/sys_stat.c
Normal 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;
|
||||
}
|
51
Userspace/libc/src/std/uni/exe.c
Normal file
51
Userspace/libc/src/std/uni/exe.c
Normal 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);
|
||||
}
|
14
Userspace/libc/src/std/uni/sleep.c
Normal file
14
Userspace/libc/src/std/uni/sleep.c
Normal 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);
|
||||
}
|
Reference in New Issue
Block a user