aboutsummaryrefslogtreecommitdiff
path: root/tests/link/driver.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2020-03-11 22:50:15 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2020-03-17 13:15:42 +0300
commit56e49a09b4f1d268bfee83324bbcd44eb925815b (patch)
tree9a8a8395560296fe52ad7b2fef487eef6ee7b4e6 /tests/link/driver.cxx
parentaabd974df745b8f9c061ab162d9babfc9545c108 (diff)
Add readsymlink(), followsymlink(), and try_followsymlink()
Diffstat (limited to 'tests/link/driver.cxx')
-rw-r--r--tests/link/driver.cxx91
1 files changed, 90 insertions, 1 deletions
diff --git a/tests/link/driver.cxx b/tests/link/driver.cxx
index a77df6f..231da4b 100644
--- a/tests/link/driver.cxx
+++ b/tests/link/driver.cxx
@@ -53,6 +53,12 @@ link_file (const path& target, const path& link, mklink ml, bool check_content)
case mklink::hard: mkhardlink (target, link); break;
case mklink::any: mkanylink (target, link, true /* copy */); break;
}
+
+ pair<bool, entry_stat> es (path_entry (link));
+ assert (es.first);
+
+ if (es.second.type == entry_type::symlink && readsymlink (link) != target)
+ return false;
}
catch (const system_error&)
{
@@ -87,6 +93,12 @@ link_dir (const dir_path& target,
mkhardlink (target, link);
else
mksymlink (target, link);
+
+ pair<bool, entry_stat> es (path_entry (link));
+ assert (es.first);
+
+ if (es.second.type == entry_type::symlink)
+ readsymlink (link); // // Check for errors.
}
catch (const system_error&)
{
@@ -120,9 +132,86 @@ link_dir (const dir_path& target,
return te == le;
}
+// Usages:
+//
+// argv[0]
+// argv[0] -s <target> <link>
+// argv[0] -f <path>
+//
+// In the first form run the basic symbolic and hard link tests.
+//
+// In the second form create a symlink. On error print the diagnostics to
+// stderr and exit with the one code.
+//
+// In the third form follow symlinks and print the resulting target path to
+// stdout. On error print the diagnostics to stderr and exit with the one
+// code.
+//
int
-main ()
+main (int argc, const char* argv[])
{
+ bool create_symlink (false);
+ bool follow_symlinks (false);
+
+ int i (1);
+ for (; i != argc; ++i)
+ {
+ string v (argv[i]);
+
+ if (v == "-s")
+ create_symlink = true;
+ else if (v == "-f")
+ follow_symlinks = true;
+ else
+ break;
+ }
+
+ if (create_symlink)
+ {
+ assert (!follow_symlinks);
+ assert (i + 2 == argc);
+
+ try
+ {
+ path t (argv[i]);
+ path l (argv[i + 1]);
+
+ bool dir (dir_exists (t.relative () ? l.directory () / t : t));
+ mksymlink (t, l, dir);
+
+ path lt (readsymlink (l));
+
+ // The targets may only differ for Windows directory junctions.
+ //
+ assert (lt == t || dir);
+
+ return 0;
+ }
+ catch (const system_error& e)
+ {
+ cerr << "error: " << e << endl;
+ return 1;
+ }
+ }
+ else if (follow_symlinks)
+ {
+ assert (!create_symlink);
+ assert (i + 1 == argc);
+
+ try
+ {
+ cout << try_followsymlink (path (argv[i])).first << endl;
+ return 0;
+ }
+ catch (const system_error& e)
+ {
+ cerr << "error: " << e << endl;
+ return 1;
+ }
+ }
+ else
+ assert (i == argc);
+
dir_path td (dir_path::temp_directory () / dir_path ("butl-link"));
// Recreate the temporary directory (that possibly exists from the previous