summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/user/app/httpd/httpd.c9
-rw-r--r--src/user/lib/_start2.c17
-rw-r--r--src/user/lib/elfload.c46
-rw-r--r--src/user/lib/err.c36
-rw-r--r--src/user/lib/include/err.h8
-rw-r--r--src/user/lib/include/stdlib.h3
-rw-r--r--src/user/lib/stdlib.c8
7 files changed, 99 insertions, 28 deletions
diff --git a/src/user/app/httpd/httpd.c b/src/user/app/httpd/httpd.c
index 2ffc2ba..02f9e6b 100644
--- a/src/user/app/httpd/httpd.c
+++ b/src/user/app/httpd/httpd.c
@@ -2,12 +2,11 @@
* easily DoSable (like the rest of the network stack), vulnerable to path traversal, etc */
#include <camellia/flags.h>
#include <camellia/syscalls.h>
+#include <err.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
-#define eprintf(fmt, ...) fprintf(stderr, "httpd: "fmt"\n" __VA_OPT__(,) __VA_ARGS__)
-
static void handle(FILE *c) {
char buf[2048];
fgets(buf, sizeof buf, c);
@@ -69,10 +68,8 @@ int main(int argc, char **argv) {
handle_t conn;
for (;;) {
conn = _syscall_open(path, strlen(path), OPEN_RW);
- if (conn < 0) {
- eprintf("open('%s') failed, %d", path, conn);
- return 1;
- }
+ if (conn < 0)
+ errx(1, "open('%s') failed, errno %d", path, -conn);
FILE *f = fdopen(conn, "a+");
handle(f);
fclose(f);
diff --git a/src/user/lib/_start2.c b/src/user/lib/_start2.c
index 6d1431f..0582dde 100644
--- a/src/user/lib/_start2.c
+++ b/src/user/lib/_start2.c
@@ -1,13 +1,30 @@
#include <camellia/syscalls.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <user/lib/elfload.h>
int main(int argc, char **argv, char **envp);
+__attribute__((visibility("hidden")))
+extern char _image_base[];
+
+const char *shortname(const char *path) {
+ if (!path) return "unknown program";
+ const char *slash = strrchr(path, '/');
+ if (slash) return slash + 1;
+ return path;
+}
+
_Noreturn void _start2(struct execdata *ed) {
+ const char *progname;
elf_selfreloc();
__setinitialcwd(ed->cwd);
+
+ progname = shortname(ed->argv[0]);
+ setprogname(progname);
+ _klogf("_start2 %s 0x%x", progname, _image_base);
+
exit(main(ed->argc, ed->argv, ed->envp));
}
diff --git a/src/user/lib/elfload.c b/src/user/lib/elfload.c
index 9776a13..99633d1 100644
--- a/src/user/lib/elfload.c
+++ b/src/user/lib/elfload.c
@@ -71,6 +71,8 @@ static void *memdup(const void *orig, size_t len) {
return n;
}
+static const char *default_argv[] = {NULL};
+
/* frees memory outside of [low; low + len] and jumps to *entry
* also sets up main's stack */
void _freejmp_chstack(void *entry, void *low, size_t len, const char **argv, char **envp, void *stack); // elfload.s
@@ -78,30 +80,30 @@ _Noreturn void execbuf_chstack(void *stack, void __user *buf, size_t len);
void _freejmp(void *entry, void *low, size_t imglen, const char **argv, char **envp) {
void *stack = (void*)~0;
struct execdata ed;
+ size_t argv_len;
- if (argv) {
- size_t argv_len;
- ed.argc = 0;
- while (argv[ed.argc]) ed.argc++;
- argv_len = (ed.argc+1) * sizeof(char *);
-
- /* make a copy of argv, so it doesn't get overridden
- * if it overlaps with the new stack. */
- argv = memdup(argv, argv_len);
- for (int i = 0; i < ed.argc; i++)
- argv[i] = strdup(argv[i]);
-
- stack -= argv_len;
- ed.argv = stack;
-
- for (int i = 0; i < ed.argc; i++) {
- size_t len = strlen(argv[i]) + 1;
- stack -= len;
- memcpy(stack, argv[i], len);
- ed.argv[i] = stack;
- }
- ed.argv[ed.argc] = NULL;
+ if (!argv) argv = default_argv;
+
+ ed.argc = 0;
+ while (argv[ed.argc]) ed.argc++;
+ argv_len = (ed.argc+1) * sizeof(char *);
+
+ /* make a copy of argv, so it doesn't get overridden
+ * if it overlaps with the new stack. */
+ argv = memdup(argv, argv_len);
+ for (int i = 0; i < ed.argc; i++)
+ argv[i] = strdup(argv[i]);
+
+ stack -= argv_len;
+ ed.argv = stack;
+
+ for (int i = 0; i < ed.argc; i++) {
+ size_t len = strlen(argv[i]) + 1;
+ stack -= len;
+ memcpy(stack, argv[i], len);
+ ed.argv[i] = stack;
}
+ ed.argv[ed.argc] = NULL;
/* push cwd */
size_t len = absolutepath(NULL, NULL, 0);
diff --git a/src/user/lib/err.c b/src/user/lib/err.c
new file mode 100644
index 0000000..7684b6d
--- /dev/null
+++ b/src/user/lib/err.c
@@ -0,0 +1,36 @@
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+_Noreturn void err(int ret, const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ vwarn(fmt, args);
+ va_end(args);
+ exit(ret);
+}
+
+_Noreturn void errx(int ret, const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ vwarnx(fmt, args);
+ va_end(args);
+ exit(ret);
+}
+
+void vwarn(const char *fmt, va_list args) {
+ fprintf(stderr, "%s: ", getprogname());
+ if (fmt) {
+ vfprintf(stderr, fmt, args);
+ fprintf(stderr, ": ");
+ }
+ fprintf(stderr, "%s\n", strerror(errno));
+}
+
+void vwarnx(const char *fmt, va_list args) {
+ fprintf(stderr, "%s: ", getprogname());
+ if (fmt) vfprintf(stderr, fmt, args);
+ fprintf(stderr, "\n");
+}
diff --git a/src/user/lib/include/err.h b/src/user/lib/include/err.h
index e69de29..9ce4253 100644
--- a/src/user/lib/include/err.h
+++ b/src/user/lib/include/err.h
@@ -0,0 +1,8 @@
+#pragma once
+#include <stdarg.h>
+
+_Noreturn void err(int ret, const char *fmt, ...);
+_Noreturn void errx(int ret, const char *fmt, ...);
+
+void vwarn(const char *fmt, va_list args);
+void vwarnx(const char *fmt, va_list args);
diff --git a/src/user/lib/include/stdlib.h b/src/user/lib/include/stdlib.h
index 2df0bf7..8a86265 100644
--- a/src/user/lib/include/stdlib.h
+++ b/src/user/lib/include/stdlib.h
@@ -12,6 +12,9 @@
_Noreturn void abort(void);
_Noreturn void exit(int);
+const char *getprogname(void);
+void setprogname(const char *progname);
+
int mkstemp(char *template);
char *getenv(const char *name);
int system(const char *cmd);
diff --git a/src/user/lib/stdlib.c b/src/user/lib/stdlib.c
index ffa9f15..5d1b09f 100644
--- a/src/user/lib/stdlib.c
+++ b/src/user/lib/stdlib.c
@@ -8,6 +8,14 @@ _Noreturn void abort(void) {
_syscall_exit(1);
}
+static const char *progname;
+const char *getprogname(void) {
+ return progname;
+}
+void setprogname(const char *pg) {
+ progname = pg;
+}
+
int mkstemp(char *template) {
// TODO randomize template
handle_t h = camellia_open(template, OPEN_CREATE | OPEN_RW);