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
|
util/local
|
||||||
.gdb_history
|
.gdb_history
|
||||||
kernel/symbols.S
|
kernel/symbols.S
|
||||||
|
base/usr/python
|
||||||
|
@ -27,3 +27,5 @@ extern double log2(double x);
|
|||||||
extern double sinh(double x);
|
extern double sinh(double x);
|
||||||
extern double tan(double x);
|
extern double tan(double x);
|
||||||
extern double tanh(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 * strpbrk(const char * s, const char * b);
|
||||||
extern char * strstr(const char * h, const char * n);
|
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 strcmp(const char * l, const char * r);
|
||||||
extern int strncmp(const char *s1, const char *s2, size_t n);
|
extern int strncmp(const char *s1, const char *s2, size_t n);
|
||||||
extern int strcoll(const char * s1, const char * s2);
|
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 *localtime(const time_t *timep);
|
||||||
extern struct tm *gmtime(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 size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
|
||||||
extern time_t time(time_t * out);
|
extern time_t time(time_t * out);
|
||||||
extern double difftime(time_t a, time_t b);
|
extern double difftime(time_t a, time_t b);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
extern char **environ;
|
extern char **environ;
|
||||||
|
|
||||||
extern pid_t getpid(void);
|
extern pid_t getpid(void);
|
||||||
|
extern pid_t getppid(void);
|
||||||
|
|
||||||
extern int close(int fd);
|
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 ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);
|
||||||
|
|
||||||
extern int chdir(const char *path);
|
extern int chdir(const char *path);
|
||||||
extern int fchdir(int fd);
|
//extern int fchdir(int fd);
|
||||||
extern int isatty(int fd);
|
extern int isatty(int fd);
|
||||||
|
|
||||||
extern unsigned int sleep(unsigned int seconds);
|
extern unsigned int sleep(unsigned int seconds);
|
||||||
@ -56,6 +57,15 @@ extern int optind, opterr, optopt;
|
|||||||
|
|
||||||
extern int unlink(const char * pathname);
|
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 STDIN_FILENO 0
|
||||||
#define STDOUT_FILENO 1
|
#define STDOUT_FILENO 1
|
||||||
#define STDERR_FILENO 2
|
#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 size_t wcslen(const wchar_t * s);
|
||||||
extern int wcscmp(const wchar_t *s1, const wchar_t *s2);
|
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 * 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;
|
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_SYSCALL3(ioctl, 47, int, int, void *);
|
||||||
DEFN_SYSCALL2(access, 48, char *, int);
|
DEFN_SYSCALL2(access, 48, char *, int);
|
||||||
DEFN_SYSCALL2(stat, 49, char *, void *);
|
DEFN_SYSCALL2(stat, 49, char *, void *);
|
||||||
DEFN_SYSCALL1(umask, 51, int);
|
|
||||||
DEFN_SYSCALL3(waitpid, 53, int, int *, int);
|
DEFN_SYSCALL3(waitpid, 53, int, int *, int);
|
||||||
DEFN_SYSCALL5(mount, SYS_MOUNT, char *, char *, char *, unsigned long, void *);
|
DEFN_SYSCALL5(mount, SYS_MOUNT, char *, char *, char *, unsigned long, void *);
|
||||||
DEFN_SYSCALL2(lstat, SYS_LSTAT, char *, 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;
|
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");
|
fprintf(stderr, "Hello world?\n");
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ struct tm *localtime(const time_t *timep) {
|
|||||||
long secs = added * 86400;
|
long secs = added * 86400;
|
||||||
|
|
||||||
if (seconds + secs >= *timep) {
|
if (seconds + secs >= *timep) {
|
||||||
_timevalue.tm_year = year - 1900;
|
_timevalue->tm_year = year - 1900;
|
||||||
year_sec = seconds;
|
year_sec = seconds;
|
||||||
fprintf(stderr, "The year is %d, year_sec=%d\n", year, year_sec);
|
fprintf(stderr, "The year is %d, year_sec=%d\n", year, year_sec);
|
||||||
for (int month = 1; month <= 12; ++month) {
|
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);
|
fprintf(stderr, "%d vs %d\n", seconds + secs, *timep);
|
||||||
if (seconds + secs >= *timep) {
|
if (seconds + secs >= *timep) {
|
||||||
fprintf(stderr, "The month is %d.\n", month);
|
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) {
|
for (int day = 1; day <= days_in_month(month, year); ++day) {
|
||||||
secs = 60 * 60 * 24;
|
secs = 60 * 60 * 24;
|
||||||
fprintf(stderr, "Checking day %d, %d vs . %d\n", day, seconds + secs, *timep);
|
fprintf(stderr, "Checking day %d, %d vs . %d\n", day, seconds + secs, *timep);
|
||||||
if (seconds + secs >= *timep) {
|
if (seconds + secs >= *timep) {
|
||||||
fprintf(stderr, "The day is %d.\n", day);
|
fprintf(stderr, "The day is %d.\n", day);
|
||||||
_timevalue.tm_mday = day;
|
_timevalue->tm_mday = day;
|
||||||
for (int hour = 1; hour <= 24; ++hour) {
|
for (int hour = 1; hour <= 24; ++hour) {
|
||||||
secs = 60 * 60;
|
secs = 60 * 60;
|
||||||
if (seconds + secs >= *timep) {
|
if (seconds + secs >= *timep) {
|
||||||
long remaining = *timep - seconds;
|
long remaining = *timep - seconds;
|
||||||
_timevalue.tm_hour = hour-1;
|
_timevalue->tm_hour = hour-1;
|
||||||
_timevalue.tm_min = remaining / 60;
|
_timevalue->tm_min = remaining / 60;
|
||||||
_timevalue.tm_sec = remaining % 60; // can be 60 on a leap second, ignore that
|
_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_wday = day_of_week(*timep); // oh shit
|
||||||
_timevalue.tm_yday = (*timep - year_sec) / SEC_DAY;
|
_timevalue->tm_yday = (*timep - year_sec) / SEC_DAY;
|
||||||
_timevalue.tm_isdst = 0; // never because UTC
|
_timevalue->tm_isdst = 0; // never because UTC
|
||||||
return &_timevalue;
|
return _timevalue;
|
||||||
} else {
|
} else {
|
||||||
seconds += secs;
|
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) {
|
struct tm *gmtime(const time_t *timep) {
|
||||||
return localtime(timep);
|
return localtime(timep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,3 +6,7 @@ DEFN_SYSCALL2(dup2, 22, int, int);
|
|||||||
int dup2(int oldfd, int newfd) {
|
int dup2(int oldfd, int newfd) {
|
||||||
return syscall_dup2(oldfd, 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;
|
errno = ENOENT;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int execv(const char * file, char * const argv[]) {
|
||||||
|
return execve(file, argv, environ);
|
||||||
|
}
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <syscall.h>
|
#include <syscall.h>
|
||||||
|
#include <syscall_nums.h>
|
||||||
|
|
||||||
DEFN_SYSCALL0(getpid, 9);
|
DEFN_SYSCALL0(getpid, SYS_GETPID);
|
||||||
|
|
||||||
pid_t getpid(void) {
|
pid_t getpid(void) {
|
||||||
return syscall_getpid();
|
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;
|
*end = 0;
|
||||||
return dest;
|
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