aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-10-13 05:55:34 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-10-13 05:55:34 +0000
commitc388cc80b200f6e13d633f05d283642400c029fb (patch)
tree156904eeb78253d2efc70e2b907f4baa9b6aab5a
parent21d4d118ac68416c7bfe1802a4017a53cce95aa1 (diff)
downloadpaludis-c388cc80b200f6e13d633f05d283642400c029fb.tar.gz
paludis-c388cc80b200f6e13d633f05d283642400c029fb.tar.xz
Add FSEntry::symlink method
-rw-r--r--paludis/util/fs_entry.cc17
-rw-r--r--paludis/util/fs_entry.hh11
-rw-r--r--paludis/util/fs_entry_TEST.cc14
3 files changed, 42 insertions, 0 deletions
diff --git a/paludis/util/fs_entry.cc b/paludis/util/fs_entry.cc
index 8bbe31b..0d20571 100644
--- a/paludis/util/fs_entry.cc
+++ b/paludis/util/fs_entry.cc
@@ -517,6 +517,23 @@ FSEntry::mkdir(mode_t mode)
}
bool
+FSEntry::symlink(const std::string & target)
+{
+ if (0 == ::symlink(target.c_str(), _imp->path.c_str()))
+ return true;
+
+ int e(errno);
+ if (e == EEXIST)
+ {
+ if (is_symbolic_link() && target == readlink())
+ return false;
+ throw FSError("symlink '" + _imp->path + "' to '" + target + "' failed: target exists");
+ }
+ else
+ throw FSError("symlink '" + _imp->path + "' to '" + target + "' failed: " + ::strerror(e));
+}
+
+bool
FSEntry::unlink()
{
#ifdef HAVE_LCHFLAGS
diff --git a/paludis/util/fs_entry.hh b/paludis/util/fs_entry.hh
index efd9aec..4524984 100644
--- a/paludis/util/fs_entry.hh
+++ b/paludis/util/fs_entry.hh
@@ -306,6 +306,17 @@ namespace paludis
bool mkdir(const mode_t mode = 0755);
/**
+ * Try to make a symlink.
+ *
+ * \return True, if we succeeded, and false if the target already
+ * exists and is a symlink to the same target.
+ *
+ * \exception FSError If an error other than the symlink already
+ * existing occurs, or if the symlink exists and points elsewhere.
+ */
+ bool symlink(const std::string & target);
+
+ /**
* Try to unlink.
*
* \return True, if we succeeded, and false if we don't exist
diff --git a/paludis/util/fs_entry_TEST.cc b/paludis/util/fs_entry_TEST.cc
index d99de0f..27fef1b 100644
--- a/paludis/util/fs_entry_TEST.cc
+++ b/paludis/util/fs_entry_TEST.cc
@@ -242,6 +242,20 @@ namespace test_cases
}
} test_fs_entry_size;
+ struct FSEntrySymlink : TestCase
+ {
+ FSEntrySymlink() : TestCase("symlink") {}
+
+ void run()
+ {
+ FSEntry f("fs_entry_TEST_dir/new_sym");
+ TEST_CHECK(f.symlink("the_target"));
+ TEST_CHECK(f.is_symbolic_link());
+ TEST_CHECK_EQUAL(f.readlink(), "the_target");
+ f.unlink();
+ }
+ } test_fs_symlink;
+
/**
* \test Test FSEntry basename and dirname methods
*