]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
feat: ulibc realpath() — resolves '.', '..', relative paths via getcwd
authorTulio A M Mendes <[email protected]>
Thu, 12 Feb 2026 03:10:44 +0000 (00:10 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 13 Feb 2026 02:20:50 +0000 (23:20 -0300)
user/ulibc/include/stdlib.h
user/ulibc/src/stdlib.c

index 6794a99ae8ac02339e45a1a8fd067acd7b8f0f71..96b9c97c8160fabe01487e4db13757ac14b4c809 100644 (file)
@@ -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
index 072ff02f0f033d92e8ac3c05b17d508eac74c8db..de10e2aa4b4ec31d650246424e89c156894f943a 100644 (file)
@@ -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);
 }