More libc
This commit is contained in:
parent
5cd281a1a6
commit
22a3321c25
1
.gitignore
vendored
1
.gitignore
vendored
@ -13,3 +13,4 @@ util/build
|
||||
util/local
|
||||
.gdb_history
|
||||
kernel/symbols.S
|
||||
base/usr/python
|
||||
|
@ -27,3 +27,5 @@ extern double log2(double x);
|
||||
extern double sinh(double x);
|
||||
extern double tan(double x);
|
||||
extern double tanh(double x);
|
||||
|
||||
extern double modf(double x, double *iptr);
|
||||
|
@ -24,6 +24,8 @@ extern char * strrchr(const char * s, int c);
|
||||
extern char * strpbrk(const char * s, const char * b);
|
||||
extern char * strstr(const char * h, const char * n);
|
||||
|
||||
extern char * strncpy(char * dest, const char * src, size_t n);
|
||||
|
||||
extern int strcmp(const char * l, const char * r);
|
||||
extern int strncmp(const char *s1, const char *s2, size_t n);
|
||||
extern int strcoll(const char * s1, const char * s2);
|
||||
|
@ -17,6 +17,10 @@ struct tm {
|
||||
|
||||
extern struct tm *localtime(const time_t *timep);
|
||||
extern struct tm *gmtime(const time_t *timep);
|
||||
|
||||
extern struct tm *localtime_r(const time_t *timep, struct tm * buf);
|
||||
extern struct tm *gmtime_r(const time_t *timep, struct tm * buf);
|
||||
|
||||
extern size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
|
||||
extern time_t time(time_t * out);
|
||||
extern double difftime(time_t a, time_t b);
|
||||
|
@ -6,6 +6,7 @@
|
||||
extern char **environ;
|
||||
|
||||
extern pid_t getpid(void);
|
||||
extern pid_t getppid(void);
|
||||
|
||||
extern int close(int fd);
|
||||
|
||||
@ -40,7 +41,7 @@ extern int symlink(const char *target, const char *linkpath);
|
||||
extern ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);
|
||||
|
||||
extern int chdir(const char *path);
|
||||
extern int fchdir(int fd);
|
||||
//extern int fchdir(int fd);
|
||||
extern int isatty(int fd);
|
||||
|
||||
extern unsigned int sleep(unsigned int seconds);
|
||||
@ -56,6 +57,15 @@ extern int optind, opterr, optopt;
|
||||
|
||||
extern int unlink(const char * pathname);
|
||||
|
||||
/* Unimplemented stubs */
|
||||
struct utimbuf {
|
||||
time_t actime;
|
||||
time_t modtime;
|
||||
};
|
||||
extern char * ttyname(int fd);
|
||||
extern int utime(const char *filename, const struct utimbuf *times);
|
||||
extern int rmdir(const char *pathname); /* TODO rm probably just works */
|
||||
|
||||
#define STDIN_FILENO 0
|
||||
#define STDOUT_FILENO 1
|
||||
#define STDERR_FILENO 2
|
||||
|
@ -7,5 +7,14 @@ extern wchar_t * wcsncpy(wchar_t * dest, const wchar_t * src, size_t n);
|
||||
extern size_t wcslen(const wchar_t * s);
|
||||
extern int wcscmp(const wchar_t *s1, const wchar_t *s2);
|
||||
extern wchar_t * wcscat(wchar_t *dest, const wchar_t *src);
|
||||
extern wchar_t * wcstok(wchar_t * str, const wchar_t * delim, wchar_t ** saveptr);
|
||||
extern size_t wcsspn(const wchar_t * wcs, const wchar_t * accept);
|
||||
extern wchar_t *wcspbrk(const wchar_t *wcs, const wchar_t *accept);
|
||||
extern wchar_t * wcschr(const wchar_t *wcs, wchar_t wc);
|
||||
extern wchar_t * wcsrchr(const wchar_t *wcs, wchar_t wc);
|
||||
extern wchar_t * wcsncat(wchar_t *dest, const wchar_t * src, size_t n);
|
||||
|
||||
/* TODO */
|
||||
extern size_t wcstombs(char * dest, const wchar_t *src, size_t n);
|
||||
|
||||
typedef unsigned int wint_t;
|
||||
|
@ -37,7 +37,6 @@ DEFN_SYSCALL2(sleepabs, 45, unsigned long, unsigned long);
|
||||
DEFN_SYSCALL3(ioctl, 47, int, int, void *);
|
||||
DEFN_SYSCALL2(access, 48, char *, int);
|
||||
DEFN_SYSCALL2(stat, 49, char *, void *);
|
||||
DEFN_SYSCALL1(umask, 51, int);
|
||||
DEFN_SYSCALL3(waitpid, 53, int, int *, int);
|
||||
DEFN_SYSCALL5(mount, SYS_MOUNT, char *, char *, char *, unsigned long, void *);
|
||||
DEFN_SYSCALL2(lstat, SYS_LSTAT, char *, void *);
|
||||
|
7
libc/math/modf.c
Normal file
7
libc/math/modf.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <math.h>
|
||||
|
||||
double modf(double x, double *iptr) {
|
||||
int i = (int)x;
|
||||
*iptr = (double)i;
|
||||
return x - i;
|
||||
}
|
13
libc/string/strncpy.c
Normal file
13
libc/string/strncpy.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include <string.h>
|
||||
|
||||
char * strncpy(char * dest, const char * src, size_t n) {
|
||||
char * out = dest;
|
||||
while (n > 0) {
|
||||
if (!*src) break;
|
||||
*out = *src;
|
||||
++out;
|
||||
++src;
|
||||
--n;
|
||||
}
|
||||
return out;
|
||||
}
|
@ -56,7 +56,7 @@ static long secs_of_month(int months, int year) {
|
||||
return days * SEC_DAY;
|
||||
}
|
||||
|
||||
struct tm *localtime(const time_t *timep) {
|
||||
struct tm *localtime_r(const time_t *timep, struct tm * _timevalue) {
|
||||
|
||||
fprintf(stderr, "Hello world?\n");
|
||||
|
||||
@ -71,7 +71,7 @@ struct tm *localtime(const time_t *timep) {
|
||||
long secs = added * 86400;
|
||||
|
||||
if (seconds + secs >= *timep) {
|
||||
_timevalue.tm_year = year - 1900;
|
||||
_timevalue->tm_year = year - 1900;
|
||||
year_sec = seconds;
|
||||
fprintf(stderr, "The year is %d, year_sec=%d\n", year, year_sec);
|
||||
for (int month = 1; month <= 12; ++month) {
|
||||
@ -80,24 +80,24 @@ struct tm *localtime(const time_t *timep) {
|
||||
fprintf(stderr, "%d vs %d\n", seconds + secs, *timep);
|
||||
if (seconds + secs >= *timep) {
|
||||
fprintf(stderr, "The month is %d.\n", month);
|
||||
_timevalue.tm_mon = month - 1;
|
||||
_timevalue->tm_mon = month - 1;
|
||||
for (int day = 1; day <= days_in_month(month, year); ++day) {
|
||||
secs = 60 * 60 * 24;
|
||||
fprintf(stderr, "Checking day %d, %d vs . %d\n", day, seconds + secs, *timep);
|
||||
if (seconds + secs >= *timep) {
|
||||
fprintf(stderr, "The day is %d.\n", day);
|
||||
_timevalue.tm_mday = day;
|
||||
_timevalue->tm_mday = day;
|
||||
for (int hour = 1; hour <= 24; ++hour) {
|
||||
secs = 60 * 60;
|
||||
if (seconds + secs >= *timep) {
|
||||
long remaining = *timep - seconds;
|
||||
_timevalue.tm_hour = hour-1;
|
||||
_timevalue.tm_min = remaining / 60;
|
||||
_timevalue.tm_sec = remaining % 60; // can be 60 on a leap second, ignore that
|
||||
_timevalue.tm_wday = day_of_week(*timep); // oh shit
|
||||
_timevalue.tm_yday = (*timep - year_sec) / SEC_DAY;
|
||||
_timevalue.tm_isdst = 0; // never because UTC
|
||||
return &_timevalue;
|
||||
_timevalue->tm_hour = hour-1;
|
||||
_timevalue->tm_min = remaining / 60;
|
||||
_timevalue->tm_sec = remaining % 60; // can be 60 on a leap second, ignore that
|
||||
_timevalue->tm_wday = day_of_week(*timep); // oh shit
|
||||
_timevalue->tm_yday = (*timep - year_sec) / SEC_DAY;
|
||||
_timevalue->tm_isdst = 0; // never because UTC
|
||||
return _timevalue;
|
||||
} else {
|
||||
seconds += secs;
|
||||
}
|
||||
@ -150,6 +150,15 @@ time_t mktime(struct tm *tm) {
|
||||
|
||||
}
|
||||
|
||||
struct tm * gmtime_r(const time_t * timep, struct tm * tm) {
|
||||
return localtime_r(timep, tm);
|
||||
}
|
||||
|
||||
struct tm * localtime(const time_t *timep) {
|
||||
return localtime_r(timep, &_timevalue);
|
||||
}
|
||||
|
||||
struct tm *gmtime(const time_t *timep) {
|
||||
return localtime(timep);
|
||||
}
|
||||
|
||||
|
@ -6,3 +6,7 @@ DEFN_SYSCALL2(dup2, 22, int, int);
|
||||
int dup2(int oldfd, int newfd) {
|
||||
return syscall_dup2(oldfd, newfd);
|
||||
}
|
||||
|
||||
int dup(int oldfd) {
|
||||
return dup2(oldfd, -1);
|
||||
}
|
||||
|
@ -47,3 +47,7 @@ int execvp(const char *file, char *const argv[]) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int execv(const char * file, char * const argv[]) {
|
||||
return execve(file, argv, environ);
|
||||
}
|
||||
|
@ -1,8 +1,15 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <syscall.h>
|
||||
#include <syscall_nums.h>
|
||||
|
||||
DEFN_SYSCALL0(getpid, 9);
|
||||
DEFN_SYSCALL0(getpid, SYS_GETPID);
|
||||
|
||||
pid_t getpid(void) {
|
||||
return syscall_getpid();
|
||||
}
|
||||
|
||||
pid_t getppid(void) {
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
||||
|
7
libc/unistd/rmdir.c
Normal file
7
libc/unistd/rmdir.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
int rmdir(const char *pathname) {
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
7
libc/unistd/ttyname.c
Normal file
7
libc/unistd/ttyname.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
char * ttyname(int fd) {
|
||||
errno = ENOTSUP;
|
||||
return NULL;
|
||||
}
|
9
libc/unistd/umask.c
Normal file
9
libc/unistd/umask.c
Normal file
@ -0,0 +1,9 @@
|
||||
#include <unistd.h>
|
||||
#include <syscall.h>
|
||||
#include <syscall_nums.h>
|
||||
|
||||
DEFN_SYSCALL1(umask, SYS_UMASK, int);
|
||||
|
||||
mode_t umask(mode_t mask) {
|
||||
return syscall_umask(mask);
|
||||
}
|
8
libc/unistd/utime.c
Normal file
8
libc/unistd/utime.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
int utime(const char *filename, const struct utimbuf *times) {
|
||||
/* Unimplemented */
|
||||
errno = ENOTSUP;
|
||||
return -1;
|
||||
}
|
21
libc/wchar/wcs.c
Normal file
21
libc/wchar/wcs.c
Normal file
@ -0,0 +1,21 @@
|
||||
#include <wchar.h>
|
||||
|
||||
size_t wcstombs(char * dest, const wchar_t *src, size_t n) {
|
||||
/* TODO */
|
||||
size_t c = 0;
|
||||
while (c < n && *src) {
|
||||
*dest = *src;
|
||||
c++;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
size_t mbstowcs(wchar_t * dest, const char *src, size_t n) {
|
||||
/* TODO */
|
||||
size_t c = 0;
|
||||
while (c < n && *src) {
|
||||
*dest = *src;
|
||||
c++;
|
||||
}
|
||||
return c;
|
||||
}
|
@ -13,3 +13,23 @@ wchar_t * wcscat(wchar_t *dest, const wchar_t *src) {
|
||||
*end = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
wchar_t * wcsncat(wchar_t *dest, const wchar_t * src, size_t n) {
|
||||
wchar_t * end = dest;
|
||||
size_t c = 0;
|
||||
while (*end != 0) {
|
||||
++end;
|
||||
c++;
|
||||
}
|
||||
if (c >= n) return dest;
|
||||
|
||||
while (*src && c < n) {
|
||||
*end = *src;
|
||||
end++;
|
||||
src++;
|
||||
c++;
|
||||
}
|
||||
*end = 0;
|
||||
return dest;
|
||||
|
||||
}
|
||||
|
74
libc/wchar/wcstok.c
Normal file
74
libc/wchar/wcstok.c
Normal file
@ -0,0 +1,74 @@
|
||||
#include <wchar.h>
|
||||
|
||||
size_t wcsspn(const wchar_t * wcs, const wchar_t * accept) {
|
||||
size_t out = 0;
|
||||
|
||||
while (*wcs) {
|
||||
int good = 0;
|
||||
for (const wchar_t * a = accept; *a; ++a) {
|
||||
if (*wcs == *a) {
|
||||
good = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!good) break;
|
||||
out++;
|
||||
wcs++;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
wchar_t *wcspbrk(const wchar_t *wcs, const wchar_t *accept) {
|
||||
while (*wcs) {
|
||||
for (const wchar_t * a = accept; *a; ++a) {
|
||||
if (*wcs == *a) {
|
||||
return (wchar_t *)wcs;
|
||||
}
|
||||
}
|
||||
wcs++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wchar_t * wcschr(const wchar_t *wcs, wchar_t wc) {
|
||||
while (*wcs != wc && *wcs != L'0') {
|
||||
wcs++;
|
||||
}
|
||||
if (!*wcs) return NULL;
|
||||
return (wchar_t *)wcs;
|
||||
}
|
||||
|
||||
wchar_t * wcsrchr(const wchar_t *wcs, wchar_t wc) {
|
||||
wchar_t * last = NULL;
|
||||
while (*wcs != L'0') {
|
||||
if (*wcs == wc) {
|
||||
last = (wchar_t *)wcs;
|
||||
}
|
||||
wcs++;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
|
||||
wchar_t * wcstok(wchar_t * str, const wchar_t * delim, wchar_t ** saveptr) {
|
||||
wchar_t * token;
|
||||
if (str == NULL) {
|
||||
str = *saveptr;
|
||||
}
|
||||
str += wcsspn(str, delim);
|
||||
if (*str == '\0') {
|
||||
*saveptr = str;
|
||||
return NULL;
|
||||
}
|
||||
token = str;
|
||||
str = wcspbrk(token, delim);
|
||||
if (str == NULL) {
|
||||
*saveptr = (wchar_t *)wcschr(token, '\0');
|
||||
} else {
|
||||
*str = '\0';
|
||||
*saveptr = str + 1;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user