From 8bca4ee6c892a358d9e3255a466347b672348f54 Mon Sep 17 00:00:00 2001 From: "K. Lange" Date: Sat, 18 Sep 2021 13:30:47 +0900 Subject: [PATCH] libc: cleanup, some missing things --- base/usr/include/time.h | 1 + base/usr/include/unistd.h | 10 ++-- base/usr/include/utime.h | 15 ++++++ base/usr/include/wchar.h | 6 +++ libc/time/clock_gettime.c | 11 ++++ libc/unistd/getpgrp.c | 3 +- libc/unistd/ttyname.c | 8 +++ libc/{unistd => utime}/utime.c | 2 +- libc/wchar/wcscmp.c | 11 ++++ libc/wchar/wcstol.c | 95 ++++++++++++++++++++++++++++++++++ 10 files changed, 153 insertions(+), 9 deletions(-) create mode 100644 base/usr/include/utime.h rename libc/{unistd => utime}/utime.c (87%) create mode 100644 libc/wchar/wcstol.c diff --git a/base/usr/include/time.h b/base/usr/include/time.h index c8f0b3466..fa886e6a1 100644 --- a/base/usr/include/time.h +++ b/base/usr/include/time.h @@ -49,5 +49,6 @@ typedef int clockid_t; #define CLOCK_MONOTONIC 1 extern int clock_gettime(clockid_t clk_id, struct timespec *tp); +extern int clock_getres(clockid_t clk_id, struct timespec *res); _End_C_Header diff --git a/base/usr/include/unistd.h b/base/usr/include/unistd.h index f48632991..ad1320f66 100644 --- a/base/usr/include/unistd.h +++ b/base/usr/include/unistd.h @@ -66,15 +66,12 @@ 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 */ extern int chown(const char * pathname, uid_t owner, gid_t group); + extern char * getlogin(void); +extern char * ttyname(int fd); +extern int ttyname_r(int fd, char * buf, size_t buflen); #define STDIN_FILENO 0 #define STDOUT_FILENO 1 @@ -95,6 +92,7 @@ extern int sethostname(const char * name, size_t len); extern pid_t setsid(void); extern int setpgid(pid_t, pid_t); extern pid_t getpgid(pid_t); +extern pid_t getpgrp(void); extern unsigned int alarm(unsigned int seconds); diff --git a/base/usr/include/utime.h b/base/usr/include/utime.h new file mode 100644 index 000000000..5c833a9f3 --- /dev/null +++ b/base/usr/include/utime.h @@ -0,0 +1,15 @@ +#pragma once + +#include <_cheader.h> +#include + +_Begin_C_Header + +struct utimbuf { + time_t actime; + time_t modtime; +}; + +extern int utime(const char *filename, const struct utimbuf *times); + +_End_C_Header diff --git a/base/usr/include/wchar.h b/base/usr/include/wchar.h index a82baa7c6..a79c5bece 100644 --- a/base/usr/include/wchar.h +++ b/base/usr/include/wchar.h @@ -15,6 +15,12 @@ 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); +extern int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n); +extern wchar_t * wcscpy(wchar_t * dest, const wchar_t * src); +extern unsigned long int wcstoul(const wchar_t *nptr, wchar_t **endptr, int base); +extern unsigned long long int wcstoull(const char *nptr, wchar_t **endptr, int base); +extern long int wcstol(const wchar_t *nptr, wchar_t **endptr, int base); +extern long long int wcstoll(const wchar_t *nptr, wchar_t **endptr, int base); typedef unsigned int wint_t; _End_C_Header diff --git a/libc/time/clock_gettime.c b/libc/time/clock_gettime.c index 5d69a0d60..068df394e 100644 --- a/libc/time/clock_gettime.c +++ b/libc/time/clock_gettime.c @@ -2,6 +2,17 @@ #include #include +int clock_getres(clockid_t clk_id, struct timespec *res) { + if (clk_id < 0 || clk_id > 1) { + errno = EINVAL; + return -1; + } + + res->tv_sec = 0; + res->tv_nsec = 1000; + return 0; +} + int clock_gettime(clockid_t clk_id, struct timespec *tp) { if (clk_id < 0 || clk_id > 1) { errno = EINVAL; diff --git a/libc/unistd/getpgrp.c b/libc/unistd/getpgrp.c index 94e8c5d48..54732070f 100644 --- a/libc/unistd/getpgrp.c +++ b/libc/unistd/getpgrp.c @@ -1,6 +1,5 @@ #include int getpgrp() { - /* XXX */ - return getgid(); + return getpgid(0); } diff --git a/libc/unistd/ttyname.c b/libc/unistd/ttyname.c index 8d1d83e79..5a922af1d 100644 --- a/libc/unistd/ttyname.c +++ b/libc/unistd/ttyname.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -15,3 +16,10 @@ char * ttyname(int fd) { return _tty_name; } + +int ttyname_r(int fd, char * buf, size_t buflen) { + if (!isatty(fd)) return ENOTTY; + if (buflen < 30) return ERANGE; + ioctl(fd, IOCTLTTYNAME, buf); + return 0; +} diff --git a/libc/unistd/utime.c b/libc/utime/utime.c similarity index 87% rename from libc/unistd/utime.c rename to libc/utime/utime.c index 96b080c18..7ba29c8d2 100644 --- a/libc/unistd/utime.c +++ b/libc/utime/utime.c @@ -1,4 +1,4 @@ -#include +#include #include int utime(const char *filename, const struct utimbuf *times) { diff --git a/libc/wchar/wcscmp.c b/libc/wchar/wcscmp.c index e2b4c3c41..05928f3d2 100644 --- a/libc/wchar/wcscmp.c +++ b/libc/wchar/wcscmp.c @@ -4,3 +4,14 @@ int wcscmp(const wchar_t *l, const wchar_t *r) { for (; *l == *r && *l; l++, r++); return *(unsigned int *)l - *(unsigned int *)r; } + +int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n) { + if (n == 0) return 0; + + while (n-- && *s1 == *s2) { + if (!n || !*s1) break; + s1++; + s2++; + } + return (*s1) - (*s2); +} diff --git a/libc/wchar/wcstol.c b/libc/wchar/wcstol.c new file mode 100644 index 000000000..b3d805c8b --- /dev/null +++ b/libc/wchar/wcstol.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include + +static int is_valid(int base, wchar_t c) { + if (c < '0') return 0; + if (base <= 10) { + return c < ('0' + base); + } + + if (c >= 'a' && c < 'a' + (base - 10)) return 1; + if (c >= 'A' && c < 'A' + (base - 10)) return 1; + if (c >= '0' && c <= '9') return 1; + return 0; +} + +static int convert_digit(wchar_t c) { + if (c >= '0' && c <= '9') { + return c - '0'; + } + if (c >= 'a' && c <= 'z') { + return c - 'a' + 0xa; + } + if (c >= 'A' && c <= 'Z') { + return c - 'A' + 0xa; + } + return 0; +} + +#define strtox(max, type) \ + if (base < 0 || base == 1 || base > 36) { \ + errno = EINVAL; \ + return max; \ + } \ + while (*nptr && isspace(*nptr)) nptr++; \ + int sign = 1; \ + if (*nptr == '-') { \ + sign = -1; \ + nptr++; \ + } else if (*nptr == '+') { \ + nptr++; \ + } \ + if (base == 16) { \ + if (*nptr == '0') { \ + nptr++; \ + if (*nptr == 'x') { \ + nptr++; \ + } \ + } \ + } \ + if (base == 0) { \ + if (*nptr == '0') { \ + base = 8; \ + nptr++; \ + if (*nptr == 'x') { \ + base = 16; \ + nptr++; \ + } \ + } else { \ + base = 10; \ + } \ + } \ + type val = 0; \ + while (is_valid(base, *nptr)) { \ + val *= base; \ + val += convert_digit(*nptr); \ + nptr++; \ + } \ + if (endptr) { \ + *endptr = (wchar_t *)nptr; \ + } \ + if (sign == -1) { \ + return -val; \ + } else { \ + return val; \ + } + +unsigned long int wcstoul(const wchar_t *nptr, wchar_t **endptr, int base) { + strtox(ULONG_MAX, unsigned long int); +} + +unsigned long long int wcstoull(const char *nptr, wchar_t **endptr, int base) { + strtox(ULLONG_MAX, unsigned long int); +} + +long int wcstol(const wchar_t *nptr, wchar_t **endptr, int base) { + strtox(LONG_MAX, unsigned long int); +} + +long long int wcstoll(const wchar_t *nptr, wchar_t **endptr, int base) { + strtox(LLONG_MAX, unsigned long long int); +} +