mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-30 00:07:59 +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
|
#define DT_TMO
|
||||||
|
|
||||||
int alphasort(const struct dirent **, const struct dirent **);
|
int alphasort(const struct dirent **, const struct dirent **);
|
||||||
int closedir(DIR *);
|
int closedir(DIR *dirp);
|
||||||
int dirfd(DIR *);
|
int dirfd(DIR *);
|
||||||
DIR *fdopendir(int);
|
DIR *fdopendir(int);
|
||||||
DIR *opendir(const char *);
|
DIR *opendir(const char *);
|
||||||
|
@ -23,6 +23,8 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
typedef struct f_owner_ex
|
typedef struct f_owner_ex
|
||||||
{
|
{
|
||||||
int type; /* Discriminator for pid. */
|
int type; /* Discriminator for pid. */
|
||||||
|
@ -90,9 +90,9 @@ extern "C"
|
|||||||
int feof(FILE *);
|
int feof(FILE *);
|
||||||
int ferror(FILE *);
|
int ferror(FILE *);
|
||||||
int fflush(FILE *stream);
|
int fflush(FILE *stream);
|
||||||
int fgetc(FILE *);
|
int fgetc(FILE *stream);
|
||||||
int fgetpos(FILE *restrict, fpos_t *restrict);
|
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 *);
|
int fileno(FILE *);
|
||||||
void flockfile(FILE *);
|
void flockfile(FILE *);
|
||||||
FILE *fmemopen(void *restrict, size_t, const char *restrict);
|
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);
|
ssize_t getline(char **restrict, size_t *restrict, FILE *restrict);
|
||||||
FILE *open_memstream(char **, size_t *);
|
FILE *open_memstream(char **, size_t *);
|
||||||
int pclose(FILE *);
|
int pclose(FILE *);
|
||||||
void perror(const char *);
|
void perror(const char *s);
|
||||||
FILE *popen(const char *, const char *);
|
FILE *popen(const char *, const char *);
|
||||||
int printf(const char *restrict format, ...);
|
int printf(const char *restrict format, ...);
|
||||||
int putc(int c, FILE *stream);
|
int putc(int c, FILE *stream);
|
||||||
@ -134,8 +134,8 @@ extern "C"
|
|||||||
int scanf(const char *restrict, ...);
|
int scanf(const char *restrict, ...);
|
||||||
void setbuf(FILE *restrict, char *restrict);
|
void setbuf(FILE *restrict, char *restrict);
|
||||||
int setvbuf(FILE *restrict, char *restrict, int, size_t);
|
int setvbuf(FILE *restrict, char *restrict, int, size_t);
|
||||||
int snprintf(char *restrict, size_t, const char *restrict, ...);
|
int snprintf(char *restrict s, size_t n, const char *restrict format, ...);
|
||||||
int sprintf(char *restrict, const char *restrict, ...);
|
int sprintf(char *restrict s, const char *restrict format, ...);
|
||||||
int sscanf(const char *restrict, const char *restrict, ...);
|
int sscanf(const char *restrict, const char *restrict, ...);
|
||||||
FILE *tmpfile(void);
|
FILE *tmpfile(void);
|
||||||
char *tmpnam(char *);
|
char *tmpnam(char *);
|
||||||
|
@ -51,7 +51,7 @@ extern "C"
|
|||||||
|
|
||||||
long a64l(const char *);
|
long a64l(const char *);
|
||||||
void abort(void);
|
void abort(void);
|
||||||
int abs(int);
|
int abs(int i);
|
||||||
int atexit(void (*func)(void));
|
int atexit(void (*func)(void));
|
||||||
double atof(const char *);
|
double atof(const char *);
|
||||||
int atoi(const char *);
|
int atoi(const char *);
|
||||||
@ -66,7 +66,7 @@ extern "C"
|
|||||||
char *fcvt(double, int, int *, int *);
|
char *fcvt(double, int, int *, int *);
|
||||||
void free(void *ptr);
|
void free(void *ptr);
|
||||||
char *gcvt(double, int, char *);
|
char *gcvt(double, int, char *);
|
||||||
char *getenv(const char *);
|
char *getenv(const char *name);
|
||||||
int getsubopt(char **, char *const *, char **);
|
int getsubopt(char **, char *const *, char **);
|
||||||
int grantpt(int);
|
int grantpt(int);
|
||||||
char *initstate(unsigned int, char *, size_t);
|
char *initstate(unsigned int, char *, size_t);
|
||||||
|
@ -36,7 +36,7 @@ extern "C"
|
|||||||
char *stpcpy(char *restrict, const char *restrict);
|
char *stpcpy(char *restrict, const char *restrict);
|
||||||
char *stpncpy(char *restrict, const char *restrict, size_t);
|
char *stpncpy(char *restrict, const char *restrict, size_t);
|
||||||
char *strcat(char *restrict, const char *restrict);
|
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 strcmp(const char *s1, const char *s2);
|
||||||
int strcoll(const char *, const char *);
|
int strcoll(const char *, const char *);
|
||||||
int strcoll_l(const char *, const char *, locale_t);
|
int strcoll_l(const char *, const char *, locale_t);
|
||||||
@ -48,19 +48,19 @@ extern "C"
|
|||||||
int strerror_r(int, char *, size_t);
|
int strerror_r(int, char *, size_t);
|
||||||
size_t strlcat(char *restrict, const char *restrict, size_t);
|
size_t strlcat(char *restrict, const char *restrict, size_t);
|
||||||
size_t strlcpy(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);
|
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 *strncpy(char *restrict, const char *restrict, size_t);
|
||||||
char *strndup(const char *, size_t);
|
char *strndup(const char *, size_t);
|
||||||
size_t strnlen(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 *strrchr(const char *, int);
|
||||||
char *strsignal(int);
|
char *strsignal(int signum);
|
||||||
size_t strspn(const char *, const char *);
|
size_t strspn(const char *s1, const char *s2);
|
||||||
char *strstr(const char *, const char *);
|
char *strstr(const char *, const char *);
|
||||||
char *strtok(char *restrict, const char *restrict);
|
char *strtok(char *restrict s, const char *restrict sep);
|
||||||
char *strtok_r(char *restrict, const char *restrict, char **restrict);
|
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(char *restrict, const char *restrict, size_t);
|
||||||
size_t strxfrm_l(char *restrict, const char *restrict, size_t, locale_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 fstatat(int, const char *restrict, struct stat *restrict, int);
|
||||||
int futimens(int, const struct timespec[2]);
|
int futimens(int, const struct timespec[2]);
|
||||||
int lstat(const char *restrict, struct stat *restrict);
|
int lstat(const char *restrict, struct stat *restrict);
|
||||||
int mkdir(const char *, mode_t);
|
int mkdir(const char *path, mode_t mode);
|
||||||
int mkdirat(int, const char *, mode_t);
|
int mkdirat(int fd, const char *path, mode_t mode);
|
||||||
int mkfifo(const char *, mode_t);
|
int mkfifo(const char *, mode_t);
|
||||||
int mkfifoat(int, const char *, mode_t);
|
int mkfifoat(int, const char *, mode_t);
|
||||||
int mknod(const char *, mode_t, dev_t);
|
int mknod(const char *, mode_t, dev_t);
|
||||||
|
@ -54,9 +54,9 @@ extern "C"
|
|||||||
typedef unsigned int id_t;
|
typedef unsigned int id_t;
|
||||||
typedef int pid_t;
|
typedef int pid_t;
|
||||||
|
|
||||||
pid_t wait(int *);
|
pid_t wait(int *stat_loc);
|
||||||
int waitid(idtype_t, id_t, siginfo_t *, int);
|
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
|
||||||
pid_t waitpid(pid_t, int *, int);
|
pid_t waitpid(pid_t pid, int *stat_loc, int options);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -57,9 +57,10 @@ extern "C"
|
|||||||
|
|
||||||
extern char *optarg;
|
extern char *optarg;
|
||||||
extern int optind, opterr, optopt;
|
extern int optind, opterr, optopt;
|
||||||
|
extern char **environ;
|
||||||
|
|
||||||
int access(const char *, int);
|
int access(const char *, int);
|
||||||
unsigned int alarm(unsigned int);
|
unsigned int alarm(unsigned int seconds);
|
||||||
int brk(void *);
|
int brk(void *);
|
||||||
int chdir(const char *);
|
int chdir(const char *);
|
||||||
int chroot(const char *);
|
int chroot(const char *);
|
||||||
@ -72,12 +73,12 @@ extern "C"
|
|||||||
int dup(int);
|
int dup(int);
|
||||||
int dup2(int, int);
|
int dup2(int, int);
|
||||||
void encrypt(char[64], int);
|
void encrypt(char[64], int);
|
||||||
int execl(const char *, const char *, ...);
|
int execl(const char *path, const char *arg0, ... /*, (char *)0 */);
|
||||||
int execle(const char *, const char *, ...);
|
int execle(const char *path, const char *arg0, ... /*, (char *)0, char *const envp[]*/);
|
||||||
int execlp(const char *, const char *, ...);
|
int execlp(const char *file, const char *arg0, ... /*, (char *)0 */);
|
||||||
int execv(const char *, char *const[]);
|
int execv(const char *path, char *const argv[]);
|
||||||
int execve(const char *, char *const[], char *const[]);
|
int execve(const char *path, char *const argv[], char *const envp[]);
|
||||||
int execvp(const char *, char *const[]);
|
int execvp(const char *file, char *const argv[]);
|
||||||
void _exit(int);
|
void _exit(int);
|
||||||
int fchown(int, uid_t, gid_t);
|
int fchown(int, uid_t, gid_t);
|
||||||
int fchdir(int);
|
int fchdir(int);
|
||||||
@ -128,7 +129,7 @@ extern "C"
|
|||||||
int setreuid(uid_t, uid_t);
|
int setreuid(uid_t, uid_t);
|
||||||
pid_t setsid(void);
|
pid_t setsid(void);
|
||||||
int setuid(uid_t);
|
int setuid(uid_t);
|
||||||
unsigned int sleep(unsigned int);
|
unsigned int sleep(unsigned int seconds);
|
||||||
void swab(const void *, void *, ssize_t);
|
void swab(const void *, void *, ssize_t);
|
||||||
int symlink(const char *, const char *);
|
int symlink(const char *, const char *);
|
||||||
void sync(void);
|
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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <fennix/syscalls.h>
|
#include <fennix/syscalls.h>
|
||||||
#include "../print/printf.h"
|
#include "../print/printf.h"
|
||||||
|
|
||||||
@ -109,9 +110,54 @@ export int fflush(FILE *stream)
|
|||||||
return 0;
|
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 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 int fileno(FILE *);
|
||||||
export void flockfile(FILE *);
|
export void flockfile(FILE *);
|
||||||
export FILE *fmemopen(void *restrict, size_t, const char *restrict);
|
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 ssize_t getline(char **restrict, size_t *restrict, FILE *restrict);
|
||||||
export FILE *open_memstream(char **, size_t *);
|
export FILE *open_memstream(char **, size_t *);
|
||||||
export int pclose(FILE *);
|
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 FILE *popen(const char *, const char *);
|
||||||
|
|
||||||
export int printf(const char *restrict format, ...)
|
export int printf(const char *restrict format, ...)
|
||||||
@ -327,8 +381,25 @@ export void rewind(FILE *);
|
|||||||
export int scanf(const char *restrict, ...);
|
export int scanf(const char *restrict, ...);
|
||||||
export void setbuf(FILE *restrict, char *restrict);
|
export void setbuf(FILE *restrict, char *restrict);
|
||||||
export int setvbuf(FILE *restrict, char *restrict, int, size_t);
|
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 int sscanf(const char *restrict, const char *restrict, ...);
|
||||||
export FILE *tmpfile(void);
|
export FILE *tmpfile(void);
|
||||||
export char *tmpnam(char *);
|
export char *tmpnam(char *);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
#include "../mem/liballoc_1_1.h"
|
#include "../mem/liballoc_1_1.h"
|
||||||
|
|
||||||
#define MAX_ATEXIT_FUNCS 32
|
#define MAX_ATEXIT_FUNCS 32
|
||||||
@ -31,7 +32,10 @@ export _Noreturn void abort(void)
|
|||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
export int abs(int);
|
export int abs(int i)
|
||||||
|
{
|
||||||
|
return (i < 0) ? -i : i;
|
||||||
|
}
|
||||||
|
|
||||||
export int atexit(void (*func)(void))
|
export int atexit(void (*func)(void))
|
||||||
{
|
{
|
||||||
@ -62,7 +66,18 @@ export void exit(int status)
|
|||||||
export char *fcvt(double, int, int *, int *);
|
export char *fcvt(double, int, int *, int *);
|
||||||
export void free(void *ptr) { return PREFIX(free)(ptr); }
|
export void free(void *ptr) { return PREFIX(free)(ptr); }
|
||||||
export char *gcvt(double, int, char *);
|
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 getsubopt(char **, char *const *, char **);
|
||||||
export int grantpt(int);
|
export int grantpt(int);
|
||||||
export char *initstate(unsigned int, char *, size_t);
|
export char *initstate(unsigned int, char *, size_t);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <fennix/syscalls.h>
|
||||||
|
|
||||||
export void *memccpy(void *restrict, const void *restrict, int, size_t);
|
export void *memccpy(void *restrict, const void *restrict, int, size_t);
|
||||||
export void *memchr(const void *, 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 *stpcpy(char *restrict, const char *restrict);
|
||||||
export char *stpncpy(char *restrict, const char *restrict, size_t);
|
export char *stpncpy(char *restrict, const char *restrict, size_t);
|
||||||
export char *strcat(char *restrict, const char *restrict);
|
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)
|
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 int strerror_r(int, char *, size_t);
|
||||||
export size_t strlcat(char *restrict, const char *restrict, 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 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 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 *strncpy(char *restrict, const char *restrict, size_t);
|
||||||
export char *strndup(const char *, size_t);
|
export char *strndup(const char *, size_t);
|
||||||
export size_t strnlen(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 *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 *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(char *restrict, const char *restrict, size_t);
|
||||||
export size_t strxfrm_l(char *restrict, const char *restrict, size_t, locale_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 <unistd.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <fennix/syscalls.h>
|
#include <fennix/syscalls.h>
|
||||||
|
|
||||||
export char *optarg;
|
export char *optarg;
|
||||||
export int optind, opterr, optopt;
|
export int optind, opterr, optopt;
|
||||||
|
export char **environ;
|
||||||
|
|
||||||
export int access(const char *, int);
|
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 brk(void *);
|
||||||
export int chdir(const char *);
|
export int chdir(const char *);
|
||||||
export int chroot(const char *);
|
export int chroot(const char *);
|
||||||
@ -35,17 +48,122 @@ export char *cuserid(char *s);
|
|||||||
export int dup(int);
|
export int dup(int);
|
||||||
export int dup2(int, int);
|
export int dup2(int, int);
|
||||||
export void encrypt(char[64], int);
|
export void encrypt(char[64], int);
|
||||||
export int execl(const char *, const char *, ...);
|
|
||||||
export int execle(const char *, const char *, ...);
|
export int execl(const char *path, const char *arg0, ...)
|
||||||
export int execlp(const char *, const char *, ...);
|
{
|
||||||
export int execv(const char *, char *const[]);
|
va_list args;
|
||||||
export int execve(const char *, char *const[], char *const[]);
|
va_start(args, arg0);
|
||||||
export int execvp(const char *, char *const[]);
|
|
||||||
|
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 void _exit(int);
|
||||||
export int fchown(int, uid_t, gid_t);
|
export int fchown(int, uid_t, gid_t);
|
||||||
export int fchdir(int);
|
export int fchdir(int);
|
||||||
export int fdatasync(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 long int fpathconf(int, int);
|
||||||
export int fsync(int);
|
export int fsync(int);
|
||||||
export int ftruncate(int, off_t);
|
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 off_t lseek(int, off_t, int);
|
||||||
export int nice(int);
|
export int nice(int);
|
||||||
export long int pathconf(const char *, 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 int pipe(int[2]);
|
||||||
export ssize_t pread(int, void *, size_t, off_t);
|
export ssize_t pread(int, void *, size_t, off_t);
|
||||||
export int pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
|
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 int setreuid(uid_t, uid_t);
|
||||||
export pid_t setsid(void);
|
export pid_t setsid(void);
|
||||||
export int setuid(uid_t);
|
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 void swab(const void *, void *, ssize_t);
|
||||||
export int symlink(const char *, const char *);
|
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 long int sysconf(int);
|
||||||
export pid_t tcgetpgrp(int);
|
export pid_t tcgetpgrp(int);
|
||||||
export int tcsetpgrp(int, pid_t);
|
export int tcsetpgrp(int, pid_t);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user