Skip to content

fix(libkernel): unlink a dangling Windows directory link - #12820

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
JJenkx:windows/libkernel-unlink-dangling-dir-link
Nov 2, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
JJenkx:windows/libkernel-unlink-dangling-dir-link

Conversation

@JJenkx

@JJenkx JJenkx commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

What

guest_filesystem failed on the measured Windows main revisions recorded below. The first bad commit is the merge of #9473 (2257ffde7b); its first-parent predecessor 430270f510 passes. Found by a full Windows ctest run and a first-parent bisect over the 64 merges between edf6804cf5 and 1db077e876.

The failing check is the last one in #9473's Windows directory-link block (GuestFilesystem.cpp:1522):

Require(unlink_nid_postfix(directoryLink.string().c_str()) == 0 && unlink_nid_postfix(danglingDirectoryLink.string().c_str()) == 0);

with guest errno 13 (EACCES). The cause is the dangling directory link. sceKernelUnlink enters its directory-symlink branch only when std::filesystem::is_directory(std::filesystem::symlink_status(native)) is true. MinGW's libstdc++ symlink_status follows the link instead of describing it, so on this host:

link symlink_status FindFirstFileW removal
live directory link directory 0x410, tag 0xa000000c (symlink) branch runs, RemoveDirectoryW succeeds
dangling directory link not_found, error 2 0x410, tag 0xa000000c (symlink) branch skipped; DeleteFileW fails with ERROR_ACCESS_DENIED -> EACCES

(Measured with a standalone program built with the same WinLibs toolchain. RemoveDirectoryW removes the dangling link fine.)

This PR moves #9473's directory-symlink check ahead of the symlink_status test. It now requires FILE_ATTRIBUTE_DIRECTORY as well as the reparse point and IO_REPARSE_TAG_SYMLINK from FindFirstFileW, so a directory symbolic link is recognised from its own attributes whether or not its target exists. File symbolic links (no FILE_ATTRIBUTE_DIRECTORY) still go through NativeUnlink, and junctions keep the existing branch inside the directory test. Only the #ifdef _WIN32 code moves; other platforms are unchanged.

Because the probe now runs for every Windows unlink, a second commit (from review) skips it when the last component contains *?<>". FindFirstFileW would otherwise treat those as search patterns and match a different entry: unlink("…/directory-li*") next to directory-link returned EIO. A new check in the directory-link block covers that case.

#9473's author measured on Windows 11 10.0.26300 against an older base; I don't know why it passed there. On 10.0.22621 it fails every run.

Tested

Latest qualification (2026-11-01): exact linear head 79e6d32c050fd04aeb746ec34bc280446e4e144c, tested main 93dbd0f82aea684e95f15f06e7d42c0064af18cf. Preserves main’s GetFileAttributesW directory-link classification and existing junction fallback, while keeping the earlier wildcard-guarded FindFirstFileW symlink probe. All filesystem fixtures are the automatic union of main and the branch.

Linux CPU: 5 focused groups, 15 passes, zero skips; public headers, conventions, raw production-library build and production NID patch commands passed. Two affected translation units passed MinGW syntax. No new Windows runtime, native title, console SDK, GPU or performance claim. Existing Windows observations retain their exact historical pins. Fresh Windows runtime qualification remains separate.

Earlier pinned qualifications follow.

Windows 11 Enterprise 10.0.22621, Ryzen 9 5950X, WinLibs GCC 15.2.0 UCRT r7, Ninja, Release, BUILD_TESTING=ON; this machine can create symbolic links without elevation, so #9473's link block runs (not the skip path).

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Fixes: none
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 5021 core/libs/prx/libkernel/File/src/Open.cpp
PR 6936 core/libs/prx/libkernel/File/src/Open.cpp
PR 7121 core/libs/prx/libkernel/File/src/Open.cpp
PR 9019 core/libs/prx/libkernel/File/src/Open.cpp
PR 9371 core/libs/tests/GuestFilesystem.cpp
PR 10319 core/libs/prx/libkernel/File/src/Open.cpp
core/libs/tests/GuestFilesystem.cpp
PR 11831 core/libs/prx/libkernel/File/src/Open.cpp
PR 12560 core/libs/prx/libkernel/File/src/Open.cpp
core/libs/tests/GuestFilesystem.cpp
PR 12682 core/libs/prx/libkernel/File/src/Open.cpp
PR 12688 core/libs/prx/libkernel/File/src/Open.cpp
PR 12700 core/libs/prx/libkernel/File/src/Open.cpp
PR 12965 core/libs/prx/libkernel/File/src/Open.cpp

