mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-07-05 20:39:16 +00:00
feat(userspace/libc): implement functions for porting apps
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
@ -19,6 +19,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <bits/libc.h>
|
||||
#include <fcntl.h>
|
||||
#include "../print/printf.h"
|
||||
@ -466,7 +467,24 @@ export int puts(const char *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
export int remove(const char *);
|
||||
export int remove(const char *path)
|
||||
{
|
||||
if (!path)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct stat path_stat;
|
||||
if (sysdep(Stat)(path, &path_stat) < 0)
|
||||
return -1;
|
||||
|
||||
if (S_ISDIR(path_stat.st_mode))
|
||||
return sysdep(RemoveDirectory)(path);
|
||||
else
|
||||
return sysdep(Unlink)(path);
|
||||
}
|
||||
|
||||
export int rename(const char *, const char *);
|
||||
export int renameat(int, const char *, int, const char *);
|
||||
export void rewind(FILE *);
|
||||
@ -492,7 +510,117 @@ export int sprintf(char *restrict s, const char *restrict format, ...)
|
||||
return ret;
|
||||
}
|
||||
|
||||
export int sscanf(const char *restrict, const char *restrict, ...);
|
||||
export int sscanf(const char *restrict s, const char *restrict format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
const char *p = format;
|
||||
int matchedItems = 0;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if (isspace(*p))
|
||||
{
|
||||
while (isspace(*p))
|
||||
p++;
|
||||
while (isspace(*s))
|
||||
s++;
|
||||
}
|
||||
else if (*p == '%')
|
||||
{
|
||||
p++;
|
||||
if (*p == '\0')
|
||||
break;
|
||||
|
||||
int suppress_assignment = 0;
|
||||
if (*p == '*')
|
||||
{
|
||||
suppress_assignment = 1;
|
||||
p++;
|
||||
}
|
||||
|
||||
int width = 0;
|
||||
while (isdigit(*p))
|
||||
{
|
||||
width = width * 10 + (*p - '0');
|
||||
p++;
|
||||
}
|
||||
|
||||
char specifier = *p++;
|
||||
if (specifier == '\0')
|
||||
break;
|
||||
|
||||
if (specifier == 'd' || specifier == 'i')
|
||||
{
|
||||
int value = 0;
|
||||
while (isdigit(*s) || (*s == '-' && value == 0))
|
||||
{
|
||||
if (*s == '-')
|
||||
{
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
value = value * 10 + (*s - '0');
|
||||
s++;
|
||||
}
|
||||
if (!suppress_assignment)
|
||||
{
|
||||
int *arg = va_arg(args, int *);
|
||||
*arg = value;
|
||||
matchedItems++;
|
||||
}
|
||||
}
|
||||
else if (specifier == 's')
|
||||
{
|
||||
char *str = va_arg(args, char *);
|
||||
while (*s && !isspace(*s) && (width == 0 || width-- > 0))
|
||||
{
|
||||
if (!suppress_assignment)
|
||||
*str++ = *s;
|
||||
s++;
|
||||
}
|
||||
if (!suppress_assignment)
|
||||
*str = '\0';
|
||||
matchedItems++;
|
||||
}
|
||||
else if (specifier == 'c')
|
||||
{
|
||||
char *ch = va_arg(args, char *);
|
||||
if (*s && (width == 0 || width-- > 0))
|
||||
{
|
||||
if (!suppress_assignment)
|
||||
*ch = *s;
|
||||
s++;
|
||||
matchedItems++;
|
||||
}
|
||||
}
|
||||
else if (specifier == '%')
|
||||
{
|
||||
if (*s == '%')
|
||||
s++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*s == *p)
|
||||
{
|
||||
s++;
|
||||
p++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
return matchedItems;
|
||||
}
|
||||
|
||||
export FILE *tmpfile(void);
|
||||
export char *tmpnam(char *);
|
||||
export int ungetc(int, FILE *);
|
||||
@ -526,6 +654,14 @@ export int vfprintf(FILE *restrict stream, const char *restrict format, 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 vsnprintf(char *restrict s, size_t n, const char *restrict format, va_list ap)
|
||||
{
|
||||
int ret = vsnprintf_(s, n, format, ap);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
export int vsprintf(char *restrict, const char *restrict, va_list);
|
||||
export int vsscanf(const char *restrict, const char *restrict, va_list);
|
||||
|
@ -334,7 +334,161 @@ export long long strtoll(const char *restrict nptr, char **restrict endptr, int
|
||||
return acc;
|
||||
}
|
||||
|
||||
export unsigned long int strtoul(const char *, char **, int);
|
||||
export unsigned long int strtoul(const char *restrict str, char **restrict endptr, int base)
|
||||
{
|
||||
const char *s = str;
|
||||
unsigned long acc = 0;
|
||||
int c;
|
||||
unsigned long cutoff;
|
||||
int any, cutlim;
|
||||
|
||||
if (base < 0 || base == 1 || base > 36)
|
||||
{
|
||||
errno = EINVAL;
|
||||
if (endptr)
|
||||
*endptr = (char *)str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (isspace((unsigned char)*s))
|
||||
s++;
|
||||
|
||||
if (*s == '+')
|
||||
s++;
|
||||
else if (*s == '-')
|
||||
{
|
||||
errno = EINVAL;
|
||||
if (endptr)
|
||||
*endptr = (char *)str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((base == 0 || base == 16) && *s == '0' && (s[1] == 'x' || s[1] == 'X'))
|
||||
{
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
else if (base == 0)
|
||||
base = *s == '0' ? 8 : 10;
|
||||
|
||||
cutoff = ULONG_MAX / base;
|
||||
cutlim = ULONG_MAX % base;
|
||||
|
||||
for (acc = 0, any = 0;; c = *s++)
|
||||
{
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
|
||||
if (c >= base)
|
||||
break;
|
||||
|
||||
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else
|
||||
{
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
|
||||
if (any < 0)
|
||||
{
|
||||
acc = ULONG_MAX;
|
||||
errno = ERANGE;
|
||||
}
|
||||
else if (any == 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
}
|
||||
|
||||
if (endptr)
|
||||
*endptr = (char *)(any ? s - 1 : str);
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
export unsigned long long strtoull(const char *restrict str, char **restrict endptr, int base)
|
||||
{
|
||||
const char *s = str;
|
||||
unsigned long long acc = 0;
|
||||
int c;
|
||||
unsigned long long cutoff;
|
||||
int any, cutlim;
|
||||
|
||||
if (base < 0 || base == 1 || base > 36)
|
||||
{
|
||||
errno = EINVAL;
|
||||
if (endptr)
|
||||
*endptr = (char *)str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (isspace((unsigned char)*s))
|
||||
s++;
|
||||
|
||||
if (*s == '+')
|
||||
s++;
|
||||
else if (*s == '-')
|
||||
{
|
||||
errno = EINVAL;
|
||||
if (endptr)
|
||||
*endptr = (char *)str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((base == 0 || base == 16) && *s == '0' && (s[1] == 'x' || s[1] == 'X'))
|
||||
{
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
else if (base == 0)
|
||||
base = *s == '0' ? 8 : 10;
|
||||
|
||||
cutoff = ULLONG_MAX / base;
|
||||
cutlim = ULLONG_MAX % base;
|
||||
|
||||
for (acc = 0, any = 0;; c = *s++)
|
||||
{
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
|
||||
if (c >= base)
|
||||
break;
|
||||
|
||||
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
|
||||
any = -1;
|
||||
else
|
||||
{
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
|
||||
if (any < 0)
|
||||
{
|
||||
acc = ULLONG_MAX;
|
||||
errno = ERANGE;
|
||||
}
|
||||
else if (any == 0)
|
||||
{
|
||||
errno = EINVAL;
|
||||
}
|
||||
|
||||
if (endptr)
|
||||
*endptr = (char *)(any ? s - 1 : str);
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
export int system(const char *command)
|
||||
{
|
||||
|
@ -30,12 +30,29 @@ export long timezone;
|
||||
export char *tzname[2];
|
||||
|
||||
export char *asctime(const struct tm *);
|
||||
export clock_t clock(void);
|
||||
|
||||
export clock_t clock(void)
|
||||
{
|
||||
clock_t processor_time = sysdep(Clock)();
|
||||
if (processor_time == (clock_t)-1)
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return (clock_t)-1;
|
||||
}
|
||||
return processor_time;
|
||||
}
|
||||
|
||||
export int clock_getcpuclockid(pid_t, clockid_t *);
|
||||
export int clock_getres(clockid_t, struct timespec *);
|
||||
export int clock_gettime(clockid_t, struct timespec *);
|
||||
export int clock_getres(clockid_t clock_id, struct timespec *res);
|
||||
|
||||
export int clock_gettime(clockid_t clock_id, struct timespec *tp)
|
||||
{
|
||||
return sysdep(ClockGetTime)(clock_id, tp);
|
||||
}
|
||||
|
||||
export int clock_nanosleep(clockid_t, int, const struct timespec *, struct timespec *);
|
||||
export int clock_settime(clockid_t, const struct timespec *);
|
||||
export int clock_settime(clockid_t clock_id, const struct timespec *tp);
|
||||
;
|
||||
export char *ctime(const time_t *);
|
||||
export double difftime(time_t, time_t);
|
||||
export struct tm *getdate(const char *);
|
||||
@ -193,7 +210,20 @@ export int nanosleep(const struct timespec *, struct timespec *);
|
||||
export size_t strftime(char *restrict, size_t, const char *restrict, const struct tm *restrict);
|
||||
export size_t strftime_l(char *restrict, size_t, const char *restrict, const struct tm *restrict, locale_t);
|
||||
export char *strptime(const char *restrict, const char *restrict, struct tm *restrict);
|
||||
export time_t time(time_t *);
|
||||
|
||||
export time_t time(time_t *tloc)
|
||||
{
|
||||
time_t current_time = sysdep(Time)();
|
||||
if (current_time == (time_t)-1)
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return (time_t)-1;
|
||||
}
|
||||
if (tloc)
|
||||
*tloc = current_time;
|
||||
return current_time;
|
||||
}
|
||||
|
||||
export int timer_create(clockid_t, struct sigevent *restrict, timer_t *restrict);
|
||||
export int timer_delete(timer_t);
|
||||
export int timer_getoverrun(timer_t);
|
||||
|
@ -293,7 +293,12 @@ export ssize_t read(int fildes, void *buf, size_t nbyte)
|
||||
}
|
||||
|
||||
export int readlink(const char *, char *, size_t);
|
||||
export int rmdir(const char *);
|
||||
|
||||
export int rmdir(const char *path)
|
||||
{
|
||||
return __check_errno(sysdep(RemoveDirectory)(path), -1);
|
||||
}
|
||||
|
||||
export void *sbrk(intptr_t incr);
|
||||
export int setgid(gid_t);
|
||||
export int setpgid(pid_t, pid_t);
|
||||
@ -334,7 +339,12 @@ 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 unlink(const char *path)
|
||||
{
|
||||
return __check_errno(sysdep(Unlink)(path), -1);
|
||||
}
|
||||
|
||||
export int usleep(useconds_t);
|
||||
export pid_t vfork(void);
|
||||
|
||||
|
Reference in New Issue
Block a user