Skip to content

fix: resolve relative symlink targets against parent directory#394

Draft
Koan-Bot wants to merge 1 commit into
cpan-authors:mainfrom
atoomic:koan.atoomic/fix-relative-symlink-resolution
Draft

fix: resolve relative symlink targets against parent directory#394
Koan-Bot wants to merge 1 commit into
cpan-authors:mainfrom
atoomic:koan.atoomic/fix-relative-symlink-resolution

Conversation

@Koan-Bot
Copy link
Copy Markdown
Contributor

@Koan-Bot Koan-Bot commented May 7, 2026

What

Fix _find_file_or_fh() to resolve relative symlink targets against the symlink's parent directory instead of getcwd().

Why

POSIX mandates that relative symlink targets (e.g., symlink('target.txt', '/dir/link')) resolve relative to the directory containing the symlink. The __cwd_abs_path() function already handled this correctly, but the core path resolution in _find_file_or_fh() passed relative targets directly to _abs_path_to_file(), which resolves against getcwd(). This meant opening a file through a relative symlink silently resolved to the wrong path.

How

Before recursing on a symlink target, check if it's relative. If so, prepend the directory portion of the symlink's absolute path. This is the same approach __cwd_abs_path() uses (tracking $resolved), applied to the simpler recursive resolver.

Testing

  • New t/relative_symlink.t with 7 subtests: simple relative, ../ paths, chained relative symlinks, stat follow, broken relative symlink, write-through, and unlink behavior.
  • All existing symlink tests pass (symlink.t, symlink_follow_ops.t, symlink_link.t, cwd_abs_path.t).

🤖 Generated with Claude Code


Quality Report

Changes: 3 files changed, 112 insertions(+), 1 deletion(-)

Code scan: clean

Tests: passed (OK)

Branch hygiene: clean

Generated by Kōan post-mission quality pipeline

_find_file_or_fh() resolved relative symlink targets (e.g. 'target.txt'
in symlink('target.txt', '/dir/link')) against getcwd() instead of the
directory containing the symlink. This meant that opening a file through
a relative symlink would fail to find the target in most cases.

POSIX mandates that relative symlink targets resolve relative to the
directory containing the symlink. __cwd_abs_path() already handled this
correctly, but the core _find_file_or_fh() resolution path did not.

The fix prepends the symlink's parent directory to relative targets
before recursing, matching POSIX semantics and __cwd_abs_path behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant