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"
26namespace fs = std::filesystem;
27using namespace fs;
28
29static void test_signatures()
30{
31 const path p; ((void)p);
32 std::error_code ec; ((void)ec);
33 ASSERT_NOT_NOEXCEPT(fs::copy_symlink(existing_symlink: p, new_symlink: p));
34 ASSERT_NOEXCEPT(fs::copy_symlink(existing_symlink: p, new_symlink: p, ec&: ec));
35}
36
37
38static 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(existing_symlink: f, new_symlink: 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(existing_symlink: file, new_symlink: dne, ec&: 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(existing_symlink: dir, new_symlink: dne, ec&: ec);
71 assert(ec);
72 assert(checkThrow(dir, dne, ec));
73 }
74 { // destination exists
75 std::error_code ec;
76 fs::copy_symlink(existing_symlink: sym, new_symlink: file2, ec&: ec);
77 assert(ec);
78 }
79}
80
81static 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(existing_symlink: dir_sym, new_symlink: dest, ec&: 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(existing_symlink: file_sym, new_symlink: dest, ec&: ec);
100 assert(!ec);
101 assert(is_symlink(dest));
102 assert(equivalent(dest, file));
103 }
104}
105
106int main(int, char**) {
107 test_signatures();
108 test_error_reporting();
109 copy_symlink_basic();
110
111 return 0;
112}
113

source code of libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_symlink/copy_symlink.pass.cpp