@XairRrR XairRrR left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed — comments

The change is a small, well-reasoned reordering of the Windows directory-symlink branch in sceKernelUnlink, and I found nothing blocking. The edited code is entirely inside #ifdef _WIN32, though, so this Linux host can neither compile it nor run it, and I cannot approve on what I was able to observe.

What I ran

  • Head: 21e632b9ea89383dff4b513e961ec48480b02586
  • main: ba5b5330b37724bca4b99f30faab504653635a04 (the PR is based on this commit)
  • Host: Arch Linux 7.2.11-zen, GCC 16.2.1, Intel Core i9-14900KF, NVIDIA GeForce RTX 4070 Ti SUPER (driver 615.78.08). Release, Ninja, BUILD_TESTING=ON, in a clean worktree.
git fetch -q origin main pull/12820/head:refs/review/12820
git checkout -q --detach origin/main
git merge -q --no-ff --no-edit refs/review/12820
git diff --check origin/main...refs/review/12820
python3 tools/check_conventions.py --base origin/main
nice -n 10 cmake --build build -j10 --target libkernel guest_filesystem_tests guest_kernel_sys_tests guest_kernel_rename_tests guest_posix_filesystem_tests guest_directory_tests
nice -n 10 ctest --test-dir build -j4 --output-on-failure -R '^(guest_filesystem|guest_kernel_sys|guest_kernel_rename|guest_posix_filesystem|guest_directory)$'
git rev-parse 2257ffde7b^1

Results

Check Result
Merge into main Clean
git diff --check Clean
tools/check_conventions.py --base origin/main All conventions checks passed.
Build (libkernel and the five test executables, Linux) OK
guest_filesystem, guest_kernel_sys, guest_kernel_rename, guest_posix_filesystem, guest_directory (Linux) 5/5 passed
The Windows block is compiled on this host No: it is inside #ifdef _WIN32, so the Linux results only show that the non-Windows path is unchanged
The description's bisect claim 2257ffde7b is the merge of #9473 (“fix(libkernel): rmdir and unlink on a Windows directory link”), and its first parent is 430270f510, as stated. I did not reproduce the bisect itself.
ctest output
1/5 Test  #582: guest_directory ..................   Passed    0.00 sec
2/5 Test #2215: guest_posix_filesystem ...........   Passed    0.00 sec
3/5 Test #2417: guest_kernel_rename ..............   Passed    0.00 sec
4/5 Test  #399: guest_kernel_sys .................   Passed    0.03 sec
5/5 Test #2406: guest_filesystem .................   Passed    0.05 sec

100% tests passed out of 5

Negative control

None. The PR changes no tests. The existing check at GuestFilesystem.cpp:1522 is the regression test, and it only runs on Windows hosts that can create symbolic links. A Linux run cannot exercise it.

Findings

Blocking

None.

