1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // REQUIRES: can-create-symlinks
10 // UNSUPPORTED: c++03, c++11, c++14
11 // UNSUPPORTED: no-filesystem
12 // UNSUPPORTED: availability-filesystem-missing
13
14 // <filesystem>
15
16 // void copy_symlink(const path& existing_symlink, const path& new_symlink);
17 // void copy_symlink(const path& existing_symlink, const path& new_symlink,
18 // error_code& ec) noexcept;
19
20 #include <filesystem>
21 #include <type_traits>
22 #include <cassert>
23
24 #include "test_macros.h"
25 #include "filesystem_test_helper.h"
26 namespace fs = std::filesystem;
27 using namespace fs;
28
test_signatures()29 static void test_signatures()
30 {
31 const path p; ((void)p);
32 std::error_code ec; ((void)ec);
33 ASSERT_NOT_NOEXCEPT(fs::copy_symlink(p, p));
34 ASSERT_NOEXCEPT(fs::copy_symlink(p, p, ec));
35 }
36
37
test_error_reporting()38 static void test_error_reporting()
39 {
40 auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
41 {
42 #ifndef TEST_HAS_NO_EXCEPTIONS
43 try {
44 fs::copy_symlink(f, t);
45 return true;
46 } catch (filesystem_error const& err) {
47 return err.path1() == f
48 && err.code() == ec;
49 }
50 #else
51 ((void)f); ((void)t); ((void)ec);
52 return true;
53 #endif
54 };
55
56 scoped_test_env env;
57 const path file = env.create_file("file1", 42);
58 const path file2 = env.create_file("file2", 55);
59 const path sym = env.create_symlink(file, "sym");
60 const path dir = env.create_dir("dir");
61 const path dne = env.make_env_path("dne");
62 { // from is a file, not a symlink
63 std::error_code ec;
64 fs::copy_symlink(file, dne, ec);
65 assert(ec);
66 assert(checkThrow(file, dne, ec));
67 }
68 { // from is a file, not a symlink
69 std::error_code ec;
70 fs::copy_symlink(dir, dne, ec);
71 assert(ec);
72 assert(checkThrow(dir, dne, ec));
73 }
74 { // destination exists
75 std::error_code ec;
76 fs::copy_symlink(sym, file2, ec);
77 assert(ec);
78 }
79 }
80
copy_symlink_basic()81 static void copy_symlink_basic()
82 {
83 scoped_test_env env;
84 const path dir = env.create_dir("dir");
85 const path dir_sym = env.create_directory_symlink(dir, "dir_sym");
86 const path file = env.create_file("file", 42);
87 const path file_sym = env.create_symlink(file, "file_sym");
88 { // test for directory symlinks
89 const path dest = env.make_env_path("dest1");
90 std::error_code ec;
91 fs::copy_symlink(dir_sym, dest, ec);
92 assert(!ec);
93 assert(is_symlink(dest));
94 assert(equivalent(dest, dir));
95 }
96 { // test for file symlinks
97 const path dest = env.make_env_path("dest2");
98 std::error_code ec;
99 fs::copy_symlink(file_sym, dest, ec);
100 assert(!ec);
101 assert(is_symlink(dest));
102 assert(equivalent(dest, file));
103 }
104 }
105
main(int,char **)106 int main(int, char**) {
107 test_signatures();
108 test_error_reporting();
109 copy_symlink_basic();
110
111 return 0;
112 }
113