On Tue, 30 Jun 2026 at 04:51, Adam Wood <[email protected]> wrote: > > Test that fs::remove and fs::remove_all delete an initial directory > symlink instead of following it. Also test that fs::remove_all > delete symlinks inside a directory rather than following them. > > libstdc++-v3/ChangeLog: > > * testsuite/27_io/filesystem/operations/remove.cc: Check > fs::remove deletes symlink instead of target. > * testsuite/27_io/filesystem/operations/remove_all.cc: Likewise. > --- > > Tested on x86_64-pc-linux-gnu. > > Tested on x86_64-w64-mingw32 with Wine 11.11. I tested with the v5 symlink > patch.
Thanks - I've pushed this to trunk. > > .../27_io/filesystem/operations/remove.cc | 19 +++++++++ > .../27_io/filesystem/operations/remove_all.cc | 40 ++++++++++++++++++- > 2 files changed, 58 insertions(+), 1 deletion(-) > > diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/remove.cc > b/libstdc++-v3/testsuite/27_io/filesystem/operations/remove.cc > index 50b1b764716..858884517dd 100644 > --- a/libstdc++-v3/testsuite/27_io/filesystem/operations/remove.cc > +++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/remove.cc > @@ -68,6 +68,25 @@ test01() > > const auto dir = __gnu_test::nonexistent_path(); > create_directories(dir/"a/b"); > + > +#ifndef NO_SYMLINKS > + create_directories(dir/"real"); > + create_directory_symlink(dir/"real", dir/"link"); > + > + ec = bad_ec; > + n = remove(dir/"link", ec); > + VERIFY( !ec ); > + VERIFY( exists(dir/"real") ); > + VERIFY( !exists(symlink_status(dir/"link")) ); > + VERIFY( n ); > + > + ec = bad_ec; > + n = remove(dir/"real", ec); > + VERIFY( !ec ); > + VERIFY( !exists(dir/"real") ); > + VERIFY( n ); > +#endif > + > ec.clear(); > n = remove(dir/"a", ec); > VERIFY( ec ); > diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/remove_all.cc > b/libstdc++-v3/testsuite/27_io/filesystem/operations/remove_all.cc > index 16c215ce999..f29e05086ef 100644 > --- a/libstdc++-v3/testsuite/27_io/filesystem/operations/remove_all.cc > +++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/remove_all.cc > @@ -61,7 +61,7 @@ test01() > #endif > > const auto dir = __gnu_test::nonexistent_path(); > - create_directories(dir/"a/b/c"); > + create_directories(dir/"a"/"b"/"c"); > ec = bad_ec; > n = remove_all(dir/"a", ec); > VERIFY( !ec ); > @@ -69,6 +69,44 @@ test01() > VERIFY( exists(dir) ); > VERIFY( !exists(dir/"a") ); > > +#ifndef NO_SYMLINKS > + // Test that remove_all does not follow an initial directory symlink. > + create_directories(dir/"real"); > + create_directory_symlink(dir/"real", dir/"link"); > + > + ec = bad_ec; > + n = remove_all(dir/"link", ec); > + VERIFY( !ec ); > + VERIFY( exists(dir/"real") ); > + VERIFY( !exists(symlink_status(dir/"link")) ); > + VERIFY( n == 1 ); > + > + ec = bad_ec; > + n = remove_all(dir/"real", ec); > + VERIFY( !ec ); > + VERIFY( !exists(dir/"real") ); > + VERIFY( n == 1 ); > + > + // Test that remove_all does not follow symlinks inside the directory. > + create_directories(dir/"subdir"); > + create_directories(dir/"target_dir"); > + __gnu_test::scoped_file f2(dir/"target_file"); > + create_directory_symlink(dir/"target_dir", dir/"subdir"/"link_dir"); > + create_symlink(dir/"target_file", dir/"subdir"/"link_file"); > + > + ec = bad_ec; > + n = remove_all(dir/"subdir", ec); > + VERIFY( !ec ); > + VERIFY( exists(dir/"target_dir") ); > + VERIFY( exists(dir/"target_file") ); > + VERIFY( !exists(dir/"subdir") ); > + VERIFY( n == 3 ); > + > + f2.path.clear(); > + remove(dir/"target_dir"); > + remove(dir/"target_file"); > +#endif > + > create_directories(dir/"a/b/c"); > __gnu_test::scoped_file a1(dir/"a/1"); > __gnu_test::scoped_file a2(dir/"a/2"); > -- > 2.54.0 >
