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