mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-28 15:34:31 +00:00
userspace/libc: implement std more functions
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
parent
f5a813380b
commit
2f71bccef2
@ -59,7 +59,7 @@ extern "C"
|
||||
#define DT_TMO
|
||||
|
||||
int alphasort(const struct dirent **, const struct dirent **);
|
||||
int closedir(DIR *);
|
||||
int closedir(DIR *dirp);
|
||||
int dirfd(DIR *);
|
||||
DIR *fdopendir(int);
|
||||
DIR *opendir(const char *);
|
||||
|
@ -23,6 +23,8 @@ extern "C"
|
||||
{
|
||||
#endif // __cplusplus
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef struct f_owner_ex
|
||||
{
|
||||
int type; /* Discriminator for pid. */
|
||||
|
@ -90,9 +90,9 @@ extern "C"
|
||||
int feof(FILE *);
|
||||
int ferror(FILE *);
|
||||
int fflush(FILE *stream);
|
||||
int fgetc(FILE *);
|
||||
int fgetc(FILE *stream);
|
||||
int fgetpos(FILE *restrict, fpos_t *restrict);
|
||||
char *fgets(char *restrict, int, FILE *restrict);
|
||||
char *fgets(char *restrict s, int n, FILE *restrict stream);
|
||||
int fileno(FILE *);
|
||||
void flockfile(FILE *);
|
||||
FILE *fmemopen(void *restrict, size_t, const char *restrict);
|
||||
@ -119,7 +119,7 @@ extern "C"
|
||||
ssize_t getline(char **restrict, size_t *restrict, FILE *restrict);
|
||||
FILE *open_memstream(char **, size_t *);
|
||||
int pclose(FILE *);
|
||||
void perror(const char *);
|
||||
void perror(const char *s);
|
||||
FILE *popen(const char *, const char *);
|
||||
int printf(const char *restrict format, ...);
|
||||
int putc(int c, FILE *stream);
|
||||
@ -134,8 +134,8 @@ extern "C"
|
||||
int scanf(const char *restrict, ...);
|
||||
void setbuf(FILE *restrict, char *restrict);
|
||||
int setvbuf(FILE *restrict, char *restrict, int, size_t);
|
||||
int snprintf(char *restrict, size_t, const char *restrict, ...);
|
||||
int sprintf(char *restrict, const char *restrict, ...);
|
||||
int snprintf(char *restrict s, size_t n, const char *restrict format, ...);
|
||||
int sprintf(char *restrict s, const char *restrict format, ...);
|
||||
int sscanf(const char *restrict, const char *restrict, ...);
|
||||
FILE *tmpfile(void);
|
||||
char *tmpnam(char *);
|
||||
|
@ -51,7 +51,7 @@ extern "C"
|
||||
|
||||
long a64l(const char *);
|
||||
void abort(void);
|
||||
int abs(int);
|
||||
int abs(int i);
|
||||
int atexit(void (*func)(void));
|
||||
double atof(const char *);
|
||||
int atoi(const char *);
|
||||
@ -66,7 +66,7 @@ extern "C"
|
||||
char *fcvt(double, int, int *, int *);
|
||||
void free(void *ptr);
|
||||
char *gcvt(double, int, char *);
|
||||
char *getenv(const char *);
|
||||
char *getenv(const char *name);
|
||||
int getsubopt(char **, char *const *, char **);
|
||||
int grantpt(int);
|
||||
char *initstate(unsigned int, char *, size_t);
|
||||
|
@ -36,7 +36,7 @@ extern "C"
|
||||
char *stpcpy(char *restrict, const char *restrict);
|
||||
char *stpncpy(char *restrict, const char *restrict, size_t);
|
||||
char *strcat(char *restrict, const char *restrict);
|
||||
char *strchr(const char *, int);
|
||||
char *strchr(const char *s, int c);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
int strcoll(const char *, const char *);
|
||||
int strcoll_l(const char *, const char *, locale_t);
|
||||
@ -48,19 +48,19 @@ extern "C"
|
||||
int strerror_r(int, char *, size_t);
|
||||
size_t strlcat(char *restrict, const char *restrict, size_t);
|
||||
size_t strlcpy(char *restrict, const char *restrict, size_t);
|
||||
size_t strlen(const char *);
|
||||
size_t strlen(const char *s);
|
||||
char *strncat(char *restrict, const char *restrict, size_t);
|
||||
int strncmp(const char *, const char *, size_t);
|
||||
int strncmp(const char *s1, const char *s2, size_t n);
|
||||
char *strncpy(char *restrict, const char *restrict, size_t);
|
||||
char *strndup(const char *, size_t);
|
||||
size_t strnlen(const char *, size_t);
|
||||
char *strpbrk(const char *, const char *);
|
||||
char *strpbrk(const char *s1, const char *s2);
|
||||
char *strrchr(const char *, int);
|
||||
char *strsignal(int);
|
||||
size_t strspn(const char *, const char *);
|
||||
char *strsignal(int signum);
|
||||
size_t strspn(const char *s1, const char *s2);
|
||||
char *strstr(const char *, const char *);
|
||||
char *strtok(char *restrict, const char *restrict);
|
||||
char *strtok_r(char *restrict, const char *restrict, char **restrict);
|
||||
char *strtok(char *restrict s, const char *restrict sep);
|
||||
char *strtok_r(char *restrict s, const char *restrict sep, char **restrict state);
|
||||
size_t strxfrm(char *restrict, const char *restrict, size_t);
|
||||
size_t strxfrm_l(char *restrict, const char *restrict, size_t, locale_t);
|
||||
|
||||
|
@ -91,8 +91,8 @@ extern "C"
|
||||
int fstatat(int, const char *restrict, struct stat *restrict, int);
|
||||
int futimens(int, const struct timespec[2]);
|
||||
int lstat(const char *restrict, struct stat *restrict);
|
||||
int mkdir(const char *, mode_t);
|
||||
int mkdirat(int, const char *, mode_t);
|
||||
int mkdir(const char *path, mode_t mode);
|
||||
int mkdirat(int fd, const char *path, mode_t mode);
|
||||
int mkfifo(const char *, mode_t);
|
||||
int mkfifoat(int, const char *, mode_t);
|
||||
int mknod(const char *, mode_t, dev_t);
|
||||
|
@ -54,9 +54,9 @@ extern "C"
|
||||
typedef unsigned int id_t;
|
||||
typedef int pid_t;
|
||||
|
||||
pid_t wait(int *);
|
||||
int waitid(idtype_t, id_t, siginfo_t *, int);
|
||||
pid_t waitpid(pid_t, int *, int);
|
||||
pid_t wait(int *stat_loc);
|
||||
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
|
||||
pid_t waitpid(pid_t pid, int *stat_loc, int options);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -57,9 +57,10 @@ extern "C"
|
||||
|
||||
extern char *optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
extern char **environ;
|
||||
|
||||
int access(const char *, int);
|
||||
unsigned int alarm(unsigned int);
|
||||
unsigned int alarm(unsigned int seconds);
|
||||
int brk(void *);
|
||||
int chdir(const char *);
|
||||
int chroot(const char *);
|
||||
@ -72,12 +73,12 @@ extern "C"
|
||||
int dup(int);
|
||||
int dup2(int, int);
|
||||
void encrypt(char[64], int);
|
||||
int execl(const char *, const char *, ...);
|
||||
int execle(const char *, const char *, ...);
|
||||
int execlp(const char *, const char *, ...);
|
||||
int execv(const char *, char *const[]);
|
||||
int execve(const char *, char *const[], char *const[]);
|
||||
int execvp(const char *, char *const[]);
|
||||
int execl(const char *path, const char *arg0, ... /*, (char *)0 */);
|
||||
int execle(const char *path, const char *arg0, ... /*, (char *)0, char *const envp[]*/);
|
||||
int execlp(const char *file, const char *arg0, ... /*, (char *)0 */);
|
||||
int execv(const char *path, char *const argv[]);
|
||||
int execve(const char *path, char *const argv[], char *const envp[]);
|
||||
int execvp(const char *file, char *const argv[]);
|
||||
void _exit(int);
|
||||
int fchown(int, uid_t, gid_t);
|
||||
int fchdir(int);
|
||||
@ -128,7 +129,7 @@ extern "C"
|
||||
int setreuid(uid_t, uid_t);
|
||||
pid_t setsid(void);
|
||||
int setuid(uid_t);
|
||||
unsigned int sleep(unsigned int);
|
||||
unsigned int sleep(unsigned int seconds);
|
||||
void swab(const void *, void *, ssize_t);
|
||||
int symlink(const char *, const char *);
|
||||
void sync(void);
|
||||
|
57
Userspace/libc/src/std/dirent.c
Normal file
57
Userspace/libc/src/std/dirent.c
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
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 <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
export int alphasort(const struct dirent **, const struct dirent **);
|
||||
|
||||
export int closedir(DIR *dirp)
|
||||
{
|
||||
if (!dirp)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fd = dirfd(dirp);
|
||||
if (fd == -1)
|
||||
{
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int result = close(fd);
|
||||
if (result == -1)
|
||||
return -1;
|
||||
|
||||
free(dirp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
export int dirfd(DIR *);
|
||||
export DIR *fdopendir(int);
|
||||
export DIR *opendir(const char *);
|
||||
export ssize_t posix_getdents(int, void *, size_t, int);
|
||||
export struct dirent *readdir(DIR *);
|
||||
export int readdir_r(DIR *restrict, struct dirent *restrict, struct dirent **restrict);
|
||||
export void rewinddir(DIR *);
|
||||
export int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **));
|
||||
export void seekdir(DIR *, long);
|
||||
export long telldir(DIR *);
|
@ -18,6 +18,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include "../print/printf.h"
|
||||
|
||||
@ -109,9 +110,54 @@ export int fflush(FILE *stream)
|
||||
return 0;
|
||||
}
|
||||
|
||||
export int fgetc(FILE *);
|
||||
export int fgetc(FILE *stream)
|
||||
{
|
||||
if (!stream || !(stream->flags & _i_READ))
|
||||
return EOF;
|
||||
|
||||
if (stream->buffer_pos >= stream->buffer_size)
|
||||
{
|
||||
int res = call_read(stream->fd, stream->buffer, 4096);
|
||||
if (res <= 0)
|
||||
{
|
||||
if (res == 0)
|
||||
stream->eof = 1;
|
||||
else
|
||||
stream->error = 1;
|
||||
return EOF;
|
||||
}
|
||||
stream->buffer_pos = 0;
|
||||
stream->buffer_size = res;
|
||||
}
|
||||
|
||||
return (unsigned char)stream->buffer[stream->buffer_pos++];
|
||||
}
|
||||
|
||||
export int fgetpos(FILE *restrict, fpos_t *restrict);
|
||||
export char *fgets(char *restrict, int, FILE *restrict);
|
||||
|
||||
export char *fgets(char *restrict s, int n, FILE *restrict stream)
|
||||
{
|
||||
if (!s || n <= 0 || !stream)
|
||||
return NULL;
|
||||
|
||||
int i = 0;
|
||||
while (i < n - 1)
|
||||
{
|
||||
int c = fgetc(stream);
|
||||
if (c == EOF)
|
||||
{
|
||||
if (i == 0)
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
s[i++] = (char)c;
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
s[i] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
export int fileno(FILE *);
|
||||
export void flockfile(FILE *);
|
||||
export FILE *fmemopen(void *restrict, size_t, const char *restrict);
|
||||
@ -302,7 +348,15 @@ 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 void perror(const char *s)
|
||||
{
|
||||
fputs(s, stderr);
|
||||
fputs(": ", stderr);
|
||||
fputs(strerror(errno), stderr);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
export FILE *popen(const char *, const char *);
|
||||
|
||||
export int printf(const char *restrict format, ...)
|
||||
@ -327,8 +381,25 @@ 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 snprintf(char *restrict s, size_t n, const char *restrict format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int ret = vsnprintf_(s, n, format, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
export int sprintf(char *restrict s, const char *restrict format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int ret = vsprintf_(s, format, args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
|
||||
export int sscanf(const char *restrict, const char *restrict, ...);
|
||||
export FILE *tmpfile(void);
|
||||
export char *tmpnam(char *);
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "../mem/liballoc_1_1.h"
|
||||
|
||||
#define MAX_ATEXIT_FUNCS 32
|
||||
@ -31,7 +32,10 @@ export _Noreturn void abort(void)
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
export int abs(int);
|
||||
export int abs(int i)
|
||||
{
|
||||
return (i < 0) ? -i : i;
|
||||
}
|
||||
|
||||
export int atexit(void (*func)(void))
|
||||
{
|
||||
@ -62,7 +66,18 @@ export void exit(int status)
|
||||
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 char *getenv(const char *name)
|
||||
{
|
||||
for (char **env = environ; *env != 0; ++env)
|
||||
{
|
||||
char *thisEnv = *env;
|
||||
if (strncmp(thisEnv, name, strlen(name)) == 0 && thisEnv[strlen(name)] == '=')
|
||||
return thisEnv + strlen(name) + 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
export int getsubopt(char **, char *const *, char **);
|
||||
export int grantpt(int);
|
||||
export char *initstate(unsigned int, char *, size_t);
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <fennix/syscalls.h>
|
||||
|
||||
export void *memccpy(void *restrict, const void *restrict, int, size_t);
|
||||
export void *memchr(const void *, int, size_t);
|
||||
@ -46,7 +47,19 @@ 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 char *strchr(const char *s, int c)
|
||||
{
|
||||
while (*s)
|
||||
{
|
||||
if (*s == (char)c)
|
||||
return (char *)s;
|
||||
s++;
|
||||
}
|
||||
if (c == '\0')
|
||||
return (char *)s;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
export int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
@ -69,18 +82,171 @@ 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 size_t strlen(const char *s)
|
||||
{
|
||||
const char *start = s;
|
||||
while (*s)
|
||||
s++;
|
||||
return s - start;
|
||||
}
|
||||
|
||||
export char *strncat(char *restrict, const char *restrict, size_t);
|
||||
export int strncmp(const char *, const char *, size_t);
|
||||
|
||||
export int strncmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
while (n--)
|
||||
{
|
||||
if (*s1 != *s2)
|
||||
return *(unsigned char *)s1 - *(unsigned char *)s2;
|
||||
if (*s1 == '\0')
|
||||
return 0;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 *strpbrk(const char *s1, const char *s2)
|
||||
{
|
||||
while (*s1)
|
||||
{
|
||||
const char *s = s2;
|
||||
while (*s)
|
||||
{
|
||||
if (*s1 == *s)
|
||||
return (char *)s1;
|
||||
s++;
|
||||
}
|
||||
s1++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
export char *strrchr(const char *, int);
|
||||
export char *strsignal(int);
|
||||
export size_t strspn(const char *, const char *);
|
||||
|
||||
export char *strsignal(int signum)
|
||||
{
|
||||
switch (signum)
|
||||
{
|
||||
case __SYS_SIGNULL:
|
||||
return "NULL signal";
|
||||
case __SYS_SIGABRT:
|
||||
return "Aborted";
|
||||
case __SYS_SIGALRM:
|
||||
return "Alarm clock";
|
||||
case __SYS_SIGBUS:
|
||||
return "Bus error";
|
||||
case __SYS_SIGCHLD:
|
||||
return "Child status changed";
|
||||
case __SYS_SIGCONT:
|
||||
return "Continued";
|
||||
case __SYS_SIGFPE:
|
||||
return "Arithmetic exception";
|
||||
case __SYS_SIGHUP:
|
||||
return "Hangup";
|
||||
case __SYS_SIGILL:
|
||||
return "Illegal instruction";
|
||||
case __SYS_SIGINT:
|
||||
return "Interrupt";
|
||||
case __SYS_SIGKILL:
|
||||
return "Killed";
|
||||
case __SYS_SIGPIPE:
|
||||
return "Broken pipe";
|
||||
case __SYS_SIGQUIT:
|
||||
return "Quit";
|
||||
case __SYS_SIGSEGV:
|
||||
return "Segmentation fault";
|
||||
case __SYS_SIGSTOP:
|
||||
return "Stopped (signal)";
|
||||
case __SYS_SIGTERM:
|
||||
return "Terminated";
|
||||
case __SYS_SIGTSTP:
|
||||
return "Stopped (user)";
|
||||
case __SYS_SIGTTIN:
|
||||
return "Stopped (tty input)";
|
||||
case __SYS_SIGTTOU:
|
||||
return "Stopped (tty output)";
|
||||
case __SYS_SIGUSR1:
|
||||
return "User defined signal 1";
|
||||
case __SYS_SIGUSR2:
|
||||
return "User defined signal 2";
|
||||
case __SYS_SIGPOLL:
|
||||
return "Pollable event occurred";
|
||||
case __SYS_SIGPROF:
|
||||
return "Profiling timer expired";
|
||||
case __SYS_SIGSYS:
|
||||
return "Bad system call";
|
||||
case __SYS_SIGTRAP:
|
||||
return "Trace/breakpoint trap";
|
||||
case __SYS_SIGURG:
|
||||
return "Urgent I/O condition";
|
||||
case __SYS_SIGVTALRM:
|
||||
return "Virtual timer expired";
|
||||
case __SYS_SIGXCPU:
|
||||
return "CPU time limit exceeded";
|
||||
case __SYS_SIGXFSZ:
|
||||
return "File size limit exceeded";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
export size_t strspn(const char *s1, const char *s2)
|
||||
{
|
||||
const char *p = s1;
|
||||
const char *spanp;
|
||||
char c, sc;
|
||||
|
||||
cont:
|
||||
c = *p++;
|
||||
for (spanp = s2; (sc = *spanp++) != 0;)
|
||||
{
|
||||
if (sc == c)
|
||||
goto cont;
|
||||
}
|
||||
return p - 1 - s1;
|
||||
}
|
||||
|
||||
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 char *strtok(char *restrict s, const char *restrict sep)
|
||||
{
|
||||
static char *last;
|
||||
return strtok_r(s, sep, &last);
|
||||
}
|
||||
|
||||
export char *strtok_r(char *restrict s, const char *restrict sep, char **restrict state)
|
||||
{
|
||||
char *start;
|
||||
char *end;
|
||||
|
||||
if (s == NULL)
|
||||
s = *state;
|
||||
|
||||
s += strspn(s, sep);
|
||||
if (*s == '\0')
|
||||
{
|
||||
*state = s;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
start = s;
|
||||
end = strpbrk(start, sep);
|
||||
if (end)
|
||||
{
|
||||
*end = '\0';
|
||||
*state = end + 1;
|
||||
}
|
||||
else
|
||||
*state = start + strlen(start);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
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);
|
||||
|
47
Userspace/libc/src/std/sys/stat.c
Normal file
47
Userspace/libc/src/std/sys/stat.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 <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
export int chmod(const char *, mode_t);
|
||||
export int fchmod(int, mode_t);
|
||||
export int fchmodat(int, const char *, mode_t, int);
|
||||
export int fstat(int, struct stat *);
|
||||
export int fstatat(int, const char *restrict, struct stat *restrict, int);
|
||||
export int futimens(int, const struct timespec[2]);
|
||||
export int lstat(const char *restrict, struct stat *restrict);
|
||||
|
||||
export int mkdir(const char *path, mode_t mode)
|
||||
{
|
||||
return __check_errno(call_mkdir(path, mode), -1);
|
||||
}
|
||||
|
||||
export int mkdirat(int fd, const char *path, mode_t mode)
|
||||
{
|
||||
printf("mkdirat() is unimplemented\n");
|
||||
return __check_errno(-ENOSYS, -1);
|
||||
}
|
||||
|
||||
export int mkfifo(const char *, mode_t);
|
||||
export int mkfifoat(int, const char *, mode_t);
|
||||
export int mknod(const char *, mode_t, dev_t);
|
||||
export int mknodat(int, const char *, mode_t, dev_t);
|
||||
export int stat(const char *restrict, struct stat *restrict);
|
||||
export mode_t umask(mode_t);
|
||||
export int utimensat(int, const char *, const struct timespec[2], int);
|
38
Userspace/libc/src/std/sys/wait.c
Normal file
38
Userspace/libc/src/std/sys/wait.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
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/wait.h>
|
||||
#include <fennix/syscalls.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
export pid_t wait(int *stat_loc)
|
||||
{
|
||||
return waitpid((pid_t)-1, stat_loc, 0);
|
||||
}
|
||||
|
||||
export int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)
|
||||
{
|
||||
printf("waitid() is unimplemented\n");
|
||||
return __check_errno(-ENOSYS, -1);
|
||||
}
|
||||
|
||||
export pid_t waitpid(pid_t pid, int *stat_loc, int options)
|
||||
{
|
||||
return __check_errno(call_waitpid(pid, stat_loc, options), -1);
|
||||
}
|
@ -16,13 +16,26 @@
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fennix/syscalls.h>
|
||||
|
||||
export char *optarg;
|
||||
export int optind, opterr, optopt;
|
||||
export char **environ;
|
||||
|
||||
export int access(const char *, int);
|
||||
export unsigned int alarm(unsigned int);
|
||||
|
||||
export unsigned int alarm(unsigned int seconds)
|
||||
{
|
||||
printf("alarm() is unimplemented\n");
|
||||
return __check_errno(-ENOSYS, -1);
|
||||
}
|
||||
|
||||
export int brk(void *);
|
||||
export int chdir(const char *);
|
||||
export int chroot(const char *);
|
||||
@ -35,17 +48,122 @@ 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 int execl(const char *path, const char *arg0, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, arg0);
|
||||
|
||||
int argc = 1;
|
||||
while (va_arg(args, const char *))
|
||||
argc++;
|
||||
va_end(args);
|
||||
|
||||
char *argv[argc + 1];
|
||||
va_start(args, arg0);
|
||||
argv[0] = (char *)arg0;
|
||||
for (int i = 1; i < argc; i++)
|
||||
argv[i] = va_arg(args, char *);
|
||||
|
||||
argv[argc] = NULL;
|
||||
va_end(args);
|
||||
return execve(path, argv, environ);
|
||||
}
|
||||
|
||||
export int execle(const char *path, const char *arg0, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, arg0);
|
||||
|
||||
int argc = 1;
|
||||
while (va_arg(args, const char *))
|
||||
argc++;
|
||||
va_end(args);
|
||||
|
||||
char *argv[argc + 1];
|
||||
va_start(args, arg0);
|
||||
argv[0] = (char *)arg0;
|
||||
for (int i = 1; i < argc; i++)
|
||||
argv[i] = va_arg(args, char *);
|
||||
|
||||
argv[argc] = NULL;
|
||||
|
||||
char *const *envp = va_arg(args, char *const *);
|
||||
va_end(args);
|
||||
|
||||
return execve(path, argv, envp);
|
||||
}
|
||||
|
||||
export int execlp(const char *file, const char *arg0, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, arg0);
|
||||
|
||||
int argc = 1;
|
||||
while (va_arg(args, const char *))
|
||||
argc++;
|
||||
|
||||
va_end(args);
|
||||
|
||||
char *argv[argc + 1];
|
||||
va_start(args, arg0);
|
||||
argv[0] = (char *)arg0;
|
||||
for (int i = 1; i < argc; i++)
|
||||
argv[i] = va_arg(args, char *);
|
||||
|
||||
argv[argc] = NULL;
|
||||
va_end(args);
|
||||
|
||||
return execvp(file, argv);
|
||||
}
|
||||
|
||||
export int execv(const char *path, char *const argv[])
|
||||
{
|
||||
return execve(path, argv, environ);
|
||||
}
|
||||
|
||||
export int execve(const char *path, char *const argv[], char *const envp[])
|
||||
{
|
||||
return __check_errno(call_execve(path, argv, envp), -1);
|
||||
}
|
||||
|
||||
export int execvp(const char *file, char *const argv[])
|
||||
{
|
||||
if (strchr(file, '/'))
|
||||
return execve(file, argv, environ);
|
||||
|
||||
char *path = getenv("PATH");
|
||||
if (!path)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *p = strtok(path, ":");
|
||||
while (p)
|
||||
{
|
||||
char fullpath[PATH_MAX];
|
||||
snprintf(fullpath, sizeof(fullpath), "%s/%s", p, file);
|
||||
execve(fullpath, argv, environ);
|
||||
if (errno != ENOENT && errno != ENOTDIR)
|
||||
return -1;
|
||||
p = strtok(NULL, ":");
|
||||
}
|
||||
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
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 pid_t fork(void)
|
||||
{
|
||||
return __check_errno(call_fork(), -1);
|
||||
}
|
||||
|
||||
export long int fpathconf(int, int);
|
||||
export int fsync(int);
|
||||
export int ftruncate(int, off_t);
|
||||
@ -79,7 +197,13 @@ 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 pause(void)
|
||||
{
|
||||
printf("pause() is unimplemented\n");
|
||||
return __check_errno(-ENOSYS, -1);
|
||||
}
|
||||
|
||||
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));
|
||||
@ -95,10 +219,31 @@ 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 unsigned int sleep(unsigned int seconds)
|
||||
{
|
||||
unsigned int unslept = alarm(0); /* Cancel any existing alarm */
|
||||
if (unslept > 0)
|
||||
{
|
||||
alarm(unslept); /* Restore the previous alarm if it was set */
|
||||
return unslept;
|
||||
}
|
||||
|
||||
alarm(seconds); /* Set the alarm for the requested sleep time */
|
||||
pause(); /* Suspend execution until a signal is received */
|
||||
|
||||
unslept = alarm(0); /* Cancel the alarm and get the remaining time */
|
||||
return unslept;
|
||||
}
|
||||
|
||||
export void swab(const void *, void *, ssize_t);
|
||||
export int symlink(const char *, const char *);
|
||||
export void sync(void);
|
||||
|
||||
export void sync(void)
|
||||
{
|
||||
printf("sync() is unimplemented\n");
|
||||
}
|
||||
|
||||
export long int sysconf(int);
|
||||
export pid_t tcgetpgrp(int);
|
||||
export int tcsetpgrp(int, pid_t);
|
||||
|
Loading…
x
Reference in New Issue
Block a user