From dcccba655fe848564e961b3f285ce3a82d3ac73a Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Sat, 7 Mar 2020 14:07:28 +0300 Subject: Add more support for symlinks on Windows See mksymlink() for details of the symlinks support on Windows. --- tests/cpfile/driver.cxx | 134 ++++++++++++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 62 deletions(-) (limited to 'tests/cpfile/driver.cxx') diff --git a/tests/cpfile/driver.cxx b/tests/cpfile/driver.cxx index ae40b5f..c613b49 100644 --- a/tests/cpfile/driver.cxx +++ b/tests/cpfile/driver.cxx @@ -30,10 +30,7 @@ using namespace butl; static const char text1[] = "ABCDEF\nXYZ"; static const char text2[] = "12345\nDEF"; - -#ifndef _WIN32 static const char text3[] = "XAB\r\n9"; -#endif static string from_file (const path& f) @@ -135,72 +132,85 @@ main () assert (from_file (hlink) == text2); -#ifndef _WIN32 - - // Check that 'from' being a symbolic link is properly resolved. + // Note that on Windows regular file symlinks may not be supported (see + // mksymlink() for details), so the following tests are allowed to fail + // with ENOSYS on Windows. // - path fslink (td / path ("fslink")); - mksymlink (from, fslink); - - cpfile (fslink, to, cpflags::overwrite_content); - - // Make sure 'to' is not a symbolic link to 'from' and from_file() just - // follows it. - // - assert (try_rmfile (from) == rmfile_status::success); - assert (from_file (to) == text2); - - // Check that 'to' being a symbolic link is properly resolved. - // - path tslink (td / path ("tslink")); - mksymlink (to, tslink); - - to_file (from, text3); - cpfile (from, tslink, cpflags::overwrite_content); - assert (from_file (to) == text3); - - // Check that permissions are properly overwritten when 'to' is a symbolic - // link. - // - to_file (from, text1); - path_permissions (from, permissions::ru | permissions::xu); - - cpfile ( - from, tslink, cpflags::overwrite_content | cpflags::overwrite_permissions); - - assert (from_file (to) == text1); - assert (path_permissions (to) == path_permissions (from)); - - path_permissions (to, p); - path_permissions (from, p); - - // Check that no-overwrite file copy fails even if 'to' symlink points to - // non-existent file. - // - assert (try_rmfile (to) == rmfile_status::success); - try { - cpfile (from, tslink, cpflags::none); - assert (false); - } - catch (const system_error&) - { + // Check that 'from' being a symbolic link is properly resolved. + // + path fslink (td / path ("fslink")); + mksymlink (from, fslink); + + cpfile (fslink, to, cpflags::overwrite_content); + + // Make sure 'to' is not a symbolic link to 'from' and from_file() just + // follows it. + // + assert (try_rmfile (from) == rmfile_status::success); + assert (from_file (to) == text2); + + // Check that 'to' being a symbolic link is properly resolved. + // + path tslink (td / path ("tslink")); + mksymlink (to, tslink); + + to_file (from, text3); + cpfile (from, tslink, cpflags::overwrite_content); + assert (from_file (to) == text3); + + // Check that permissions are properly overwritten when 'to' is a symbolic + // link. + // + to_file (from, text1); + path_permissions (from, permissions::ru | permissions::xu); + + cpfile ( + from, tslink, cpflags::overwrite_content | cpflags::overwrite_permissions); + + assert (from_file (to) == text1); + assert (path_permissions (to) == path_permissions (from)); + + path_permissions (to, p); + path_permissions (from, p); + + // Check that no-overwrite file copy fails even if 'to' symlink points to + // non-existent file. + // + assert (try_rmfile (to) == rmfile_status::success); + + try + { + cpfile (from, tslink, cpflags::none); + assert (false); + } + catch (const system_error&) + { + } + + // Check that copy fail if 'from' symlink points to non-existent file. The + // std::system_error is thrown as cpfile() fails to obtain permissions for + // the 'from' symlink target. + // + try + { + cpfile (tslink, from, cpflags::none); + assert (false); + } + catch (const system_error&) + { + } } - - // Check that copy fail if 'from' symlink points to non-existent file. The - // std::system_error is thrown as cpfile() fails to obtain permissions for - // the 'from' symlink target. - // - try + catch (const system_error& e) { - cpfile (tslink, from, cpflags::none); +#ifndef _WIN32 assert (false); - } - catch (const system_error&) - { - } +#else + assert (e.code ().category () == generic_category () && + e.code ().value () == ENOSYS); #endif + } rmdir_r (td); } -- cgit v1.1