Non-blocking

  1. Newly reachable: wildcard characters in the last path component. Open.cpp:491-504 now calls FindFirstFileW(native) on every Windows unlink. Before this PR it only ran once symlink_status had reported an existing directory. FindFirstFileW treats * and ? as wildcards. I did not find any escaping of those characters in the path resolution. Take a guest unlink("…/foo*") with a directory symlink foobar next to it: the search matches foobar, the attribute and tag checks pass, and then RemoveDirectoryW(L"…\\foo*") fails with an error other than ERROR_ACCESS_DENIED. The call therefore returns EIO (5) instead of falling through to the ENOENT path. Nothing is deleted, so the only effect is the wrong errno. sceKernelRmdir already detects links without a wildcard-capable API: Stdio.cpp:1652 uses File::FillLinkStat, and Stdio.cpp:1657-1661 uses GetFileAttributesW with REPARSE_POINT | DIRECTORY. Using the same approach here, with GetFileAttributesW for the two attribute bits and File::WindowsSymbolicLink::Read (WindowsSymbolicLink.hpp:64-79 returns false unless the tag is IO_REPARSE_TAG_SYMLINK), or comparing found.cFileName with native.filename(), would keep the old exposure.
  2. Same failure class remains for dangling junctions. Your diagnosis is that MinGW's symlink_status follows the link. If that holds, a junction whose target is missing also skips the junction branch at Open.cpp:505-515 and reaches NativeUnlink. It would then fail with EACCES just as the dangling symbolic link did. This is outside the PR's scope and is not a regression. Since the DirectoryLink check now sits before the symlink_status test, it might be worth handling IO_REPARSE_TAG_MOUNT_POINT there as well in a follow-up. If not, record the gap in docs/dev/debt/libkernel.md.
  3. Also pre-existing and unchanged in behaviour: a file symbolic link (no FILE_ATTRIBUTE_DIRECTORY) that points at an existing directory still enters the is_directory branch, fails ReadJunction and returns EPERM. POSIX unlink would remove the link. Before this PR it returned EACCES/EIO from RemoveDirectoryW, so neither version removes it. Noting it only for completeness.

Not verified

  • I compiled nothing inside #ifdef _WIN32 and ran nothing on Windows. That includes the guest_filesystem directory-link block, the description's 3/3 pass on 10.0.22621, and the full Windows ctest run.
  • The libstdc++/MinGW symlink_status behaviour described in the table: I did not reproduce it.
  • Why the check passed for #9473's author on 10.0.26300.

To get this to a good state

  • Ideally a second Windows run confirms the fix, for example Windows CI or another contributor with symlink rights. Otherwise this needs a maintainer who trusts the description's Windows results.
  • Optionally address finding 1 so the directory-link probe cannot match a different entry through wildcards.

@JJenkx

JJenkx commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

@XairRrR thanks, finding 1 is real, and I reproduced it on Windows. 1d6c5f549f addresses it.

Finding 1 (wildcards): the probe now runs only when the last component contains none of *?<>". FindFirstFileW treats all five as search patterns, and none can appear in a Windows file name, so no existing link is skipped. I added a check to the Windows directory-link block, while directory-link still exists:

Require(unlink_nid_postfix((root / "directory-li*").string().c_str()) == -1 && *__error_nid_postfix() != 5 && (GetFileAttributesW(directoryLink.c_str()) & FILE_ATTRIBUTE_REPARSE_POINT) != 0);

One correction to the expected errno: with the probe skipped, the call doesn't reach ENOENT. It fails as it did on main before the probe moved, with EINVAL, because DeleteFileW rejects the name with ERROR_INVALID_NAME. So the check asserts what the guard is for (no EIO, and the link is untouched) rather than pinning that host-specific errno. On Windows 11 10.0.22621, on main ba5b5330b3:

Open.cpp new check guest_filesystem
21e632b9ea (no guard) fails: guest errno 5, Win32 error 123 fails
1d6c5f549f (guard) passes passes 3 of 3

guest_kernel_sys, guest_kernel_rename, guest_posix_filesystem and guest_directory also pass 3 of 3 with the guard. The test's stderr is redirected at that point, so I read the failing line through a local file-writing probe in Check (not committed).

Finding 2 (dangling junctions): agreed, same class. I'll check a dangling junction on Windows and send it as a separate PR, or as a debt entry if the fix isn't clean. That's to keep this one to the #9473 regression.

Finding 3: noted. A file symlink pointing at a directory is unchanged by this PR.

AI-assisted: yes (Claude Code).

