From 9a462d7a19005520021f961fe76320268ae17860 Mon Sep 17 00:00:00 2001 From: Tulio A M Mendes Date: Thu, 12 Feb 2026 00:10:44 -0300 Subject: [PATCH] =?utf8?q?feat:=20ulibc=20realpath()=20=E2=80=94=20resolve?= =?utf8?q?s=20'.',=20'..',=20relative=20paths=20via=20getcwd?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- user/ulibc/include/stdlib.h | 1 + user/ulibc/src/stdlib.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/user/ulibc/include/stdlib.h b/user/ulibc/include/stdlib.h index 6794a99..96b9c97 100644 --- a/user/ulibc/include/stdlib.h +++ b/user/ulibc/include/stdlib.h @@ -9,6 +9,7 @@ void* calloc(size_t nmemb, size_t size); void* realloc(void* ptr, size_t size); int atoi(const char* s); +char* realpath(const char* path, char* resolved); void exit(int status) __attribute__((noreturn)); #ifndef NULL diff --git a/user/ulibc/src/stdlib.c b/user/ulibc/src/stdlib.c index 072ff02..de10e2a 100644 --- a/user/ulibc/src/stdlib.c +++ b/user/ulibc/src/stdlib.c @@ -70,6 +70,42 @@ int atoi(const char* s) { return neg ? -n : n; } +char* realpath(const char* path, char* resolved) { + if (!path || !resolved) return (void*)0; + + char tmp[256]; + int tpos = 0; + + if (path[0] != '/') { + if (getcwd(tmp, sizeof(tmp)) < 0) return (void*)0; + tpos = (int)strlen(tmp); + if (tpos > 0 && tmp[tpos - 1] != '/') tmp[tpos++] = '/'; + } + + while (*path) { + if (*path == '/') { path++; continue; } + if (path[0] == '.' && (path[1] == '/' || path[1] == '\0')) { + path += 1; continue; + } + if (path[0] == '.' && path[1] == '.' && (path[2] == '/' || path[2] == '\0')) { + path += 2; + if (tpos > 1) { + tpos--; + while (tpos > 0 && tmp[tpos - 1] != '/') tpos--; + } + continue; + } + if (tpos > 0 && tmp[tpos - 1] != '/') tmp[tpos++] = '/'; + while (*path && *path != '/' && tpos < 254) tmp[tpos++] = *path++; + } + + if (tpos == 0) tmp[tpos++] = '/'; + tmp[tpos] = '\0'; + + memcpy(resolved, tmp, (size_t)(tpos + 1)); + return resolved; +} + void exit(int status) { _exit(status); } -- 2.43.0