]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
Fix getcwd: return char* (POSIX) instead of int
authorTulio A M Mendes <[email protected]>
Sun, 19 Apr 2026 17:38:54 +0000 (14:38 -0300)
committerTulio A M Mendes <[email protected]>
Sun, 19 Apr 2026 17:38:54 +0000 (14:38 -0300)
ulibc getcwd() returned int (0 on success, -1 on error) but POSIX
specifies char* (buf on success, NULL on error). Bash and other
ported software call getcwd expecting a pointer return; getting 0
(NULL) on success caused:

  shell-init: error retrieving current directory: getcwd:
  cannot access parent directories: Bad address

The kernel syscall already returns 0 on success, so the fix is in
the ulibc wrapper: return buf on success, NULL on error (setting
errno). This matches the newlib wrapper in posix_stubs.c which had
the correct signature all along.

Updated all internal callers (sh, pwd, realpath) from int-style
checks (>= 0 / < 0) to pointer-style checks (truthy / !ptr).

user/cmds/pwd/pwd.c
user/cmds/sh/sh.c
user/ulibc/include/unistd.h
user/ulibc/src/stdlib.c
user/ulibc/src/unistd.c

index 5c5395bb725c99f886c330da94c66a67b5a1f8af..fc21ff7ea34373d5ad1ebc708fe15c7a5065ed7f 100644 (file)
@@ -13,7 +13,7 @@
 
 int main(void) {
     char buf[256];
-    if (getcwd(buf, sizeof(buf)) >= 0)
+    if (getcwd(buf, sizeof(buf)))
         printf("%s\n", buf);
     else {
         fprintf(stderr, "pwd: error\n");
index 30817262dfc708339bd28cd21233dd0da74681ad..c7443e3e01aed16637a83f3452b6e43afa9e92e3 100644 (file)
@@ -656,7 +656,7 @@ static void run_simple(char* cmd) {
             fprintf(stderr, "cd: %s: No such file or directory\n", dir);
         else {
             char cwd[256];
-            if (getcwd(cwd, sizeof(cwd)) >= 0)
+            if (getcwd(cwd, sizeof(cwd)))
                 var_set("PWD", cwd, 1);
         }
         goto restore_redir;
@@ -664,7 +664,7 @@ static void run_simple(char* cmd) {
 
     if (strcmp(argv[0], "pwd") == 0) {
         char cwd[256];
-        if (getcwd(cwd, sizeof(cwd)) >= 0)
+        if (getcwd(cwd, sizeof(cwd)))
             printf("%s\n", cwd);
         else
             fprintf(stderr, "pwd: error\n");
@@ -979,7 +979,7 @@ static void print_prompt(void) {
     if (!user) user = "root";
     if (!host) host = "adros";
 
-    if (getcwd(cwd, sizeof(cwd)) < 0) strcpy(cwd, "?");
+    if (!getcwd(cwd, sizeof(cwd))) strcpy(cwd, "?");
 
     printf("%s@%s:%s$ ", user, host, cwd);
     fflush(stdout);
index 31244d0d62ce98552bece3e48e4ae3f4164beff7..3ca39ff17bffcf3c6b624e8aa5cd9cf05d36a45e 100644 (file)
@@ -34,7 +34,7 @@ int     execve(const char* path, char* const argv[], char* const envp[]);
 int     getpid(void);
 int     getppid(void);
 int     chdir(const char* path);
-int     getcwd(char* buf, size_t size);
+char*   getcwd(char* buf, size_t size);
 int     mkdir(const char* path, ...);  /* mode_t optional in AdrOS */
 int     unlink(const char* path);
 int     rmdir(const char* path);
index 56f49655219af9bce5a70096df5fba7be8f86b71..2c9b4a8e3d4dadcff8a591f0f7c01e2ba816fea7 100644 (file)
@@ -176,7 +176,7 @@ char* realpath(const char* path, char* resolved) {
     int tpos = 0;
 
     if (path[0] != '/') {
-        if (getcwd(tmp, sizeof(tmp)) < 0) return (void*)0;
+        if (!getcwd(tmp, sizeof(tmp))) return (void*)0;
         tpos = (int)strlen(tmp);
         if (tpos > 0 && tmp[tpos - 1] != '/') tmp[tpos++] = '/';
     }
index 3f7d9194c420bff3daa1c3622f38e4b53e2a10e2..34c6ac94ffee7b9620eca4df29850418496725d4 100644 (file)
@@ -69,8 +69,10 @@ int chdir(const char* path) {
     return __syscall_ret(_syscall1(SYS_CHDIR, (int)path));
 }
 
-int getcwd(char* buf, size_t size) {
-    return __syscall_ret(_syscall2(SYS_GETCWD, (int)buf, (int)size));
+char* getcwd(char* buf, size_t size) {
+    int r = _syscall2(SYS_GETCWD, (int)buf, (int)size);
+    if (r < 0) { errno = -r; return NULL; }
+    return buf;
 }
 
 int mkdir(const char* path, ...) {