@XairRrR XairRrR left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-checked — comments

1d6c5f549f skips the FindFirstFileW probe when the last component holds a search-pattern character and adds a regression check for that case. That resolves my wildcard finding as far as I can tell from reading the code. Nothing is blocking. All of the changed code is still inside #ifdef _WIN32, though, so this Linux host cannot compile or run it, and I am leaving a comment rather than an approval for the same reason as last time.

What changed since my last review

  • New commit 1d6c5f549f ("fix(libkernel): keep unlink's directory-link probe off wildcard names"):
    • Open.cpp:492 now runs the probe only when native.filename() contains none of *?<>".
    • GuestFilesystem.cpp:1522 adds a check to the Windows directory-link block. It unlinks directory-li* while directory-link still exists, and requires that the call fails, that errno is not EIO, and that the link is still a reparse point.
  • The author replied to findings 1–3, and the description now covers the wildcard guard and its Windows results.

What I ran

  • Head: 1d6c5f549f285766ade936771c12c75da5d56ebf
  • main: ba5b5330b37724bca4b99f30faab504653635a04
  • Host: Arch Linux 7.2.11-zen, GCC 16.2.1, Intel Core i9-14900KF, NVIDIA GeForce RTX 4070 Ti SUPER (driver 615.78.08). Release, Ninja, BUILD_TESTING=ON, in a clean worktree.
git fetch -q origin main pull/12820/head:refs/review/12820
git diff 21e632b9ea89383dff4b513e961ec48480b02586 refs/review/12820
git checkout -q --detach origin/main
git merge -q --no-ff --no-edit refs/review/12820
git diff --check origin/main...refs/review/12820
python3 tools/check_conventions.py --base origin/main
nice -n 10 cmake --build build -j10 --target libkernel guest_filesystem_tests guest_kernel_sys_tests guest_kernel_rename_tests guest_posix_filesystem_tests guest_directory_tests
nice -n 10 ctest --test-dir build -j4 --output-on-failure -R '^(guest_filesystem|guest_kernel_sys|guest_kernel_rename|guest_posix_filesystem|guest_directory)$'
Check Result
Merge into main Clean
git diff --check Clean
tools/check_conventions.py --base origin/main All conventions checks passed.
Build (libkernel and the five test executables, Linux) OK
guest_filesystem, guest_kernel_sys, guest_kernel_rename, guest_posix_filesystem, guest_directory (Linux) 5/5 passed
Negative control for the new check Not possible here: the check is inside #ifdef _WIN32, and this host has no MinGW toolchain or Windows headers
ctest output
1/5 Test  #582: guest_directory ..................   Passed    0.00 sec
2/5 Test #2215: guest_posix_filesystem ...........   Passed    0.00 sec
3/5 Test #2417: guest_kernel_rename ..............   Passed    0.00 sec
4/5 Test  #399: guest_kernel_sys .................   Passed    0.03 sec
5/5 Test #2406: guest_filesystem .................   Passed    0.05 sec

100% tests passed out of 5

