summaryrefslogtreecommitdiff
path: root/libs/ardour/file_source.cc
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2011-09-21 17:19:01 +0000
committerCarl Hetherington <carl@carlh.net>2011-09-21 17:19:01 +0000
commit3314322c7e40a089268c3d86a08660ae9cbd30c2 (patch)
tree632937bc9eeecb8d3e1e54b9ae8494c2580cfafd /libs/ardour/file_source.cc
parent8d84c69eec8130db69b961481ae5026510631619 (diff)
Check inodes before reporting ambigious files (#4326).
git-svn-id: svn://localhost/ardour2/branches/3.0@10109 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/file_source.cc')
-rw-r--r--libs/ardour/file_source.cc54
1 files changed, 46 insertions, 8 deletions
diff --git a/libs/ardour/file_source.cc b/libs/ardour/file_source.cc
index 409d978a11..877a0a4939 100644
--- a/libs/ardour/file_source.cc
+++ b/libs/ardour/file_source.cc
@@ -245,7 +245,6 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist
if (!Glib::path_is_absolute (path)) {
vector<string> dirs;
vector<string> hits;
- int cnt;
string fullpath;
string search_path = s.source_search_path (type);
@@ -257,7 +256,6 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist
split (search_path, dirs, ':');
- cnt = 0;
hits.clear ();
for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i) {
@@ -267,21 +265,55 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist
if (Glib::file_test (fullpath, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_REGULAR)) {
keeppath = fullpath;
hits.push_back (fullpath);
- ++cnt;
}
}
- if (cnt > 1) {
+ /* Remove duplicate inodes from the list of ambiguous files, since if there are symlinks
+ in the session path it is possible to arrive at the same file via more than one path.
+ */
- int which = FileSource::AmbiguousFileName (path, search_path, hits).get_value_or (-1);
+ vector<string> de_duped_hits;
+
+ for (vector<string>::iterator i = hits.begin(); i != hits.end(); ++i) {
+
+ vector<string>::iterator j = i;
+ ++j;
+
+ while (j != hits.end()) {
+
+ struct stat bufA;
+ int const rA = stat (i->c_str(), &bufA);
+ struct stat bufB;
+ int const rB = stat (j->c_str(), &bufB);
+
+ if (rA == 0 && rB == 0 && bufA.st_ino == bufB.st_ino) {
+ /* *i and *j are the same file; break out of the loop early */
+ break;
+ }
+
+ ++j;
+ }
+
+ if (j == hits.end ()) {
+ de_duped_hits.push_back (*i);
+ }
+ }
+
+ if (de_duped_hits.size() > 1) {
+
+ /* more than one match: ask the user */
+
+ int which = FileSource::AmbiguousFileName (path, search_path, de_duped_hits).get_value_or (-1);
if (which < 0) {
goto out;
} else {
- keeppath = hits[which];
+ keeppath = de_duped_hits[which];
}
- } else if (cnt == 0) {
+ } else if (de_duped_hits.size() == 0) {
+
+ /* no match: error */
if (must_exist) {
error << string_compose(
@@ -291,7 +323,13 @@ FileSource::find (Session& s, DataType type, const string& path, bool must_exist
} else {
isnew = true;
}
- }
+ } else {
+
+ /* only one match: happy days */
+
+ keeppath = de_duped_hits[0];
+ }
+
} else {
keeppath = path;
}