From 89b7a51b52ca7c744d82a0b7c74549207cdc8387 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 de433d7b..e52655c8 100644 --- a/user/ulibc/include/stdlib.h +++ b/user/ulibc/include/stdlib.h @@ -18,6 +18,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 2234dff9..fc65f256 100644 --- a/user/ulibc/src/stdlib.c +++ b/user/ulibc/src/stdlib.c @@ -79,6 +79,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