summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2022-08-26 14:16:16 +0200
committerdzwdz2022-08-26 14:16:16 +0200
commite6584db26da34572fb13aa236e16e19f71c8e976 (patch)
tree055c528765e986bc8ed6706cec84289e50b46ed6 /src
parentffdf0e8d93f8e98ed9d5a8270feb2a19eb9659e3 (diff)
user/libc: prepare for OpenED port
Diffstat (limited to 'src')
-rw-r--r--src/shared/include/assert.h6
-rw-r--r--src/user/lib/ctype.c9
-rw-r--r--src/user/lib/elfload.c1
-rw-r--r--src/user/lib/include/ctype.h3
-rw-r--r--src/user/lib/include/err.h0
-rw-r--r--src/user/lib/include/limits.h5
-rw-r--r--src/user/lib/include/pwd.h0
-rw-r--r--src/user/lib/include/setjmp.h13
-rw-r--r--src/user/lib/include/signal.h17
-rw-r--r--src/user/lib/include/stdio.h27
-rw-r--r--src/user/lib/include/stdlib.h5
-rw-r--r--src/user/lib/include/string.h2
-rw-r--r--src/user/lib/include/sys/ioctl.h13
-rw-r--r--src/user/lib/include/sys/stat.h11
-rw-r--r--src/user/lib/include/sys/wait.h0
-rw-r--r--src/user/lib/include/unistd.h4
-rw-r--r--src/user/lib/panic.h5
-rw-r--r--src/user/lib/stdio/file.c (renamed from src/user/lib/file.c)58
-rw-r--r--src/user/lib/stdio/file.h (renamed from src/user/lib/file.h)0
-rw-r--r--src/user/lib/stdio/misc.c25
-rw-r--r--src/user/lib/stdlib.c32
-rw-r--r--src/user/lib/string.c9
-rw-r--r--src/user/lib/unistd.c19
23 files changed, 253 insertions, 11 deletions
diff --git a/src/shared/include/assert.h b/src/shared/include/assert.h
index 7adf297..7520aa9 100644
--- a/src/shared/include/assert.h
+++ b/src/shared/include/assert.h
@@ -1,3 +1,7 @@
-#pragma once
+#ifdef NDEBUG
+#define assert(stmt) do {} while (0)
+#else
#define assert(stmt) do { if (!(stmt)) __badassert(__func__, __FILE__, __LINE__); } while (0)
+#endif
+
_Noreturn void __badassert(const char *func, const char *file, int line);
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/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
--- /dev/null
+++ b/src/user/lib/include/err.h
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 <limits.h>
+#include <camellia/path.h> // 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
--- /dev/null
+++ b/src/user/lib/include/pwd.h
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 <user/lib/panic.h>
+
+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 <errno.h> // 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 <bits/file.h>
#include <stdarg.h>
#include <stddef.h>
+#include <sys/types.h>
#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 <stddef.h>
+#include <stdlib.h>
#ifndef NO_MALLOC_H
#include <user/lib/vendor/dlmalloc/malloc.h>
#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 <errno.h> // 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 <errno.h> // 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
--- /dev/null
+++ b/src/user/lib/include/sys/wait.h
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 <stdio.h>
+#include <stdlib.h>
+
+#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/file.c b/src/user/lib/stdio/file.c
index f2b74b1..63b004d 100644
--- a/src/user/lib/file.c
+++ b/src/user/lib/stdio/file.c
@@ -7,9 +7,9 @@
#include <string.h>
#include <unistd.h>
-static FILE _stdin_null = { .fd = 0 };
-static FILE _stdout_null = { .fd = 1 };
-static FILE _stderr_null = { .fd = 2 };
+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;
@@ -21,7 +21,7 @@ FILE *fopen(const char *path, const char *mode) {
int flags = 0;
char *tmppath = NULL;
if (!path) {
- errno = -1;
+ errno = 1;
return NULL;
} else if (path[0] == '!') {
/* special handling for "!files" */
@@ -29,7 +29,7 @@ FILE *fopen(const char *path, const char *mode) {
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;
+ errno = 1;
return NULL;
}
@@ -111,12 +111,32 @@ FILE *file_clone(const FILE *f, const char *mode) {
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;
@@ -180,6 +200,10 @@ size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restri
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;
@@ -192,7 +216,22 @@ char *fgets(char *buf, int size, FILE *f) {
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;
@@ -231,6 +270,10 @@ int fseek(FILE *f, long offset, int whence) {
}
long ftell(FILE *f) {
+ return ftello(f);
+}
+
+off_t ftello(FILE *f) {
return f->pos;
}
@@ -254,3 +297,8 @@ int feof(FILE *f) {
int ferror(FILE *f) {
return f->error;
}
+
+void clearerr(FILE *f) {
+ f->error = false;
+ f->eof = false;
+}
diff --git a/src/user/lib/file.h b/src/user/lib/stdio/file.h
index 604b070..604b070 100644
--- a/src/user/lib/file.h
+++ b/src/user/lib/stdio/file.h
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 <errno.h>
+#include <stdio.h>
+
+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 <camellia/syscalls.h>
+#include <camellia/flags.h>
+#include <errno.h>
+#include <string.h>
+
+_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;