Skip to content

cd through symlinks shows physical path instead of logical path in prompt #14

Description

@blshkv

Summary

After cd /symlink_folder (where symlink_folder is a symlink to another directory), the prompt and $PWD show the resolved physical path instead of the symlink name the user typed.

Steps to reproduce

$ ln -s /some/deep/path /tmp/mylink
$ cd /tmp/mylink
# prompt shows: /some/deep/path
# expected:     /tmp/mylink

Root cause

update_cwd (line ~9978 in bare.asm) unconditionally calls SYS_GETCWD:

update_cwd:
    mov rax, SYS_GETCWD
    lea rdi, [cwd_buf]

The kernel's getcwd syscall always resolves symlinks and returns the physical path. It is called after every successful chdir, discarding the logical path the user typed.

Expected behavior

POSIX and bash both preserve the logical path through symlinks. Bash maintains $PWD manually — on each cd it normalizes the user-typed path against the current logical $PWD (collapsing .. and . without resolving symlinks) and only calls getcwd for the initial startup value.

Fix sketch

In the cd handler, after SYS_CHDIR succeeds, instead of calling update_cwd:

  1. If the target path is absolute: normalize it (collapse //, /./, /../) into cwd_buf directly.
  2. If relative: append to the current logical cwd_buf, then normalize.
  3. Only call SYS_GETCWD on shell startup (as today) or if cwd_buf is somehow empty.

This matches the POSIX-specified behavior for cd with the logical path option (cd -L, which is the default).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions