summaryrefslogtreecommitdiff
path: root/src/user/lib/stdlib.c
diff options
context:
space:
mode:
authordzwdz2022-08-09 18:29:25 +0200
committerdzwdz2022-08-09 18:29:25 +0200
commit9438c2fdaf4e75c9218a5fde84f121a7a0abb457 (patch)
tree4ed0de6a19d2180198d939c042237aa43e751c3a /src/user/lib/stdlib.c
parentd51413be236c09f3946d390327595adc109fcf66 (diff)
user/libc: preserve cwd through exec()
Diffstat (limited to 'src/user/lib/stdlib.c')
-rw-r--r--src/user/lib/stdlib.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/src/user/lib/stdlib.c b/src/user/lib/stdlib.c
index 566eb3e..a5d2d9b 100644
--- a/src/user/lib/stdlib.c
+++ b/src/user/lib/stdlib.c
@@ -53,9 +53,19 @@ _Noreturn void abort(void) {
}
+static const char *__initialcwd;
static char *cwd = NULL, *cwd2 = NULL;
static size_t cwdcapacity = 0;
+static const char *getrealcwd(void) {
+ /* __initialcwd can't just be initialized with "/" because ld has seemingly
+ * started to revolt against humanity and not process half the relocations
+ * it sees. */
+ if (cwd) return cwd;
+ if (__initialcwd) return __initialcwd;
+ return "/";
+}
+
int chdir(const char *path) {
handle_t h;
char *tmp;
@@ -66,12 +76,12 @@ int chdir(const char *path) {
cwd = realloc(cwd, len);
cwd2 = realloc(cwd2, len);
} else {
- cwd = malloc(len);
- cwd[0] = '/';
- cwd[1] = '\0';
- cwd2 = malloc(len);
- cwd2[0] = '/';
- cwd2[1] = '\0';
+ size_t initlen = strlen(__initialcwd) + 1;
+ if (len < initlen)
+ len = initlen;
+ cwd = malloc(initlen);
+ cwd2 = malloc(initlen);
+ memcpy(cwd, __initialcwd, initlen);
}
}
absolutepath(cwd2, path, cwdcapacity);
@@ -95,16 +105,17 @@ int chdir(const char *path) {
}
char *getcwd(char *buf, size_t size) {
- const char *realcwd = cwd ? cwd : "/";
+ const char *realcwd = getrealcwd();
// TODO bounds checking
memcpy(buf, realcwd, strlen(realcwd) + 1);
return buf;
}
size_t absolutepath(char *out, const char *in, size_t size) {
- const char *realcwd = cwd ? cwd : "/";
+ const char *realcwd = getrealcwd();
size_t len, pos = 0;
- if (!in) return strlen(realcwd);
+ _klogf("realcwd == %x\n", (long)__initialcwd);
+ if (!in) return strlen(realcwd) + 1;
if (!(in[0] == '/')) {
len = strlen(realcwd);
@@ -133,3 +144,7 @@ size_t absolutepath(char *out, const char *in, size_t size) {
return pos;
}
+
+void __setinitialcwd(const char *s) {
+ __initialcwd = s;
+}