mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-08-26 21:44:59 +00:00
userspace: Rewrite everything
Everything. Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
26
Userspace/libc/src/std/assert.c
Normal file
26
Userspace/libc/src/std/assert.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
export void __assert_fail(const char *file, int line, const char *func)
|
||||
{
|
||||
printf("assertion failed: %s:%d:%s\n", file, line, func);
|
||||
abort();
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
#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';
|
||||
}
|
@@ -1,10 +1,212 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h> // For PUBLIC
|
||||
|
||||
int __local_stub_errno = 0;
|
||||
|
||||
PUBLIC int *__errno_location(void)
|
||||
__iptr __check_errno(__iptr status, __iptr err)
|
||||
{
|
||||
return &__local_stub_errno;
|
||||
if (status >= EOK)
|
||||
return status;
|
||||
pthread_self()->CurrentError = status;
|
||||
return err;
|
||||
}
|
||||
|
||||
export int *__errno_location(void)
|
||||
{
|
||||
return &pthread_self()->CurrentError;
|
||||
}
|
||||
|
||||
export char *strerror(int errnum)
|
||||
{
|
||||
if (errnum < 0)
|
||||
errnum = -errnum;
|
||||
|
||||
if (errnum > __ERRNO_MAX)
|
||||
return (char *)"Not a valid error number";
|
||||
|
||||
switch (errnum)
|
||||
{
|
||||
case EOK:
|
||||
return (char *)"No error";
|
||||
case E2BIG:
|
||||
return (char *)"Argument list too long";
|
||||
case EACCES:
|
||||
return (char *)"Permission denied";
|
||||
case EADDRINUSE:
|
||||
return (char *)"Address in use";
|
||||
case EADDRNOTAVAIL:
|
||||
return (char *)"Address not available";
|
||||
case EAFNOSUPPORT:
|
||||
return (char *)"Address family not supported";
|
||||
case EAGAIN:
|
||||
return (char *)"Resource unavailable, try again";
|
||||
case EALREADY:
|
||||
return (char *)"Connection already in progress";
|
||||
case EBADF:
|
||||
return (char *)"Bad file descriptor";
|
||||
case EBADMSG:
|
||||
return (char *)"Bad message";
|
||||
case EBUSY:
|
||||
return (char *)"Device or resource busy";
|
||||
case ECANCELED:
|
||||
return (char *)"Operation canceled";
|
||||
case ECHILD:
|
||||
return (char *)"No child processes";
|
||||
case ECONNABORTED:
|
||||
return (char *)"Connection aborted";
|
||||
case ECONNREFUSED:
|
||||
return (char *)"Connection refused";
|
||||
case ECONNRESET:
|
||||
return (char *)"Connection reset";
|
||||
case EDEADLK:
|
||||
return (char *)"Resource deadlock would occur";
|
||||
case EDESTADDRREQ:
|
||||
return (char *)"Destination address required";
|
||||
case EDOM:
|
||||
return (char *)"Mathematics argument out of domain of function";
|
||||
case EDQUOT:
|
||||
return (char *)"Reserved";
|
||||
case EEXIST:
|
||||
return (char *)"File exists";
|
||||
case EFAULT:
|
||||
return (char *)"Bad address";
|
||||
case EFBIG:
|
||||
return (char *)"File too large";
|
||||
case EHOSTUNREACH:
|
||||
return (char *)"Host is unreachable";
|
||||
case EIDRM:
|
||||
return (char *)"Identifier removed";
|
||||
case EILSEQ:
|
||||
return (char *)"Illegal byte sequence";
|
||||
case EINPROGRESS:
|
||||
return (char *)"Operation in progress";
|
||||
case EINTR:
|
||||
return (char *)"Interrupted function";
|
||||
case EINVAL:
|
||||
return (char *)"Invalid argument";
|
||||
case EIO:
|
||||
return (char *)"I/O error";
|
||||
case EISCONN:
|
||||
return (char *)"Socket is connected";
|
||||
case EISDIR:
|
||||
return (char *)"Is a directory";
|
||||
case ELOOP:
|
||||
return (char *)"Too many levels of symbolic links";
|
||||
case EMFILE:
|
||||
return (char *)"File descriptor value too large";
|
||||
case EMLINK:
|
||||
return (char *)"Too many links";
|
||||
case EMSGSIZE:
|
||||
return (char *)"Message too large";
|
||||
case EMULTIHOP:
|
||||
return (char *)"Reserved";
|
||||
case ENAMETOOLONG:
|
||||
return (char *)"Filename too long";
|
||||
case ENETDOWN:
|
||||
return (char *)"Network is down";
|
||||
case ENETRESET:
|
||||
return (char *)"Connection aborted by network";
|
||||
case ENETUNREACH:
|
||||
return (char *)"Network unreachable";
|
||||
case ENFILE:
|
||||
return (char *)"Too many files open in system";
|
||||
case ENOBUFS:
|
||||
return (char *)"No buffer space available";
|
||||
case ENODATA:
|
||||
return (char *)"No message available on the STREAM head read queue";
|
||||
case ENODEV:
|
||||
return (char *)"No such device";
|
||||
case ENOENT:
|
||||
return (char *)"No such file or directory";
|
||||
case ENOEXEC:
|
||||
return (char *)"Executable file format error";
|
||||
case ENOLCK:
|
||||
return (char *)"No locks available";
|
||||
case ENOLINK:
|
||||
return (char *)"Reserved";
|
||||
case ENOMEM:
|
||||
return (char *)"Not enough space";
|
||||
case ENOMSG:
|
||||
return (char *)"No message of the desired type";
|
||||
case ENOPROTOOPT:
|
||||
return (char *)"Protocol not available";
|
||||
case ENOSPC:
|
||||
return (char *)"No space left on device";
|
||||
case ENOSR:
|
||||
return (char *)"No STREAM resources";
|
||||
case ENOSTR:
|
||||
return (char *)"Not a STREAM";
|
||||
case ENOSYS:
|
||||
return (char *)"Functionality not supported";
|
||||
case ENOTCONN:
|
||||
return (char *)"The socket is not connected";
|
||||
case ENOTDIR:
|
||||
return (char *)"Not a directory or a symbolic link to a directory";
|
||||
case ENOTEMPTY:
|
||||
return (char *)"Directory not empty";
|
||||
case ENOTRECOVERABLE:
|
||||
return (char *)"State not recoverable";
|
||||
case ENOTSOCK:
|
||||
return (char *)"Not a socket";
|
||||
case ENOTSUP:
|
||||
return (char *)"Not supported";
|
||||
case ENOTTY:
|
||||
return (char *)"Inappropriate I/O control operation";
|
||||
case ENXIO:
|
||||
return (char *)"No such device or address";
|
||||
case EOPNOTSUPP:
|
||||
return (char *)"Operation not supported on socket";
|
||||
case EOVERFLOW:
|
||||
return (char *)"Value too large to be stored in data type";
|
||||
case EOWNERDEAD:
|
||||
return (char *)"Previous owner died";
|
||||
case EPERM:
|
||||
return (char *)"Operation not permitted";
|
||||
case EPIPE:
|
||||
return (char *)"Broken pipe";
|
||||
case EPROTO:
|
||||
return (char *)"Protocol error";
|
||||
case EPROTONOSUPPORT:
|
||||
return (char *)"Protocol not supported";
|
||||
case EPROTOTYPE:
|
||||
return (char *)"Protocol wrong type for socket";
|
||||
case ERANGE:
|
||||
return (char *)"Result too large";
|
||||
case EROFS:
|
||||
return (char *)"Read-only file system";
|
||||
case ESPIPE:
|
||||
return (char *)"Invalid seek";
|
||||
case ESRCH:
|
||||
return (char *)"No such process";
|
||||
case ESTALE:
|
||||
return (char *)"Reserved";
|
||||
case ETIME:
|
||||
return (char *)"Stream ioctl() timeout";
|
||||
case ETIMEDOUT:
|
||||
return (char *)"Connection timed out";
|
||||
case ETXTBSY:
|
||||
return (char *)"Text file busy";
|
||||
case EWOULDBLOCK:
|
||||
return (char *)"Operation would block";
|
||||
case EXDEV:
|
||||
return (char *)"Cross-device link";
|
||||
default:
|
||||
return (char *)"Unknown error";
|
||||
}
|
||||
}
|
||||
|
@@ -1,132 +0,0 @@
|
||||
#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;
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <fennix/syscall.h>
|
||||
|
||||
#include <sys/types.h> // For PUBLIC
|
||||
|
||||
PUBLIC int fgetc(FILE *stream)
|
||||
{
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
#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); }
|
@@ -1,87 +0,0 @@
|
||||
#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;
|
||||
}
|
121
Userspace/libc/src/std/pthread.c
Normal file
121
Userspace/libc/src/std/pthread.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
export int pthread_attr_destroy(pthread_attr_t *);
|
||||
export int pthread_attr_getdetachstate(const pthread_attr_t *, int *);
|
||||
export int pthread_attr_getguardsize(const pthread_attr_t *, size_t *);
|
||||
export int pthread_attr_getinheritsched(const pthread_attr_t *, int *);
|
||||
export int pthread_attr_getschedparam(const pthread_attr_t *, struct sched_param *);
|
||||
export int pthread_attr_getschedpolicy(const pthread_attr_t *, int *);
|
||||
export int pthread_attr_getscope(const pthread_attr_t *, int *);
|
||||
export int pthread_attr_getstackaddr(const pthread_attr_t *, void **);
|
||||
export int pthread_attr_getstacksize(const pthread_attr_t *, size_t *);
|
||||
export int pthread_attr_init(pthread_attr_t *);
|
||||
export int pthread_attr_setdetachstate(pthread_attr_t *, int);
|
||||
export int pthread_attr_setguardsize(pthread_attr_t *, size_t);
|
||||
export int pthread_attr_setinheritsched(pthread_attr_t *, int);
|
||||
export int pthread_attr_setschedparam(pthread_attr_t *, const struct sched_param *);
|
||||
export int pthread_attr_setschedpolicy(pthread_attr_t *, int);
|
||||
export int pthread_attr_setscope(pthread_attr_t *, int);
|
||||
export int pthread_attr_setstackaddr(pthread_attr_t *, void *);
|
||||
export int pthread_attr_setstacksize(pthread_attr_t *, size_t);
|
||||
export int pthread_cancel(pthread_t);
|
||||
export void pthread_cleanup_push(void (*)(void *), void *);
|
||||
export void pthread_cleanup_pop(int);
|
||||
export int pthread_cond_broadcast(pthread_cond_t *);
|
||||
export int pthread_cond_destroy(pthread_cond_t *);
|
||||
export int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *);
|
||||
export int pthread_cond_signal(pthread_cond_t *);
|
||||
export int pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, const struct timespec *);
|
||||
export int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
|
||||
export int pthread_condattr_destroy(pthread_condattr_t *);
|
||||
export int pthread_condattr_getpshared(const pthread_condattr_t *, int *);
|
||||
export int pthread_condattr_init(pthread_condattr_t *);
|
||||
export int pthread_condattr_setpshared(pthread_condattr_t *, int);
|
||||
export int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *);
|
||||
export int pthread_detach(pthread_t);
|
||||
export int pthread_equal(pthread_t, pthread_t);
|
||||
export void pthread_exit(void *);
|
||||
export int pthread_getconcurrency(void);
|
||||
export int pthread_getschedparam(pthread_t, int *, struct sched_param *);
|
||||
export void *pthread_getspecific(pthread_key_t);
|
||||
export int pthread_join(pthread_t, void **);
|
||||
export int pthread_key_create(pthread_key_t *, void (*)(void *));
|
||||
export int pthread_key_delete(pthread_key_t);
|
||||
export int pthread_mutex_destroy(pthread_mutex_t *);
|
||||
export int pthread_mutex_getprioceiling(const pthread_mutex_t *, int *);
|
||||
export int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
|
||||
|
||||
export int pthread_mutex_lock(pthread_mutex_t *mutex)
|
||||
{
|
||||
if (mutex->locked)
|
||||
return EBUSY;
|
||||
mutex->locked = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
export int pthread_mutex_setprioceiling(pthread_mutex_t *, int, int *);
|
||||
export int pthread_mutex_trylock(pthread_mutex_t *);
|
||||
|
||||
export int pthread_mutex_unlock(pthread_mutex_t *mutex)
|
||||
{
|
||||
if (!mutex->locked)
|
||||
return EPERM;
|
||||
mutex->locked = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
export int pthread_mutexattr_destroy(pthread_mutexattr_t *);
|
||||
export int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *, int *);
|
||||
export int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *, int *);
|
||||
export int pthread_mutexattr_getpshared(const pthread_mutexattr_t *, int *);
|
||||
export int pthread_mutexattr_gettype(const pthread_mutexattr_t *, int *);
|
||||
export int pthread_mutexattr_init(pthread_mutexattr_t *);
|
||||
export int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int);
|
||||
export int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int);
|
||||
export int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
|
||||
export int pthread_mutexattr_settype(pthread_mutexattr_t *, int);
|
||||
export int pthread_once(pthread_once_t *, void (*)(void));
|
||||
export int pthread_rwlock_destroy(pthread_rwlock_t *);
|
||||
export int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *);
|
||||
export int pthread_rwlock_rdlock(pthread_rwlock_t *);
|
||||
export int pthread_rwlock_tryrdlock(pthread_rwlock_t *);
|
||||
export int pthread_rwlock_trywrlock(pthread_rwlock_t *);
|
||||
export int pthread_rwlock_unlock(pthread_rwlock_t *);
|
||||
export int pthread_rwlock_wrlock(pthread_rwlock_t *);
|
||||
export int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
|
||||
export int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *, int *);
|
||||
export int pthread_rwlockattr_init(pthread_rwlockattr_t *);
|
||||
export int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int);
|
||||
|
||||
export pthread_t pthread_self(void)
|
||||
{
|
||||
pthread_t tid;
|
||||
__asm__ __volatile__("mov %%fs:0, %0"
|
||||
: "=r"(tid));
|
||||
return tid;
|
||||
}
|
||||
|
||||
export int pthread_setcancelstate(int, int *);
|
||||
export int pthread_setcanceltype(int, int *);
|
||||
export int pthread_setconcurrency(int);
|
||||
export int pthread_setschedparam(pthread_t, int, const struct sched_param *);
|
||||
export int pthread_setspecific(pthread_key_t, const void *);
|
||||
export void pthread_testcancel(void);
|
47
Userspace/libc/src/std/signal.c
Normal file
47
Userspace/libc/src/std/signal.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
export int kill(pid_t pid, int sig)
|
||||
{
|
||||
return syscall2(SYS_KILL, pid, sig);
|
||||
}
|
||||
|
||||
export int killpg(pid_t, int);
|
||||
export void psiginfo(const siginfo_t *, const char *);
|
||||
export void psignal(int, const char *);
|
||||
export int pthread_kill(pthread_t, int);
|
||||
export int pthread_sigmask(int, const sigset_t *restrict, sigset_t *restrict);
|
||||
export int raise(int);
|
||||
export int sig2str(int, char *);
|
||||
export int sigaction(int, const struct sigaction *restrict, struct sigaction *restrict);
|
||||
export int sigaddset(sigset_t *, int);
|
||||
export int sigaltstack(const stack_t *restrict, stack_t *restrict);
|
||||
export int sigdelset(sigset_t *, int);
|
||||
export int sigemptyset(sigset_t *);
|
||||
export int sigfillset(sigset_t *);
|
||||
export int sigismember(const sigset_t *, int);
|
||||
export void (*signal(int, void (*)(int)))(int);
|
||||
export int sigpending(sigset_t *);
|
||||
export int sigprocmask(int, const sigset_t *restrict, sigset_t *restrict);
|
||||
export int sigqueue(pid_t, int, union sigval);
|
||||
export int sigsuspend(const sigset_t *);
|
||||
export int sigtimedwait(const sigset_t *restrict, siginfo_t *restrict, const struct timespec *restrict);
|
||||
export int sigwait(const sigset_t *restrict, int *restrict);
|
||||
export int sigwaitinfo(const sigset_t *restrict, siginfo_t *restrict);
|
||||
export int str2sig(const char *restrict, int *restrict);
|
@@ -1,17 +0,0 @@
|
||||
#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[])
|
||||
{
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
#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)
|
||||
{
|
||||
}
|
343
Userspace/libc/src/std/stdio.c
Normal file
343
Userspace/libc/src/std/stdio.c
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include "../print/printf.h"
|
||||
|
||||
struct _IO_FILE *_i_open_files[256];
|
||||
|
||||
export FILE *stdin;
|
||||
export FILE *stdout;
|
||||
export FILE *stderr;
|
||||
|
||||
void __init_stdio(void)
|
||||
{
|
||||
stdin = malloc(sizeof(FILE));
|
||||
stdin->fd = 0;
|
||||
stdin->buffer = malloc(4096);
|
||||
stdin->buffer_size = 4096;
|
||||
stdin->buffer_pos = 0;
|
||||
stdin->flags = _i_READ;
|
||||
stdin->error = 0;
|
||||
stdin->eof = 0;
|
||||
|
||||
stdout = malloc(sizeof(FILE));
|
||||
stdout->fd = 1;
|
||||
stdout->buffer = malloc(4096);
|
||||
stdout->buffer_size = 4096;
|
||||
stdout->buffer_pos = 0;
|
||||
stdout->flags = _i_WRITE;
|
||||
stdout->error = 0;
|
||||
stdout->eof = 0;
|
||||
|
||||
stderr = malloc(sizeof(FILE));
|
||||
stderr->fd = 2;
|
||||
stderr->buffer = malloc(4096);
|
||||
stderr->buffer_size = 4096;
|
||||
stderr->buffer_pos = 0;
|
||||
stderr->flags = _i_WRITE;
|
||||
stderr->error = 0;
|
||||
stderr->eof = 0;
|
||||
|
||||
_i_open_files[0] = stdin;
|
||||
_i_open_files[1] = stdout;
|
||||
_i_open_files[2] = stderr;
|
||||
}
|
||||
|
||||
export void clearerr(FILE *);
|
||||
export char *ctermid(char *);
|
||||
export int dprintf(int, const char *restrict, ...);
|
||||
|
||||
export int fclose(FILE *stream)
|
||||
{
|
||||
if (!stream)
|
||||
return EOF;
|
||||
|
||||
if (stream->buffer)
|
||||
free(stream->buffer);
|
||||
|
||||
call_close(stream->fd);
|
||||
_i_open_files[stream->fd] = NULL;
|
||||
free(stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
export FILE *fdopen(int, const char *);
|
||||
export int feof(FILE *);
|
||||
export int ferror(FILE *);
|
||||
|
||||
export int fflush(FILE *stream)
|
||||
{
|
||||
if (!stream)
|
||||
return EOF;
|
||||
|
||||
if (stream->flags & _i_WRITE)
|
||||
{
|
||||
if (stream->buffer_pos > 0)
|
||||
{
|
||||
ssize_t written = call_write(stream->fd, stream->buffer, stream->buffer_pos);
|
||||
if (written < 0)
|
||||
{
|
||||
stream->error = 1;
|
||||
return EOF;
|
||||
}
|
||||
stream->buffer_pos = 0;
|
||||
}
|
||||
}
|
||||
else if (stream->flags & _i_READ)
|
||||
{
|
||||
stream->buffer_pos = 0;
|
||||
stream->buffer_size = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
export int fgetc(FILE *);
|
||||
export int fgetpos(FILE *restrict, fpos_t *restrict);
|
||||
export char *fgets(char *restrict, int, FILE *restrict);
|
||||
export int fileno(FILE *);
|
||||
export void flockfile(FILE *);
|
||||
export FILE *fmemopen(void *restrict, size_t, const char *restrict);
|
||||
|
||||
export FILE *fopen(const char *restrict pathname, const char *restrict mode)
|
||||
{
|
||||
int flags = 0;
|
||||
mode_t perm = 0;
|
||||
|
||||
if (strcmp(mode, "r") == 0)
|
||||
flags = __SYS_O_RDONLY;
|
||||
else if (strcmp(mode, "r+") == 0)
|
||||
flags = __SYS_O_RDWR;
|
||||
else if (strcmp(mode, "w") == 0)
|
||||
{
|
||||
flags = __SYS_O_WRONLY | __SYS_O_CREAT | __SYS_O_TRUNC;
|
||||
perm = 0644;
|
||||
}
|
||||
else if (strcmp(mode, "w+") == 0)
|
||||
{
|
||||
flags = __SYS_O_RDWR | __SYS_O_CREAT | __SYS_O_TRUNC;
|
||||
perm = 0644;
|
||||
}
|
||||
else if (strcmp(mode, "a") == 0)
|
||||
{
|
||||
flags = __SYS_O_WRONLY | __SYS_O_CREAT | __SYS_O_APPEND;
|
||||
perm = 0644;
|
||||
}
|
||||
else if (strcmp(mode, "a+") == 0)
|
||||
{
|
||||
flags = __SYS_O_RDWR | __SYS_O_CREAT | __SYS_O_APPEND;
|
||||
perm = 0644;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
|
||||
int fd = call_open(pathname, flags, perm);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
FILE *file = malloc(sizeof(FILE));
|
||||
if (!file)
|
||||
return NULL;
|
||||
|
||||
file->fd = fd;
|
||||
file->buffer = malloc(4096);
|
||||
file->buffer_size = 4096;
|
||||
file->buffer_pos = 0;
|
||||
file->flags = flags;
|
||||
file->error = 0;
|
||||
file->eof = 0;
|
||||
|
||||
_i_open_files[fd] = file;
|
||||
return file;
|
||||
}
|
||||
|
||||
export int fprintf(FILE *restrict, const char *restrict, ...);
|
||||
|
||||
export int fputc(int c, FILE *stream)
|
||||
{
|
||||
if (!stream || !(stream->flags & _i_WRITE))
|
||||
return EOF;
|
||||
|
||||
stream->buffer[stream->buffer_pos++] = (char)c;
|
||||
|
||||
if (stream->buffer_pos >= stream->buffer_size)
|
||||
{
|
||||
if (fflush(stream) == EOF)
|
||||
return EOF;
|
||||
}
|
||||
|
||||
return (unsigned char)c;
|
||||
}
|
||||
|
||||
export int fputs(const char *restrict s, FILE *restrict stream)
|
||||
{
|
||||
if (!stream || !(stream->flags & _i_WRITE))
|
||||
return EOF;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
if (fputc(*s++, stream) == EOF)
|
||||
return EOF;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
export size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream)
|
||||
{
|
||||
size_t total_bytes = size * nitems;
|
||||
size_t bytes_read = 0;
|
||||
|
||||
while (bytes_read < total_bytes)
|
||||
{
|
||||
if (stream->buffer_pos >= stream->buffer_size)
|
||||
{
|
||||
int res = call_read(stream->fd, stream->buffer, stream->buffer_size);
|
||||
if (res <= 0)
|
||||
{
|
||||
if (res == 0)
|
||||
stream->eof = 1;
|
||||
else
|
||||
stream->error = 1;
|
||||
break;
|
||||
}
|
||||
stream->buffer_pos = 0;
|
||||
stream->buffer_size = res;
|
||||
}
|
||||
|
||||
size_t bytes_to_copy = total_bytes - bytes_read;
|
||||
size_t available = stream->buffer_size - stream->buffer_pos;
|
||||
if (bytes_to_copy > available)
|
||||
bytes_to_copy = available;
|
||||
|
||||
memcpy((char *)ptr + bytes_read, stream->buffer + stream->buffer_pos, bytes_to_copy);
|
||||
stream->buffer_pos += bytes_to_copy;
|
||||
bytes_read += bytes_to_copy;
|
||||
}
|
||||
|
||||
return bytes_read / size;
|
||||
}
|
||||
|
||||
export FILE *freopen(const char *restrict, const char *restrict, FILE *restrict);
|
||||
export int fscanf(FILE *restrict, const char *restrict, ...);
|
||||
|
||||
export int fseek(FILE *stream, long offset, int whence)
|
||||
{
|
||||
int res = call_seek(stream->fd, offset, whence);
|
||||
if (res < 0)
|
||||
{
|
||||
stream->error = 1;
|
||||
return EOF;
|
||||
}
|
||||
stream->buffer_pos = 0;
|
||||
stream->buffer_size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
export int fseeko(FILE *, off_t, int);
|
||||
export int fsetpos(FILE *, const fpos_t *);
|
||||
|
||||
export long ftell(FILE *stream)
|
||||
{
|
||||
return call_tell(stream->fd);
|
||||
}
|
||||
|
||||
export off_t ftello(FILE *);
|
||||
export int ftrylockfile(FILE *);
|
||||
export void funlockfile(FILE *);
|
||||
|
||||
export size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream)
|
||||
{
|
||||
size_t total_bytes = size * nitems;
|
||||
size_t bytes_written = 0;
|
||||
|
||||
while (bytes_written < total_bytes)
|
||||
{
|
||||
size_t bytes_to_copy = total_bytes - bytes_written;
|
||||
size_t space_available = stream->buffer_size - stream->buffer_pos;
|
||||
|
||||
if (bytes_to_copy > space_available)
|
||||
bytes_to_copy = space_available;
|
||||
|
||||
memcpy(stream->buffer + stream->buffer_pos, (const char *)ptr + bytes_written, bytes_to_copy);
|
||||
stream->buffer_pos += bytes_to_copy;
|
||||
bytes_written += bytes_to_copy;
|
||||
|
||||
if (stream->buffer_pos == stream->buffer_size)
|
||||
{
|
||||
if (call_write(stream->fd, stream->buffer, stream->buffer_size) != stream->buffer_size)
|
||||
{
|
||||
stream->error = 1;
|
||||
break;
|
||||
}
|
||||
stream->buffer_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return bytes_written / size;
|
||||
}
|
||||
|
||||
export int getc(FILE *);
|
||||
export int getchar(void);
|
||||
export int getc_unlocked(FILE *);
|
||||
export int getchar_unlocked(void);
|
||||
export ssize_t getdelim(char **restrict, size_t *restrict, int, FILE *restrict);
|
||||
export ssize_t getline(char **restrict, size_t *restrict, FILE *restrict);
|
||||
export FILE *open_memstream(char **, size_t *);
|
||||
export int pclose(FILE *);
|
||||
export void perror(const char *);
|
||||
export FILE *popen(const char *, const char *);
|
||||
|
||||
export int printf(const char *restrict format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int ret = vprintf_(format, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
export int putc(int c, FILE *stream) { return fputc(c, stream); }
|
||||
export int putchar(int c) { return putc(c, stdout); }
|
||||
export int putc_unlocked(int c, FILE *stream) { return fputc(c, stream); }
|
||||
export int putchar_unlocked(int c) { return putc_unlocked(c, stdout); }
|
||||
export int puts(const char *s) { return fputs(s, stdout); }
|
||||
|
||||
export int remove(const char *);
|
||||
export int rename(const char *, const char *);
|
||||
export int renameat(int, const char *, int, const char *);
|
||||
export void rewind(FILE *);
|
||||
export int scanf(const char *restrict, ...);
|
||||
export void setbuf(FILE *restrict, char *restrict);
|
||||
export int setvbuf(FILE *restrict, char *restrict, int, size_t);
|
||||
export int snprintf(char *restrict, size_t, const char *restrict, ...);
|
||||
export int sprintf(char *restrict, const char *restrict, ...);
|
||||
export int sscanf(const char *restrict, const char *restrict, ...);
|
||||
export FILE *tmpfile(void);
|
||||
export char *tmpnam(char *);
|
||||
export int ungetc(int, FILE *);
|
||||
export int vdprintf(int, const char *restrict, va_list);
|
||||
export int vfprintf(FILE *restrict, const char *restrict, va_list);
|
||||
export int vfscanf(FILE *restrict, const char *restrict, va_list);
|
||||
export int vprintf(const char *restrict, va_list);
|
||||
export int vscanf(const char *restrict, va_list);
|
||||
export int vsnprintf(char *restrict, size_t, const char *restrict, va_list);
|
||||
export int vsprintf(char *restrict, const char *restrict, va_list);
|
||||
export int vsscanf(const char *restrict, const char *restrict, va_list);
|
105
Userspace/libc/src/std/stdlib.c
Normal file
105
Userspace/libc/src/std/stdlib.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "../mem/liballoc_1_1.h"
|
||||
|
||||
#define MAX_ATEXIT_FUNCS 32
|
||||
typedef void (*atexit_func_t)(void);
|
||||
static atexit_func_t __atexit_funcs[MAX_ATEXIT_FUNCS];
|
||||
static int __num_atexit_funcs = 0;
|
||||
|
||||
export long a64l(const char *);
|
||||
export _Noreturn void abort(void)
|
||||
{
|
||||
kill(getpid(), SIGABRT);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
export int abs(int);
|
||||
|
||||
export int atexit(void (*func)(void))
|
||||
{
|
||||
if (__num_atexit_funcs >= MAX_ATEXIT_FUNCS)
|
||||
return -1;
|
||||
__atexit_funcs[__num_atexit_funcs++] = func;
|
||||
return 0;
|
||||
}
|
||||
|
||||
export double atof(const char *);
|
||||
export int atoi(const char *);
|
||||
export long int atol(const char *);
|
||||
export void *bsearch(const void *, const void *, size_t, size_t, int (*)(const void *, const void *));
|
||||
export void *calloc(size_t, size_t);
|
||||
export div_t div(int, int);
|
||||
export double drand48(void);
|
||||
export char *ecvt(double, int, int *, int *);
|
||||
export double erand48(unsigned short int[3]);
|
||||
|
||||
export void exit(int status)
|
||||
{
|
||||
for (int i = __num_atexit_funcs - 1; i >= 0; --i)
|
||||
__atexit_funcs[i]();
|
||||
_exit(status);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
export char *fcvt(double, int, int *, int *);
|
||||
export void free(void *ptr) { return PREFIX(free)(ptr); }
|
||||
export char *gcvt(double, int, char *);
|
||||
export char *getenv(const char *);
|
||||
export int getsubopt(char **, char *const *, char **);
|
||||
export int grantpt(int);
|
||||
export char *initstate(unsigned int, char *, size_t);
|
||||
export long int jrand48(unsigned short int[3]);
|
||||
export char *l64a(long);
|
||||
export long int labs(long int);
|
||||
export void lcong48(unsigned short int[7]);
|
||||
export ldiv_t ldiv(long int, long int);
|
||||
export long int lrand48(void);
|
||||
export void *malloc(size_t size) { return PREFIX(malloc)(size); }
|
||||
export int mblen(const char *, size_t);
|
||||
export size_t mbstowcs(wchar_t *, const char *, size_t);
|
||||
export int mbtowc(wchar_t *, const char *, size_t);
|
||||
export char *mktemp(char *);
|
||||
export int mkstemp(char *);
|
||||
export long int mrand48(void);
|
||||
export long int nrand48(unsigned short int[3]);
|
||||
export char *ptsname(int);
|
||||
export int putenv(char *);
|
||||
export void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
|
||||
export int rand(void);
|
||||
export int rand_r(unsigned int *);
|
||||
export long random(void);
|
||||
export void *realloc(void *, size_t);
|
||||
export char *realpath(const char *, char *);
|
||||
export unsigned short int seed48(unsigned short int[3]);
|
||||
export void setkey(const char *);
|
||||
export char *setstate(const char *);
|
||||
export void srand(unsigned int);
|
||||
export void srand48(long int);
|
||||
export void srandom(unsigned);
|
||||
export double strtod(const char *, char **);
|
||||
export long int strtol(const char *, char **, int);
|
||||
export unsigned long int strtoul(const char *, char **, int);
|
||||
export int system(const char *);
|
||||
export int ttyslot(void);
|
||||
export int unlockpt(int);
|
||||
export void *valloc(size_t);
|
||||
export size_t wcstombs(char *, const wchar_t *, size_t);
|
||||
export int wctomb(char *, wchar_t);
|
86
Userspace/libc/src/std/string.c
Normal file
86
Userspace/libc/src/std/string.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
export void *memccpy(void *restrict, const void *restrict, int, size_t);
|
||||
export void *memchr(const void *, int, size_t);
|
||||
export int memcmp(const void *, const void *, size_t);
|
||||
|
||||
export void *memcpy(void *restrict s1, const void *restrict s2, size_t n)
|
||||
{
|
||||
unsigned char *dest = (unsigned char *)s1;
|
||||
const unsigned char *src = (const unsigned char *)s2;
|
||||
|
||||
while (n >= sizeof(unsigned long))
|
||||
{
|
||||
*(unsigned long *)dest = *(const unsigned long *)src;
|
||||
dest += sizeof(unsigned long);
|
||||
src += sizeof(unsigned long);
|
||||
n -= sizeof(unsigned long);
|
||||
}
|
||||
|
||||
while (n--)
|
||||
*dest++ = *src++;
|
||||
return s1;
|
||||
}
|
||||
|
||||
export void *memmem(const void *, size_t, const void *, size_t);
|
||||
export void *memmove(void *, const void *, size_t);
|
||||
export void *memset(void *, int, size_t);
|
||||
export char *stpcpy(char *restrict, const char *restrict);
|
||||
export char *stpncpy(char *restrict, const char *restrict, size_t);
|
||||
export char *strcat(char *restrict, const char *restrict);
|
||||
export char *strchr(const char *, int);
|
||||
|
||||
export int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
while (*s1 && (*s1 == *s2))
|
||||
{
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
|
||||
return *(unsigned char *)s1 - *(unsigned char *)s2;
|
||||
}
|
||||
|
||||
export int strcoll(const char *, const char *);
|
||||
export int strcoll_l(const char *, const char *, locale_t);
|
||||
export char *strcpy(char *restrict, const char *restrict);
|
||||
export size_t strcspn(const char *, const char *);
|
||||
export char *strdup(const char *);
|
||||
export char *strerror(int);
|
||||
export char *strerror_l(int, locale_t);
|
||||
export int strerror_r(int, char *, size_t);
|
||||
export size_t strlcat(char *restrict, const char *restrict, size_t);
|
||||
export size_t strlcpy(char *restrict, const char *restrict, size_t);
|
||||
export size_t strlen(const char *);
|
||||
export char *strncat(char *restrict, const char *restrict, size_t);
|
||||
export int strncmp(const char *, const char *, size_t);
|
||||
export char *strncpy(char *restrict, const char *restrict, size_t);
|
||||
export char *strndup(const char *, size_t);
|
||||
export size_t strnlen(const char *, size_t);
|
||||
export char *strpbrk(const char *, const char *);
|
||||
export char *strrchr(const char *, int);
|
||||
export char *strsignal(int);
|
||||
export size_t strspn(const char *, const char *);
|
||||
export char *strstr(const char *, const char *);
|
||||
export char *strtok(char *restrict, const char *restrict);
|
||||
export char *strtok_r(char *restrict, const char *restrict, char **restrict);
|
||||
export size_t strxfrm(char *restrict, const char *restrict, size_t);
|
||||
export size_t strxfrm_l(char *restrict, const char *restrict, size_t, locale_t);
|
@@ -1,346 +0,0 @@
|
||||
#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;
|
||||
}
|
@@ -1,125 +0,0 @@
|
||||
#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;
|
||||
}
|
49
Userspace/libc/src/std/sys/mman.c
Normal file
49
Userspace/libc/src/std/sys/mman.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include <errno.h>
|
||||
|
||||
export int mlock(const void *, size_t);
|
||||
export int mlockall(int);
|
||||
|
||||
export void *mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
|
||||
{
|
||||
return (void *)__check_errno((__iptr)call_mmap(addr, len, prot, flags, fildes, off), (__iptr)MAP_FAILED);
|
||||
}
|
||||
|
||||
export int mprotect(void *addr, size_t len, int prot)
|
||||
{
|
||||
return __check_errno(call_mprotect(addr, len, prot), -1);
|
||||
}
|
||||
|
||||
export int msync(void *, size_t, int);
|
||||
export int munlock(const void *, size_t);
|
||||
export int munlockall(void);
|
||||
|
||||
export int munmap(void *addr, size_t len)
|
||||
{
|
||||
return __check_errno(call_munmap(addr, len), -1);
|
||||
}
|
||||
|
||||
export int posix_madvise(void *, size_t, int);
|
||||
export int posix_mem_offset(const void *restrict, size_t, off_t *restrict, size_t *restrict, int *restrict);
|
||||
export int posix_typed_mem_get_info(int, struct posix_typed_mem_info *);
|
||||
export int posix_typed_mem_open(const char *, int, int);
|
||||
export int shm_open(const char *, int, mode_t);
|
||||
export int shm_unlink(const char *);
|
@@ -1,14 +0,0 @@
|
||||
#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)
|
||||
{
|
||||
}
|
@@ -1,18 +0,0 @@
|
||||
#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;
|
||||
}
|
@@ -1,51 +0,0 @@
|
||||
#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);
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
#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);
|
||||
}
|
112
Userspace/libc/src/std/unistd.c
Normal file
112
Userspace/libc/src/std/unistd.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
This file is part of Fennix C Library.
|
||||
|
||||
Fennix C Library is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix C Library 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix C Library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fennix/syscalls.h>
|
||||
|
||||
export char *optarg;
|
||||
export int optind, opterr, optopt;
|
||||
|
||||
export int access(const char *, int);
|
||||
export unsigned int alarm(unsigned int);
|
||||
export int brk(void *);
|
||||
export int chdir(const char *);
|
||||
export int chroot(const char *);
|
||||
export int chown(const char *, uid_t, gid_t);
|
||||
export int close(int);
|
||||
export size_t confstr(int, char *, size_t);
|
||||
export char *crypt(const char *, const char *);
|
||||
export char *ctermid(char *);
|
||||
export char *cuserid(char *s);
|
||||
export int dup(int);
|
||||
export int dup2(int, int);
|
||||
export void encrypt(char[64], int);
|
||||
export int execl(const char *, const char *, ...);
|
||||
export int execle(const char *, const char *, ...);
|
||||
export int execlp(const char *, const char *, ...);
|
||||
export int execv(const char *, char *const[]);
|
||||
export int execve(const char *, char *const[], char *const[]);
|
||||
export int execvp(const char *, char *const[]);
|
||||
export void _exit(int);
|
||||
export int fchown(int, uid_t, gid_t);
|
||||
export int fchdir(int);
|
||||
export int fdatasync(int);
|
||||
export pid_t fork(void);
|
||||
export long int fpathconf(int, int);
|
||||
export int fsync(int);
|
||||
export int ftruncate(int, off_t);
|
||||
export char *getcwd(char *, size_t);
|
||||
export int getdtablesize(void);
|
||||
export gid_t getegid(void);
|
||||
export uid_t geteuid(void);
|
||||
export gid_t getgid(void);
|
||||
export int getgroups(int, gid_t[]);
|
||||
export long gethostid(void);
|
||||
export char *getlogin(void);
|
||||
export int getlogin_r(char *, size_t);
|
||||
export int getopt(int, char *const[], const char *);
|
||||
|
||||
export int getpagesize(void) { return 0x1000; } /* TODO: getpagesize */
|
||||
|
||||
export char *getpass(const char *);
|
||||
export pid_t getpgid(pid_t);
|
||||
export pid_t getpgrp(void);
|
||||
|
||||
export pid_t getpid(void) { return syscall0(SYS_GETPID); }
|
||||
export pid_t getppid(void) { return syscall0(SYS_GETPPID); }
|
||||
|
||||
export pid_t getsid(pid_t);
|
||||
export uid_t getuid(void);
|
||||
export char *getwd(char *);
|
||||
export int isatty(int);
|
||||
export int lchown(const char *, uid_t, gid_t);
|
||||
export int link(const char *, const char *);
|
||||
export int lockf(int, int, off_t);
|
||||
export off_t lseek(int, off_t, int);
|
||||
export int nice(int);
|
||||
export long int pathconf(const char *, int);
|
||||
export int pause(void);
|
||||
export int pipe(int[2]);
|
||||
export ssize_t pread(int, void *, size_t, off_t);
|
||||
export int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
|
||||
export ssize_t pwrite(int, const void *, size_t, off_t);
|
||||
export ssize_t read(int, void *, size_t);
|
||||
export int readlink(const char *, char *, size_t);
|
||||
export int rmdir(const char *);
|
||||
export void *sbrk(intptr_t);
|
||||
export int setgid(gid_t);
|
||||
export int setpgid(pid_t, pid_t);
|
||||
export pid_t setpgrp(void);
|
||||
export int setregid(gid_t, gid_t);
|
||||
export int setreuid(uid_t, uid_t);
|
||||
export pid_t setsid(void);
|
||||
export int setuid(uid_t);
|
||||
export unsigned int sleep(unsigned int);
|
||||
export void swab(const void *, void *, ssize_t);
|
||||
export int symlink(const char *, const char *);
|
||||
export void sync(void);
|
||||
export long int sysconf(int);
|
||||
export pid_t tcgetpgrp(int);
|
||||
export int tcsetpgrp(int, pid_t);
|
||||
export int truncate(const char *, off_t);
|
||||
export char *ttyname(int);
|
||||
export int ttyname_r(int, char *, size_t);
|
||||
export useconds_t ualarm(useconds_t, useconds_t);
|
||||
export int unlink(const char *);
|
||||
export int usleep(useconds_t);
|
||||
export pid_t vfork(void);
|
||||
export ssize_t write(int, const void *, size_t);
|
Reference in New Issue
Block a user