Commit e6b69151c0

Bodie Solomon <bodie@synapsegarden.net>
2018-06-17 20:35:00
Fix 1117: Use realpath in stage1 Darwin os_self_exe_path
Issue: https://github.com/ziglang/zig/issues/1117 The macOS stage1 Zig compiler should look in Zig's real absolute path for the Zig stdlib, but os_self_exe_path looks in its path as returned by _NSGetExecutablePath, which may be a symlink. This means that a symlinked Zig cannot find the Zig stdlib. This patch fixes the issue by resolving the _NSGetExecutablePath result to the real path using realpath() before copying the result to the output path.
1 parent d52ef95
Changed files (1)
src
src/os.cpp
@@ -989,12 +989,28 @@ int os_self_exe_path(Buf *out_path) {
     }
 
 #elif defined(ZIG_OS_DARWIN)
+    // How long is the executable's path?
     uint32_t u32_len = 0;
     int ret1 = _NSGetExecutablePath(nullptr, &u32_len);
     assert(ret1 != 0);
-    buf_resize(out_path, u32_len);
-    int ret2 = _NSGetExecutablePath(buf_ptr(out_path), &u32_len);
+
+    // Allocate a buffer for this path.
+    Buf *path_tmp = buf_alloc_fixed(u32_len);
+    // Fill the buffer with the path, which may be a symlink.
+    int ret2 = _NSGetExecutablePath(buf_ptr(path_tmp), &u32_len);
     assert(ret2 == 0);
+
+    // Make a buffer with room for the real path.
+    Buf *resolve_tmp = buf_alloc_fixed(PATH_MAX);
+
+    // Fill it with the real resolved path.
+    char *real_path = realpath(buf_ptr(path_tmp), buf_ptr(resolve_tmp));
+    // IEEE Std 1003.1-2017: realpath() shall return a pointer to the
+    // buffer containing the resolved name.
+    assert(real_path == buf_ptr(resolve_tmp));
+
+    // Resize out_path and copy the resulting resolved absolute path.
+    buf_init_from_buf(out_path, resolve_tmp);
     return 0;
 #elif defined(ZIG_OS_LINUX)
     buf_resize(out_path, 256);