aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Mark Loeser <halcy0n@gentoo.org> 2006-02-07 19:48:02 +0000
committerAvatar Mark Loeser <halcy0n@gentoo.org> 2006-02-07 19:48:02 +0000
commit1a7690a561d43a4ed200ce99723f466d3f39be90 (patch)
tree6d50b1006687f77c15bd006359b10284188f1244
parent93cfe52ddd65a69acf89553d01d83c31c249f526 (diff)
downloadpaludis-1a7690a561d43a4ed200ce99723f466d3f39be90.tar.gz
paludis-1a7690a561d43a4ed200ce99723f466d3f39be90.tar.xz
Add FSEntry::dirname(), cwd() and is_symbolic_link(). Also changed _stat() to use lstat() instead of stat().
-rw-r--r--paludis/fs_entry.cc36
-rw-r--r--paludis/fs_entry.hh21
-rw-r--r--paludis/fs_entry_TEST.cc38
3 files changed, 93 insertions, 2 deletions
diff --git a/paludis/fs_entry.cc b/paludis/fs_entry.cc
index 5c9af89..e1d61c6 100644
--- a/paludis/fs_entry.cc
+++ b/paludis/fs_entry.cc
@@ -138,6 +138,18 @@ FSEntry::is_regular_file() const
}
bool
+FSEntry::is_symbolic_link() const
+{
+ _stat();
+
+ if (_exists)
+ return S_ISLNK((*_stat_info).st_mode);
+
+ return false;
+}
+
+
+bool
FSEntry::has_permission(const FSUserGroup & user_group, const FSPermission & fs_perm) const
{
_stat();
@@ -233,7 +245,7 @@ FSEntry::_stat() const
return;
_stat_info = CountedPtr<struct stat, count_policy::ExternalCountTag>(new struct stat);
- if (0 != stat(_path.c_str(), _stat_info.raw_pointer()))
+ if (0 != lstat(_path.c_str(), _stat_info.raw_pointer()))
{
if (errno != ENOENT)
throw FSError("Error running stat() on '" + stringify(_path) + "': "
@@ -251,9 +263,21 @@ FSEntry::_stat() const
std::string
FSEntry::basename() const
{
+ if (_path == "/")
+ return _path;
+
return _path.substr(_path.rfind('/') + 1);
}
+std::string
+FSEntry::dirname() const
+{
+ if (_path == "/")
+ return _path;
+
+ return _path.substr(0, _path.rfind('/'));
+}
+
FSEntry
FSEntry::realpath() const
{
@@ -264,6 +288,16 @@ FSEntry::realpath() const
return FSEntry(r);
}
+FSEntry
+FSEntry::cwd()
+{
+ char r[PATH_MAX + 1];
+ std::memset(r, 0, PATH_MAX + 1);
+ if (! ::getcwd(r, PATH_MAX))
+ throw FSError("Could not get current working directory");
+ return FSEntry(r);
+}
+
std::ostream &
paludis::operator<< (std::ostream & s, const FSEntry & f)
{
diff --git a/paludis/fs_entry.hh b/paludis/fs_entry.hh
index 9b058cf..ac24554 100644
--- a/paludis/fs_entry.hh
+++ b/paludis/fs_entry.hh
@@ -95,6 +95,11 @@ namespace paludis
void _normalise();
+ /**
+ * Runs lstat() on the current path if we have not done so already
+ * Note: lstat() will give information on the symbolic link itself, and not what
+ * the link points to, which is how stat() works.
+ */
void _stat() const;
public:
@@ -164,6 +169,12 @@ namespace paludis
bool is_regular_file() const;
/**
+ * Does a filesystem entry exist at our location, and if it does,
+ * is it a symbolic link?
+ */
+ bool is_symbolic_link() const;
+
+ /**
* Check if filesystem entry has `perm` for `user_group`
* \exception FSError if there was a problem accessing the filesystem entry
*/
@@ -175,6 +186,11 @@ namespace paludis
std::string basename() const;
/**
+ * Return the first part of our path (eg '/foo/bar' => '/foo').
+ */
+ std::string dirname() const;
+
+ /**
* Return the canonicalised version of our path.
*/
FSEntry realpath() const;
@@ -190,6 +206,11 @@ namespace paludis
* \exception FSError if there was a problem accessing the filesystem entry
*/
time_t mtime() const;
+
+ /**
+ * Return the current working directory
+ */
+ static FSEntry cwd();
};
/**
diff --git a/paludis/fs_entry_TEST.cc b/paludis/fs_entry_TEST.cc
index 0d81219..075755f 100644
--- a/paludis/fs_entry_TEST.cc
+++ b/paludis/fs_entry_TEST.cc
@@ -58,6 +58,8 @@ namespace test_cases
f = c / f;
TEST_CHECK_EQUAL(f, FSEntry("/foo/bar/moo/baz"));
TEST_CHECK_EQUAL(c, FSEntry("/foo/bar/moo"));
+
+ f = FSEntry::cwd();
}
} test_fs_entry_manipulation;
@@ -87,8 +89,14 @@ namespace test_cases
TEST_CHECK(d.is_regular_file());
TEST_CHECK(d.exists());
+ d = FSEntry("fs_entry_TEST_dir/symlink_to_dir_a");
+ TEST_CHECK(d.is_symbolic_link());
+ TEST_CHECK(! d.is_directory());
+ TEST_CHECK(! d.is_regular_file());
+
FSEntry f("fs_entry_TEST_dir/symlink_to_dir_a/file_in_a");
TEST_CHECK(f.is_regular_file());
+ TEST_CHECK(! f.is_symbolic_link());
FSEntry r(f.realpath());
TEST_CHECK(r.is_regular_file());
std::string g("fs_entry_TEST_dir/dir_a/file_in_a");
@@ -136,7 +144,7 @@ namespace test_cases
/**
* \test Test FSEntry ctime and mtime methods
*/
- struct FSEntryTime: TestCase
+ struct FSEntryTime : TestCase
{
FSEntryTime() : TestCase("ctime and mtime") {}
@@ -155,4 +163,32 @@ namespace test_cases
TEST_CHECK_THROWS(c.mtime(), FSError);
}
} test_fs_entry_time;
+
+ /**
+ * \test Test FSEntry basename and dirname methods
+ */
+ struct FSEntryBaseDirName : TestCase
+ {
+ FSEntryBaseDirName() : TestCase("basename and dirname") {}
+
+ void run()
+ {
+ FSEntry a("/foo/bar");
+ FSEntry b("/moo/went/the/cow");
+ FSEntry c("/");
+ FSEntry d(".");
+ FSEntry e("..");
+
+ TEST_CHECK(a.basename() == "bar");
+ TEST_CHECK(a.dirname() == "/foo");
+ TEST_CHECK(b.basename() == "cow");
+ TEST_CHECK(b.dirname() == "/moo/went/the");
+ TEST_CHECK(c.basename() == "/");
+ TEST_CHECK(c.dirname() == "/");
+ TEST_CHECK(d.basename() == ".");
+ TEST_CHECK(d.dirname() == ".");
+ TEST_CHECK(e.basename() == "..");
+ TEST_CHECK(e.dirname() == "..");
+ }
+ } test_fs_entry_dir_base_name;
}