Previous findings

  1. Wildcards in the last component reach FindFirstFileW: Resolved. The guard covers * and ?, and also the three DOS wildcards that the file system interprets (< DOS_STAR, > DOS_QM, " DOS_DOT). None of these five can appear in a Windows file name, so the guard never skips a real link. FindFirstFileW does not accept wildcards in earlier components, so checking only the filename is enough. The author reports that the new check fails without the guard (guest errno 5, Win32 error 123) and passes with it on Windows 11 10.0.22621. I accept that as author-reported, because I cannot run it. Your correction is right: with the probe skipped, the call falls back to main's pre-PR behaviour (EINVAL from DeleteFileW), not to ENOENT as I wrote. Asserting "not EIO, link untouched" rather than a specific host errno is reasonable.
  2. Dangling junctions: Still open, deferred. The author plans to handle it in a separate PR, or as a docs/dev/debt/libkernel.md entry. It is not a regression from this PR, so it does not block.
  3. File symlink pointing at a directory: No longer applies. It was pre-existing and noted only for completeness. The behaviour is unchanged.

New findings

Blocking

None.

Non-blocking

None.

Not verified

  • Nothing inside #ifdef _WIN32 was compiled or run, neither the guard in Open.cpp nor the new GuestFilesystem.cpp check. All Windows results in the description and the reply are author-reported.
  • The negative control for the new check, for the same reason.

To get this to a good state

  • The only thing missing is independent Windows confirmation, from Windows CI or a second contributor with symlink rights. Failing that, a maintainer who accepts the author's Windows results. I have no code changes to request.

@JJenkx

JJenkx commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

@XairRrR finding 2 is confirmed on Windows and now has its own PR, #12835 (stacked on this one). A dangling junction reports not_found from symlink_status and gets ERROR_ACCESS_DENIED from DeleteFileW, so unlink returned EACCES; RemoveDirectoryW removes it. #12835 recognises junctions in the same FindFirstFileW probe, adds a dangling-junction check to guest_filesystem, and that check fails with this PR's Open.cpp.

AI-assisted: yes (Claude Code).

@JJenkx

JJenkx commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

Why main CI didn't catch this: the first main build that includes #9473 (ba5b5330b3, run 40861541628) passed guest_filesystem on its windows job, which runs on Windows Server 2025 (windows-2025-vs2026, build 26100). #9473's author also passed on 10.0.26300. On Windows 11 10.0.22621 (22H2/23H2) it fails every run. So the dangling-directory-link behaviour differs by Windows build, and the newer kernels hide it. ctest prints output only for failing tests, so I can't tell from the CI log whether the link block ran or took its skip path there. Either way, CI on 26100 can't show this regression, and a run on 22621 is the useful confirmation.

AI-assisted: yes (Claude Code).

@XairRrR XairRrR left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-checked — comments

No code has changed since my last review. You have now moved the dangling-junction case to #12835 and explained why main CI missed the regression. I checked that explanation against the CI logs and it holds. It also means CI cannot give the independent Windows confirmation I asked for, so this stays a comment.

What changed since my last review

  • No new commits. The head is still 1d6c5f549f.
  • main moved from ba5b5330b3 to 5454cd2e45. That range includes #12103, which adds rename checks to the same test file, GuestFilesystem.cpp, in a different block.
  • Two replies from you:
    • Finding 2 (dangling junctions) is confirmed on Windows and is now #12835, "fix(libkernel): unlink a dangling Windows junction", stacked on this PR.
    • main CI ran guest_filesystem on Windows Server 2025 (build 26100). That build does not show the dangling directory-link failure, so CI cannot catch this regression.

What I ran

  • Head: 1d6c5f549f285766ade936771c12c75da5d56ebf
  • main: 5454cd2e455994d992aca39335ce60507eeda1eb
  • Merged tree: 9e6ec3b7dc05d965a8cf393a7b69414182978869
  • Host: Arch Linux 7.2.11-zen, GCC 16.2.1, Intel Core i9-14900KF, NVIDIA GeForce RTX 4070 Ti SUPER (driver 615.78.08). Release, Ninja, BUILD_TESTING=ON, in a clean worktree.
git fetch -q origin main pull/12820/head:refs/review/12820
git checkout -q --detach origin/main
git merge -q --no-ff --no-edit refs/review/12820
git diff --check origin/main...refs/review/12820
python3 tools/check_conventions.py --base origin/main
nice -n 10 cmake --build build -j10 --target libkernel guest_filesystem_tests guest_kernel_sys_tests guest_kernel_rename_tests guest_posix_filesystem_tests guest_directory_tests
nice -n 10 ctest --test-dir build -j4 --output-on-failure -R '^(guest_filesystem|guest_kernel_sys|guest_kernel_rename|guest_posix_filesystem|guest_directory)$'
gh run view 40861541628 -R boykopovar/AnyPS5 --log --job 123415127398
gh api repos/boykopovar/AnyPS5/actions/jobs/123431964067 --jq '.steps[]|"\(.number) \(.conclusion) \(.name)"'
gh run view 40869073863 -R boykopovar/AnyPS5 --log --job 123431964067
Check Result
Merge into current main Clean (GuestFilesystem.cpp auto-merged with #12103's rename checks)
git diff --check Clean
tools/check_conventions.py --base origin/main All conventions checks passed.
Build (libkernel and the five test executables, Linux) OK
The five related suites (Linux) 5/5 passed
Your CI explanation Confirmed. The windows job of the main push run for ba5b5330b3 ran on windows-2025-vs2026, OS 10.0.26100, and guest_filesystem passed there.
This PR's own windows check Green, but it compiled and ran nothing from this PR (see below)
ctest output (merged tree)
2/5 Test #2232: guest_posix_filesystem ...........   Passed    0.00 sec
3/5 Test #2434: guest_kernel_rename ..............   Passed    0.00 sec
4/5 Test  #402: guest_kernel_sys .................   Passed    0.02 sec
5/5 Test #2423: guest_filesystem .................   Passed    0.06 sec

100% tests passed out of 5
CI excerpts

main push run 40861541628, windows job, head ba5b5330b3:

Microsoft Windows Server 2025
10.0.26100
Image: windows-2025-vs2026
2503/3000 Test #2510: guest_filesystem ....   Passed    0.30 sec
100% tests passed, 0 tests failed out of 3000

This PR's run 40869073863, windows job, head 1d6c5f549f, steps:

17 success Run if exist configure-seed.cmake (cmake ... -S . -B build ...)
24 skipped Run if exist build\select.ninja (ninja -C build -f select.ninja selected) else (cmake --build build)
26 success Link changed host-only core/libs test executables
27 skipped Run cmake --build build --target libs
28 skipped Run python tools/select_tests.py ctest build ...

Step 26 printed No changed host-only core/libs test executables require a link check.

Previous findings

  1. Wildcards in the last component reach FindFirstFileW: Resolved in my last review. No code changed since then.
  2. Dangling junctions: Moved to #12835. You report that a dangling junction gets EACCES and that #12835's new check fails with this PR's Open.cpp. I accept both as author-reported. I have not reviewed #12835. Leaving it out of this PR keeps this one to the #9473 regression, and it does not block here.
  3. File symlink pointing at a directory: No longer applies. No change.

New findings

Blocking

None.

Non-blocking

  1. This PR's green windows check does not compile the change. On pull_request events, the build, libs and ctest steps of the windows job are gated on github.event_name != 'pull_request' (build.yml:693-714). The job only configures and runs the host-only link check. That check found nothing to link for this PR. So no CI job has compiled Open.cpp or GuestFilesystem.cpp with MinGW at this head. A maintainer should not read the green check as Windows evidence. The first CI compile will be the main push run after the merge, on build 26100, where the regression does not show. I am not asking for a change in this PR. It only means the Windows results in the description are the only evidence that the #ifdef _WIN32 code builds and passes.

Not verified

  • Nothing inside #ifdef _WIN32 was compiled or run, here or by this PR's CI. All Windows results, including the 3-of-3 passes on 10.0.22621 and the negative control for the directory-li* check, are author-reported.
  • I could not tell whether the directory-link block ran or took its skip path on the 26100 runner. Like you, I could not see it in the log, because ctest prints output only for failing tests.
  • #12835 itself.

To get this to a good state

  • I have no code changes to request. What is missing is an independent run of guest_filesystem on a Windows 11 22H2/23H2 (10.0.22621) machine with symlink rights, or a maintainer who accepts your Windows results. A CI run on 26100 cannot replace that, as your own analysis shows.

@JJenkx

JJenkx commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

Linux run at this PR's exact head 1d6c5f549f (1d6c5f549f285766ade936771c12c75da5d56ebf), not merged onto anything else; its base on main is ba5b5330b3.

Arch Linux, kernel 7.2.9, Ryzen 9 7950X, g++ (GCC) 16.2.1 20260810, glibc 2.44, x86-64. Release, BUILD_TESTING=ON, Ninja -j4, private worktree.

  • ctest -R '^guest_filesystem$': passes in each of 3 runs (3 passes).

The fix and the added checks are all in Windows-only blocks; this run shows the Linux build and guest_filesystem are unaffected at this head. The Windows path is not exercised here.

@JJenkx

JJenkx commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor Author

Refreshed on current main 7d4006607a. This head (1d6c5f549f) still merges cleanly, both on its own and together with #12864.

  • Full Windows suite on main 7d4006607a (Windows 11 22621, GCC 15.2 UCRT, Vulkan hidden): 3086 tests, and only 2 fail, ngs2_pitchshift and guest_filesystem. This PR fixes guest_filesystem, and fix(libSceNgs2): compute the PitchShift ratio with libc's msun exp2f #12864 fixes the other.
  • With both PRs merged onto that main, the 68 ngs2_*, guest_filesystem*, guest_kernel_sys* and guest_unlink* tests pass 3 of 3 (ctest --repeat until-fail:3).

With these two merged, the only other known Windows CPU failure here is the intermittent guest_raise_exception (#11813). It passed in that full run, but fails often when run alone, and #12005 fixes it. Edited: corrected an earlier claim of no known failures.

AI-assisted: yes (Claude Code).

@JJenkx

JJenkx commented Oct 31, 2026

Copy link
Copy Markdown
Contributor Author

Rechecked on current main 7351ac7eb1. Windows 11 Enterprise 10.0.22621, Ryzen 9 5950X, WinLibs GCC 15.2.0 UCRT r7, Ninja, Release, BUILD_TESTING=ON.

  • main alone: guest_filesystem aborts (FATAL: abort() (SIGABRT)) right after creating its junctions (Junction created for …\junction-full), in a full suite run and again alone.
  • This PR's head 1d6c5f549f merged onto 7351ac7eb1 (local, clean): guest_filesystem passes 3 of 3 (ctest --repeat until-fail:3).
  • test(libkernel): unlink a dangling Windows junction #12835 alone also makes it pass 3 of 3, and so do both together.

AI-assisted: yes (Claude Code).

@JJenkx
JJenkx force-pushed the windows/libkernel-unlink-dangling-dir-link branch from 1d6c5f5 to 79e6d32 Compare November 2, 2026 01:19
@JJenkx

JJenkx commented Nov 2, 2026

Copy link
Copy Markdown
Contributor Author

@XairRrR Refreshed at exact linear head 79e6d32c050fd04aeb746ec34bc280446e4e144c on tested main 93dbd0f82aea684e95f15f06e7d42c0064af18cf. Preserves main’s GetFileAttributesW directory-link classification and existing junction fallback, while keeping the earlier wildcard-guarded FindFirstFileW symlink probe. All filesystem fixtures are the automatic union of main and the branch.

Linux focused groups: guest_filesystem, guest_kernel_sys, guest_kernel_rename, guest_posix_filesystem, guest_directory. 15 passes, zero skips; public headers and conventions pass. The raw production module, test executables and current NID patcher built, and the exact production patch command passed. MinGW syntax passed for the affected production/test files. Source proofs retain main’s fixtures and gitlinks; there are no merge commits in main..head.

Earlier runtime and negative-control reports remain pinned to their original trees. These new results are Linux CPU/MinGW only. Fresh Windows validation remains separate and pending; no new native title/GPU/performance or unsupported-path behavior claim. AI-assisted: yes (Codex).

Immutable source, command and test evidence, SHA-256 c6962a982e63dc5186eb8c88bace9fb550a33e35fed5e2b5b5838b7e5cc055c4 (public download verified).

The existing Windows owner explicitly acknowledged the finite exact-child validation request; it remains pending behind that host’s existing FIFO work.

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Nov 2, 2026
@oneandonlydean
oneandonlydean merged commit 3258c2f into boykopovar:main Nov 2, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants