aboutsummaryrefslogtreecommitdiff
path: root/libbutl/filesystem.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2017-06-14 19:06:58 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2017-06-15 20:56:46 +0300
commit273ce32a9a9c89410d4ab396c1bbdfb9a5024fa8 (patch)
tree4e90e7170d98451dcce2a19f8075c3cc60962ac3 /libbutl/filesystem.cxx
parent784f2c18990b71090f267db31a328b81b231b0a6 (diff)
Adapt for ln testscript builtin
Diffstat (limited to 'libbutl/filesystem.cxx')
-rw-r--r--libbutl/filesystem.cxx26
1 files changed, 25 insertions, 1 deletions
diff --git a/libbutl/filesystem.cxx b/libbutl/filesystem.cxx
index 7b340f6..70597b9 100644
--- a/libbutl/filesystem.cxx
+++ b/libbutl/filesystem.cxx
@@ -295,7 +295,31 @@ namespace butl
if (!CreateHardLinkA (link.string ().c_str (),
target.string ().c_str (),
nullptr))
- throw_system_error (GetLastError ());
+ {
+ // If creation fails because hardlinks are not supported for the
+ // specified target/link paths combination, then throw system_error of
+ // the generic category with an approximate POSIX errno code. This way
+ // the caller could recognize such a case and, for example, fallback
+ // to the copy operation. For other error codes use the system
+ // category.
+ //
+ DWORD ec (GetLastError ());
+ switch (ec)
+ {
+ // Target and link are on different drives.
+ //
+ case ERROR_NOT_SAME_DEVICE: throw_generic_error (EXDEV);
+
+ // Target and link are on the same drive, which doesn't support
+ // hardlinks.
+ //
+ case ERROR_ACCESS_DENIED: throw_generic_error (EPERM);
+
+ // Some other failure reason. Fallback to the system category.
+ //
+ default: throw_system_error (ec);
+ }
+ }
}
else
throw_generic_error (ENOSYS, "directory hard links not supported");