From e6584db26da34572fb13aa236e16e19f71c8e976 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Fri, 26 Aug 2022 14:16:16 +0200 Subject: user/libc: prepare for OpenED port --- src/user/lib/ctype.c | 9 ++ src/user/lib/elfload.c | 1 + src/user/lib/file.c | 256 --------------------------------- src/user/lib/file.h | 10 -- src/user/lib/include/ctype.h | 3 + src/user/lib/include/err.h | 0 src/user/lib/include/limits.h | 5 + src/user/lib/include/pwd.h | 0 src/user/lib/include/setjmp.h | 13 ++ src/user/lib/include/signal.h | 17 +++ src/user/lib/include/stdio.h | 27 ++++ src/user/lib/include/stdlib.h | 5 + src/user/lib/include/string.h | 2 + src/user/lib/include/sys/ioctl.h | 13 ++ src/user/lib/include/sys/stat.h | 11 ++ src/user/lib/include/sys/wait.h | 0 src/user/lib/include/unistd.h | 4 + src/user/lib/panic.h | 5 + src/user/lib/stdio/file.c | 304 +++++++++++++++++++++++++++++++++++++++ src/user/lib/stdio/file.h | 10 ++ src/user/lib/stdio/misc.c | 25 ++++ src/user/lib/stdlib.c | 32 +++++ src/user/lib/string.c | 9 ++ src/user/lib/unistd.c | 19 ++- 24 files changed, 509 insertions(+), 271 deletions(-) delete mode 100644 src/user/lib/file.c delete mode 100644 src/user/lib/file.h create mode 100644 src/user/lib/include/err.h create mode 100644 src/user/lib/include/limits.h create mode 100644 src/user/lib/include/pwd.h create mode 100644 src/user/lib/include/setjmp.h create mode 100644 src/user/lib/include/signal.h create mode 100644 src/user/lib/include/sys/ioctl.h create mode 100644 src/user/lib/include/sys/stat.h create mode 100644 src/user/lib/include/sys/wait.h create mode 100644 src/user/lib/panic.h create mode 100644 src/user/lib/stdio/file.c create mode 100644 src/user/lib/stdio/file.h create mode 100644 src/user/lib/stdio/misc.c create mode 100644 src/user/lib/stdlib.c (limited to 'src/user') diff --git a/src/user/lib/ctype.c b/src/user/lib/ctype.c index b702703..7d3a707 100644 --- a/src/user/lib/ctype.c +++ b/src/user/lib/ctype.c @@ -29,3 +29,12 @@ int isupper(int c) { return 'A' <= c && c <= 'Z'; } +int tolower(int c) { + if (isupper(c)) return c - 'A' + 'a'; + return c; +} + +int toupper(int c) { + if (islower(c)) return c - 'a' + 'A'; + return c; +} diff --git a/src/user/lib/elfload.c b/src/user/lib/elfload.c index b4987f4..4fcc1db 100644 --- a/src/user/lib/elfload.c +++ b/src/user/lib/elfload.c @@ -92,6 +92,7 @@ void _freejmp(void *entry, void *low, size_t imglen, char **argv, char **envp) { argc++; } len = sizeof(char*) * argc; + *--(stack.ptr) = NULL; /* NULL terminate argv */ stack.b -= len; memcpy(stack.b, argv, len); argv = stack.b; diff --git a/src/user/lib/file.c b/src/user/lib/file.c deleted file mode 100644 index f2b74b1..0000000 --- a/src/user/lib/file.c +++ /dev/null @@ -1,256 +0,0 @@ -#include "file.h" -#include -#include -#include -#include -#include -#include -#include - -static FILE _stdin_null = { .fd = 0 }; -static FILE _stdout_null = { .fd = 1 }; -static FILE _stderr_null = { .fd = 2 }; -FILE *const stdin = &_stdin_null; -FILE *const stdout = &_stdout_null; -FILE *const stderr = &_stderr_null; - - -FILE *fopen(const char *path, const char *mode) { - FILE *f; - handle_t h; - int flags = 0; - char *tmppath = NULL; - if (!path) { - errno = -1; - return NULL; - } else if (path[0] == '!') { - /* special handling for "!files" */ - path++; - if (!strcmp(path, "stdin")) return file_clone(stdin, mode); - if (!strcmp(path, "stdout")) return file_clone(stdout, mode); - if (!strcmp(path, "stderr")) return file_clone(stderr, mode); - errno = -1; - return NULL; - } - - if (path && path[0] != '/') { - size_t len = absolutepath(NULL, path, 0); - tmppath = malloc(len); - if (!tmppath) return NULL; - absolutepath(tmppath, path, len); - path = tmppath; - } - - if (mode[0] == 'w' || mode[0] == 'a') - flags |= OPEN_CREATE; - - h = _syscall_open(path, strlen(path), flags); - if (tmppath) free(tmppath); - if (h < 0) { - errno = -h; - return NULL; - } - - if (mode[0] == 'w') - _syscall_write(h, NULL, 0, 0, WRITE_TRUNCATE); - - f = fdopen(h, mode); - if (!f) close(h); - return f; -} - - FILE *freopen(const char *path, const char *mode, FILE *f) { - /* partially based on the musl implementation of freopen */ - FILE *f2; - if (!path) goto fail; - f2 = fopen(path, mode); - if (!f2) goto fail; - - if (f->fd == f2->fd) { - f2->fd = -1; - } else { - if (_syscall_dup(f2->fd, f->fd, 0) < 0) goto fail2; - } - f->pos = f2->pos; - f->eof = f2->eof; - fclose(f2); - return f; - -fail2: - fclose(f2); -fail: - fclose(f); - return NULL; -} - -FILE *fdopen(int fd, const char *mode) { - FILE *f; - f = malloc(sizeof *f); - if (!f) return NULL; - f->fd = fd; - f->pos = mode[0] == 'a' ? -1 : 0; - f->eof = false; - f->error = false; - f->extflags = 0; - return f; -} - -FILE *file_clone(const FILE *f, const char *mode) { - handle_t h = _syscall_dup(f->fd, -1, 0); - FILE *f2; - if (h < 0) return NULL; - - f2 = fdopen(h, mode); - if (!f2) { - close(h); - return NULL; - } - f2->pos = f->pos; - f2->eof = f->eof; - f2->fd = h; - return f2; -} - -int fextflags(FILE *f, int extflags) { - int old = f->extflags; - f->extflags = extflags; - return old; -} - -static void fadvance(long amt, FILE *f) { - bool pos_neg = f->pos < 0; - f->pos += amt; - if (pos_neg && f->pos >= 0) - f->pos = -1; -} - -size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict f) { - size_t total = size*nitems, pos = 0; - unsigned char *buf = ptr; - - if (f->fd < 0) { - errno = EBADF; - return 0; - } - if (size == 0) - return 0; - - while (pos < total) { - long res = _syscall_read(f->fd, buf + pos, total - pos, f->pos); - if (res < 0) { - f->error = true; - errno = -res; - break; - } else if (res == 0) { - f->eof = true; - break; - } - pos += res; - fadvance(res, f); - if (f->extflags & FEXT_NOFILL) break; - } - return pos == total ? nitems : (pos/size); -} - -size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict f) { - size_t total = size*nitems, pos = 0; - const unsigned char *buf = ptr; - - if (f->fd < 0) { - errno = EBADF; - return 0; - } - if (size == 0) - return 0; - - while (pos < total) { - long res = _syscall_write(f->fd, buf + pos, total - pos, f->pos, 0); - if (res < 0) { - f->error = true; - errno = -res; - return pos/size; - } else if (res == 0) { - f->eof = true; - return pos/size; - } else { - pos += res; - fadvance(res, f); - } - } - return nitems; -} - -char *fgets(char *buf, int size, FILE *f) { - char c = '\0'; - long pos = 0; - while (pos < (size-1) && c != '\n' && fread(&c, 1, 1, f)) - buf[pos++] = c; - buf[pos++] = '\0'; - - if (f->eof && pos == 1) return NULL; - if (f->error) return NULL; - return buf; -} - -int fseek(FILE *f, long offset, int whence) { - if (fflush(f)) - return -1; - - long base; - switch (whence) { - case SEEK_SET: - base = 0; - break; - case SEEK_CUR: - base = f->pos; - break; - case SEEK_END: - base = _syscall_getsize(f->fd); - if (base < 0) - base = -1; - break; - default: - errno = EINVAL; - return -1; - } - - if (base >= 0 && base + offset < 0) { - /* underflow */ - errno = EINVAL; - return -1; - } else if (base < 0 && base + offset >= 0) { - /* overflow - went from a negative offset (relative to EOF) - * to a positive offset (from start of file). - * can only happen when getsize() is unsupported */ - errno = EINVAL; - return -1; - } - f->pos = base + offset; - f->eof = false; - return 0; -} - -long ftell(FILE *f) { - return f->pos; -} - -int fclose(FILE *f) { - fflush(f); - if (f->fd > 0) close(f->fd); - if (f != &_stdin_null && f != &_stdout_null && f != &_stderr_null) - free(f); - return 0; -} - -int fflush(FILE *f) { - (void)f; - return 0; -} - -int feof(FILE *f) { - return f->eof; -} - -int ferror(FILE *f) { - return f->error; -} diff --git a/src/user/lib/file.h b/src/user/lib/file.h deleted file mode 100644 index 604b070..0000000 --- a/src/user/lib/file.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include - -struct _LIBC_FILE { - int fd; - long pos; - bool eof; - bool error; - int extflags; -}; diff --git a/src/user/lib/include/ctype.h b/src/user/lib/include/ctype.h index 4b15b1d..cbba529 100644 --- a/src/user/lib/include/ctype.h +++ b/src/user/lib/include/ctype.h @@ -6,3 +6,6 @@ int isdigit(int c); int islower(int c); int isspace(int c); int isupper(int c); + +int tolower(int c); +int toupper(int c); diff --git a/src/user/lib/include/err.h b/src/user/lib/include/err.h new file mode 100644 index 0000000..e69de29 diff --git a/src/user/lib/include/limits.h b/src/user/lib/include/limits.h new file mode 100644 index 0000000..065f8e0 --- /dev/null +++ b/src/user/lib/include/limits.h @@ -0,0 +1,5 @@ +#pragma once +#include_next +#include // just for PATH_MAX + +#define _POSIX2_RE_DUP_MAX 255 diff --git a/src/user/lib/include/pwd.h b/src/user/lib/include/pwd.h new file mode 100644 index 0000000..e69de29 diff --git a/src/user/lib/include/setjmp.h b/src/user/lib/include/setjmp.h new file mode 100644 index 0000000..f90bae9 --- /dev/null +++ b/src/user/lib/include/setjmp.h @@ -0,0 +1,13 @@ +#pragma once +#include + +typedef char sigjmp_buf; +static inline int sigsetjmp(sigjmp_buf env, int savemask) { + (void)env; (void)savemask; + return 0; +} + +static inline void siglongjmp(sigjmp_buf env, int val) { + (void)env; (void)val; + __libc_panic("unimplemented"); +} diff --git a/src/user/lib/include/signal.h b/src/user/lib/include/signal.h new file mode 100644 index 0000000..c279beb --- /dev/null +++ b/src/user/lib/include/signal.h @@ -0,0 +1,17 @@ +#pragma once +#include // only for ENOSYS + +#define SIGHUP 0 +#define SIGINT 0 +#define SIGWINCH 0 +#define SIGQUIT 0 +#define SIG_IGN 0 +#define SIG_ERR 0 + +typedef int sig_atomic_t; + +static inline int signal(int sig, void (*func)(int)) { + (void)sig; (void)func; + errno = ENOSYS; + return SIG_ERR; +} diff --git a/src/user/lib/include/stdio.h b/src/user/lib/include/stdio.h index b0d34a7..5ad07e0 100644 --- a/src/user/lib/include/stdio.h +++ b/src/user/lib/include/stdio.h @@ -2,13 +2,20 @@ #include #include #include +#include #define EOF (-1) +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 #define SEEK_SET 1 #define SEEK_CUR 2 #define SEEK_END 3 +#define _IONBF 0 +#define _IOLBF 1 + /* stop fread() from trying to fill the entire buffer before returning * i.e. it will call _syscall_read() exactly once */ #define FEXT_NOFILL 1 @@ -28,15 +35,35 @@ FILE *fopen(const char *path, const char *mode); FILE *freopen(const char *path, const char *mode, FILE *); FILE *fdopen(int fd, const char *mode); FILE *file_clone(const FILE *, const char *mode); +FILE *popen(const char *cmd, const char *mode); +int pclose(FILE *f); + int fextflags(FILE *, int extflags); +int setvbuf(FILE *restrict f, char *restrict buf, int type, size_t size); int fclose(FILE *); int fflush(FILE *f); size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict); size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict); +int fputs(const char *s, FILE *f); char *fgets(char *buf, int size, FILE *f); +int fgetc(FILE *f); +int getc(FILE *f); +int fputc(int c, FILE *f); +int putc(int c, FILE *f); + int fseek(FILE *f, long offset, int whence); +int fseeko(FILE *f, off_t offset, int whence); long ftell(FILE *f); +off_t ftello(FILE *f); int feof(FILE *); int ferror(FILE *); +void clearerr(FILE *f); + +void perror(const char *s); +int puts(const char *s); +int getchar(void); +int putchar(int c); + +off_t lseek(int fd, off_t off, int whence); diff --git a/src/user/lib/include/stdlib.h b/src/user/lib/include/stdlib.h index 7f6630d..e2e3996 100644 --- a/src/user/lib/include/stdlib.h +++ b/src/user/lib/include/stdlib.h @@ -1,8 +1,13 @@ #pragma once #include +#include #ifndef NO_MALLOC_H #include #endif _Noreturn void abort(void); + +int mkstemp(char *template); +char *getenv(const char *name); +int system(const char *cmd); diff --git a/src/user/lib/include/string.h b/src/user/lib/include/string.h index 5cddb61..7235da9 100644 --- a/src/user/lib/include/string.h +++ b/src/user/lib/include/string.h @@ -9,3 +9,5 @@ size_t strcspn(const char *s, const char *reject); char *strtok(char *restrict s, const char *restrict sep); char *strtok_r(char *restrict s, const char *restrict sep, char **restrict state); + +int strncmp(const char *s1, const char *s2, size_t n); diff --git a/src/user/lib/include/sys/ioctl.h b/src/user/lib/include/sys/ioctl.h new file mode 100644 index 0000000..708bc3f --- /dev/null +++ b/src/user/lib/include/sys/ioctl.h @@ -0,0 +1,13 @@ +#pragma once +#include // only for ENOSYS + +#define TIOCGWINSZ 0 +struct winsize { + int ws_row, ws_col; +}; + +static inline int ioctl(int fd, int req, ...) { + (void)fd; (void)req; + errno = ENOSYS; + return -1; +} diff --git a/src/user/lib/include/sys/stat.h b/src/user/lib/include/sys/stat.h new file mode 100644 index 0000000..a954c9b --- /dev/null +++ b/src/user/lib/include/sys/stat.h @@ -0,0 +1,11 @@ +#pragma once +#include // only for ENOSYS + +#define S_ISFIFO(x) 0 + +struct stat {}; +static inline int fstat(int fd, struct stat *sb) { + (void)fd; (void)sb; + errno = ENOSYS; + return -1; +} diff --git a/src/user/lib/include/sys/wait.h b/src/user/lib/include/sys/wait.h new file mode 100644 index 0000000..e69de29 diff --git a/src/user/lib/include/unistd.h b/src/user/lib/include/unistd.h index 9b368dc..1f0c002 100644 --- a/src/user/lib/include/unistd.h +++ b/src/user/lib/include/unistd.h @@ -5,6 +5,10 @@ int fork(void); int close(handle_t h); _Noreturn void exit(int); +_Noreturn void _exit(int); + +int unlink(const char *path); +int isatty(int fd); int execv(const char *path, char *const argv[]); diff --git a/src/user/lib/panic.h b/src/user/lib/panic.h new file mode 100644 index 0000000..91aec5f --- /dev/null +++ b/src/user/lib/panic.h @@ -0,0 +1,5 @@ +#pragma once +#include +#include + +#define __libc_panic(...) do { fprintf(stderr, "__libc_panic @ %s:", __func__); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); abort(); } while (0) diff --git a/src/user/lib/stdio/file.c b/src/user/lib/stdio/file.c new file mode 100644 index 0000000..63b004d --- /dev/null +++ b/src/user/lib/stdio/file.c @@ -0,0 +1,304 @@ +#include "file.h" +#include +#include +#include +#include +#include +#include +#include + +static FILE _stdin_null = { .fd = STDIN_FILENO }; +static FILE _stdout_null = { .fd = STDOUT_FILENO }; +static FILE _stderr_null = { .fd = STDERR_FILENO }; +FILE *const stdin = &_stdin_null; +FILE *const stdout = &_stdout_null; +FILE *const stderr = &_stderr_null; + + +FILE *fopen(const char *path, const char *mode) { + FILE *f; + handle_t h; + int flags = 0; + char *tmppath = NULL; + if (!path) { + errno = 1; + return NULL; + } else if (path[0] == '!') { + /* special handling for "!files" */ + path++; + if (!strcmp(path, "stdin")) return file_clone(stdin, mode); + if (!strcmp(path, "stdout")) return file_clone(stdout, mode); + if (!strcmp(path, "stderr")) return file_clone(stderr, mode); + errno = 1; + return NULL; + } + + if (path && path[0] != '/') { + size_t len = absolutepath(NULL, path, 0); + tmppath = malloc(len); + if (!tmppath) return NULL; + absolutepath(tmppath, path, len); + path = tmppath; + } + + if (mode[0] == 'w' || mode[0] == 'a') + flags |= OPEN_CREATE; + + h = _syscall_open(path, strlen(path), flags); + if (tmppath) free(tmppath); + if (h < 0) { + errno = -h; + return NULL; + } + + if (mode[0] == 'w') + _syscall_write(h, NULL, 0, 0, WRITE_TRUNCATE); + + f = fdopen(h, mode); + if (!f) close(h); + return f; +} + + FILE *freopen(const char *path, const char *mode, FILE *f) { + /* partially based on the musl implementation of freopen */ + FILE *f2; + if (!path) goto fail; + f2 = fopen(path, mode); + if (!f2) goto fail; + + if (f->fd == f2->fd) { + f2->fd = -1; + } else { + if (_syscall_dup(f2->fd, f->fd, 0) < 0) goto fail2; + } + f->pos = f2->pos; + f->eof = f2->eof; + fclose(f2); + return f; + +fail2: + fclose(f2); +fail: + fclose(f); + return NULL; +} + +FILE *fdopen(int fd, const char *mode) { + FILE *f; + f = malloc(sizeof *f); + if (!f) return NULL; + f->fd = fd; + f->pos = mode[0] == 'a' ? -1 : 0; + f->eof = false; + f->error = false; + f->extflags = 0; + return f; +} + +FILE *file_clone(const FILE *f, const char *mode) { + handle_t h = _syscall_dup(f->fd, -1, 0); + FILE *f2; + if (h < 0) return NULL; + + f2 = fdopen(h, mode); + if (!f2) { + close(h); + return NULL; + } + f2->pos = f->pos; + f2->eof = f->eof; + f2->fd = h; + return f2; +} + +// TODO popen / pclose +FILE *popen(const char *cmd, const char *mode) { + (void)cmd; (void)mode; + errno = ENOSYS; + return NULL; +} + +int pclose(FILE *f) { + (void)f; + errno = ENOSYS; + return -1; +} + +int fextflags(FILE *f, int extflags) { + int old = f->extflags; + f->extflags = extflags; + return old; +} + +int setvbuf(FILE *restrict f, char *restrict buf, int type, size_t size) { + (void)f; (void)buf; (void)size; + if (type == _IONBF) return 0; + errno = ENOSYS; + return -1; +} + +static void fadvance(long amt, FILE *f) { + bool pos_neg = f->pos < 0; + f->pos += amt; + if (pos_neg && f->pos >= 0) + f->pos = -1; +} + +size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict f) { + size_t total = size*nitems, pos = 0; + unsigned char *buf = ptr; + + if (f->fd < 0) { + errno = EBADF; + return 0; + } + if (size == 0) + return 0; + + while (pos < total) { + long res = _syscall_read(f->fd, buf + pos, total - pos, f->pos); + if (res < 0) { + f->error = true; + errno = -res; + break; + } else if (res == 0) { + f->eof = true; + break; + } + pos += res; + fadvance(res, f); + if (f->extflags & FEXT_NOFILL) break; + } + return pos == total ? nitems : (pos/size); +} + +size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict f) { + size_t total = size*nitems, pos = 0; + const unsigned char *buf = ptr; + + if (f->fd < 0) { + errno = EBADF; + return 0; + } + if (size == 0) + return 0; + + while (pos < total) { + long res = _syscall_write(f->fd, buf + pos, total - pos, f->pos, 0); + if (res < 0) { + f->error = true; + errno = -res; + return pos/size; + } else if (res == 0) { + f->eof = true; + return pos/size; + } else { + pos += res; + fadvance(res, f); + } + } + return nitems; +} + +int fputs(const char *s, FILE *f) { + return fprintf(f, "%s\n", s); +} + +char *fgets(char *buf, int size, FILE *f) { + char c = '\0'; + long pos = 0; + while (pos < (size-1) && c != '\n' && fread(&c, 1, 1, f)) + buf[pos++] = c; + buf[pos++] = '\0'; + + if (f->eof && pos == 1) return NULL; + if (f->error) return NULL; + return buf; +} + +int fgetc(FILE *f) { + char c; + return fread(&c, 1, 1, f) ? c : EOF; +} +int getc(FILE *f) { return fgetc(f); } + +int fputc(int c, FILE *f) { + return fwrite(&c, 1, 1, f) ? c : EOF; +} +int putc(int c, FILE *f) { return fputc(c, f); } + +int fseek(FILE *f, long offset, int whence) { + return fseeko(f, offset, whence); +} + +int fseeko(FILE *f, off_t offset, int whence) { + if (fflush(f)) + return -1; + + long base; + switch (whence) { + case SEEK_SET: + base = 0; + break; + case SEEK_CUR: + base = f->pos; + break; + case SEEK_END: + base = _syscall_getsize(f->fd); + if (base < 0) + base = -1; + break; + default: + errno = EINVAL; + return -1; + } + + if (base >= 0 && base + offset < 0) { + /* underflow */ + errno = EINVAL; + return -1; + } else if (base < 0 && base + offset >= 0) { + /* overflow - went from a negative offset (relative to EOF) + * to a positive offset (from start of file). + * can only happen when getsize() is unsupported */ + errno = EINVAL; + return -1; + } + f->pos = base + offset; + f->eof = false; + return 0; +} + +long ftell(FILE *f) { + return ftello(f); +} + +off_t ftello(FILE *f) { + return f->pos; +} + +int fclose(FILE *f) { + fflush(f); + if (f->fd > 0) close(f->fd); + if (f != &_stdin_null && f != &_stdout_null && f != &_stderr_null) + free(f); + return 0; +} + +int fflush(FILE *f) { + (void)f; + return 0; +} + +int feof(FILE *f) { + return f->eof; +} + +int ferror(FILE *f) { + return f->error; +} + +void clearerr(FILE *f) { + f->error = false; + f->eof = false; +} diff --git a/src/user/lib/stdio/file.h b/src/user/lib/stdio/file.h new file mode 100644 index 0000000..604b070 --- /dev/null +++ b/src/user/lib/stdio/file.h @@ -0,0 +1,10 @@ +#pragma once +#include + +struct _LIBC_FILE { + int fd; + long pos; + bool eof; + bool error; + int extflags; +}; diff --git a/src/user/lib/stdio/misc.c b/src/user/lib/stdio/misc.c new file mode 100644 index 0000000..8f872ec --- /dev/null +++ b/src/user/lib/stdio/misc.c @@ -0,0 +1,25 @@ +#include +#include + +void perror(const char *s) { + if (s) fprintf(stderr, "%s: ", s); + fprintf(stderr, "errno %d\n", errno); +} + +int puts(const char *s) { + return printf("%s\n", s); +} + +int getchar(void) { + return fgetc(stdin); +} + +int putchar(int c) { + return fputc(c, stdout); +} + +off_t lseek(int fd, off_t off, int whence) { + (void)fd; (void)off; (void)whence; + errno = ENOSYS; + return -1; +} diff --git a/src/user/lib/stdlib.c b/src/user/lib/stdlib.c new file mode 100644 index 0000000..6018d16 --- /dev/null +++ b/src/user/lib/stdlib.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include + +_Noreturn void abort(void) { + _syscall_exit(1); +} + +int mkstemp(char *template) { + // TODO randomize template + handle_t h = _syscall_open(template, strlen(template), OPEN_CREATE); + if (h < 0) { + errno = -h; + return -1; + } + // TODO truncate + return h; +} + +// TODO process env +char *getenv(const char *name) { + (void)name; + return NULL; +} + +// TODO system() +int system(const char *cmd) { + (void)cmd; + errno = ENOSYS; + return -1; +} diff --git a/src/user/lib/string.c b/src/user/lib/string.c index ff67399..8424574 100644 --- a/src/user/lib/string.c +++ b/src/user/lib/string.c @@ -86,3 +86,12 @@ char *strtok_r(char *restrict s, const char *restrict sep, char **restrict state } return s; } + +int strncmp(const char *s1, const char *s2, size_t n) { + while (n-- & *s1 && *s1 == *s2) { + s1++; s2++; + } + if (*s1 == *s2) return 0; + if (*s1 < *s2) return -1; + else return 1; +} diff --git a/src/user/lib/unistd.c b/src/user/lib/unistd.c index 9d0c479..f40b876 100644 --- a/src/user/lib/unistd.c +++ b/src/user/lib/unistd.c @@ -20,6 +20,20 @@ int close(handle_t h) { _Noreturn void exit(int c) { _syscall_exit(c); } +_Noreturn void _exit(int c) { exit(c); }; + +// TODO unlink +int unlink(const char *path) { + (void)path; + errno = ENOSYS; + return -1; +} + +// TODO isatty +int isatty(int fd) { + return fd <= 2 ? 1 : 0; +} + int execv(const char *path, char *const argv[]) { FILE *file = fopen(path, "r"); @@ -48,11 +62,6 @@ int execv(const char *path, char *const argv[]) { return -1; } -// stdlib.h -_Noreturn void abort(void) { - _syscall_exit(1); -} - static const char *__initialcwd; static char *cwd = NULL, *cwd2 = NULL; -- cgit v1.2.3