From 9438c2fdaf4e75c9218a5fde84f121a7a0abb457 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Tue, 9 Aug 2022 18:29:25 +0200 Subject: user/libc: preserve cwd through exec() --- src/user/lib/stdlib.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'src/user/lib/stdlib.c') 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; +} -- cgit v1.2.3