diff --git a/.gitignore b/.gitignore index 119c748d..e236766e 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ util/build util/local .gdb_history kernel/symbols.S +base/usr/python diff --git a/base/usr/include/math.h b/base/usr/include/math.h index a21f8322..75e15c9e 100644 --- a/base/usr/include/math.h +++ b/base/usr/include/math.h @@ -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); diff --git a/base/usr/include/string.h b/base/usr/include/string.h index 11930d7e..52b01631 100644 --- a/base/usr/include/string.h +++ b/base/usr/include/string.h @@ -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); diff --git a/base/usr/include/time.h b/base/usr/include/time.h index 32d60c45..d5600667 100644 --- a/base/usr/include/time.h +++ b/base/usr/include/time.h @@ -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); diff --git a/base/usr/include/unistd.h b/base/usr/include/unistd.h index b6bb5103..9b297ebe 100644 --- a/base/usr/include/unistd.h +++ b/base/usr/include/unistd.h @@ -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 diff --git a/base/usr/include/wchar.h b/base/usr/include/wchar.h index 3137d0d7..0261201c 100644 --- a/base/usr/include/wchar.h +++ b/base/usr/include/wchar.h @@ -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; diff --git a/libc/main.c b/libc/main.c index 67aa8ecd..3730ead0 100644 --- a/libc/main.c +++ b/libc/main.c @@ -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 *); diff --git a/libc/math/modf.c b/libc/math/modf.c new file mode 100644 index 00000000..11191a4d --- /dev/null +++ b/libc/math/modf.c @@ -0,0 +1,7 @@ +#include + +double modf(double x, double *iptr) { + int i = (int)x; + *iptr = (double)i; + return x - i; +} diff --git a/libc/string/strncpy.c b/libc/string/strncpy.c new file mode 100644 index 00000000..a665b87d --- /dev/null +++ b/libc/string/strncpy.c @@ -0,0 +1,13 @@ +#include + +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; +} diff --git a/libc/time/localtime.c b/libc/time/localtime.c index 29332135..1245a081 100644 --- a/libc/time/localtime.c +++ b/libc/time/localtime.c @@ -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); } + diff --git a/libc/unistd/dup2.c b/libc/unistd/dup2.c index e3398dcd..5f4fceca 100644 --- a/libc/unistd/dup2.c +++ b/libc/unistd/dup2.c @@ -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); +} diff --git a/libc/unistd/execvp.c b/libc/unistd/execvp.c index f4b04f15..570a4ddc 100644 --- a/libc/unistd/execvp.c +++ b/libc/unistd/execvp.c @@ -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); +} diff --git a/libc/unistd/getpid.c b/libc/unistd/getpid.c index 447161b3..7ecc84dc 100644 --- a/libc/unistd/getpid.c +++ b/libc/unistd/getpid.c @@ -1,8 +1,15 @@ #include +#include #include +#include -DEFN_SYSCALL0(getpid, 9); +DEFN_SYSCALL0(getpid, SYS_GETPID); pid_t getpid(void) { return syscall_getpid(); } + +pid_t getppid(void) { + errno = ENOTSUP; + return -1; +} diff --git a/libc/unistd/rmdir.c b/libc/unistd/rmdir.c new file mode 100644 index 00000000..01a48d33 --- /dev/null +++ b/libc/unistd/rmdir.c @@ -0,0 +1,7 @@ +#include +#include + +int rmdir(const char *pathname) { + errno = ENOTSUP; + return -1; +} diff --git a/libc/unistd/ttyname.c b/libc/unistd/ttyname.c new file mode 100644 index 00000000..ecf2fe93 --- /dev/null +++ b/libc/unistd/ttyname.c @@ -0,0 +1,7 @@ +#include +#include + +char * ttyname(int fd) { + errno = ENOTSUP; + return NULL; +} diff --git a/libc/unistd/umask.c b/libc/unistd/umask.c new file mode 100644 index 00000000..13f7665f --- /dev/null +++ b/libc/unistd/umask.c @@ -0,0 +1,9 @@ +#include +#include +#include + +DEFN_SYSCALL1(umask, SYS_UMASK, int); + +mode_t umask(mode_t mask) { + return syscall_umask(mask); +} diff --git a/libc/unistd/utime.c b/libc/unistd/utime.c new file mode 100644 index 00000000..96b080c1 --- /dev/null +++ b/libc/unistd/utime.c @@ -0,0 +1,8 @@ +#include +#include + +int utime(const char *filename, const struct utimbuf *times) { + /* Unimplemented */ + errno = ENOTSUP; + return -1; +} diff --git a/libc/wchar/wcs.c b/libc/wchar/wcs.c new file mode 100644 index 00000000..ab52aa28 --- /dev/null +++ b/libc/wchar/wcs.c @@ -0,0 +1,21 @@ +#include + +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; +} diff --git a/libc/wchar/wcscat.c b/libc/wchar/wcscat.c index 0e553949..8ef8a8bd 100644 --- a/libc/wchar/wcscat.c +++ b/libc/wchar/wcscat.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; + +} diff --git a/libc/wchar/wcstok.c b/libc/wchar/wcstok.c new file mode 100644 index 00000000..19e71a60 --- /dev/null +++ b/libc/wchar/wcstok.c @@ -0,0 +1,74 @@ +#include + +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; +} + +