Ask for the real path in any case.
This commit is contained in:
parent
55a4e89b3b
commit
d36bfe15e4
@ -300,10 +300,15 @@ std::string cached_realpath(llvm::StringRef path, llvm::StringRef base_path = ""
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If already cached - retun cached result
|
// If already cached - retun cached result
|
||||||
static llvm::StringMap<std::string> cache;
|
static llvm::StringMap<std::pair<std::string,int>> cache;
|
||||||
auto it = cache.find(path);
|
bool relative_path = llvm::sys::path::is_relative(path);
|
||||||
if (it != cache.end())
|
if (!relative_path) {
|
||||||
return it->second;
|
auto it = cache.find(path);
|
||||||
|
if (it != cache.end()) {
|
||||||
|
errno = it->second.second;
|
||||||
|
return it->second.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If result not in cache - call system function and cache result
|
// If result not in cache - call system function and cache result
|
||||||
|
|
||||||
@ -313,7 +318,7 @@ std::string cached_realpath(llvm::StringRef path, llvm::StringRef base_path = ""
|
|||||||
llvm::SmallVector<llvm::StringRef, 16> p;
|
llvm::SmallVector<llvm::StringRef, 16> p;
|
||||||
|
|
||||||
// Relative or absolute path
|
// Relative or absolute path
|
||||||
if (llvm::sys::path::is_relative(path)) {
|
if (relative_path) {
|
||||||
if (is_base_path_real) {
|
if (is_base_path_real) {
|
||||||
result.assign(base_path);
|
result.assign(base_path);
|
||||||
} else {
|
} else {
|
||||||
@ -359,14 +364,21 @@ std::string cached_realpath(llvm::StringRef path, llvm::StringRef base_path = ""
|
|||||||
result = cached_realpath(symlink, "", true, symlooplevel - 1);
|
result = cached_realpath(symlink, "", true, symlooplevel - 1);
|
||||||
}
|
}
|
||||||
} else if (st_mode == 0) {
|
} else if (st_mode == 0) {
|
||||||
cache.insert(std::pair<llvm::StringRef, llvm::StringRef>(path, ""));
|
cache.insert(std::pair<llvm::StringRef, std::pair<std::string,int>>(
|
||||||
|
path,
|
||||||
|
std::pair<std::string,int>("",ENOENT))
|
||||||
|
);
|
||||||
|
errno = ENOENT;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
llvm::sys::fs::real_path(path, result);
|
llvm::sys::fs::real_path(path, result);
|
||||||
#endif
|
#endif
|
||||||
cache.insert(std::pair<llvm::StringRef, std::string>(path, result.str().str()));
|
cache.insert(std::pair<llvm::StringRef, std::pair<std::string,int>>(
|
||||||
|
path,
|
||||||
|
std::pair<std::string,int>(result.str().str(),errno))
|
||||||
|
);
|
||||||
return result.str().str();
|
return result.str().str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1312,8 +1324,9 @@ namespace cling {
|
|||||||
// Not in a known shared library, let's give up
|
// Not in a known shared library, let's give up
|
||||||
return {};
|
return {};
|
||||||
} else {
|
} else {
|
||||||
if (strchr(info.dli_fname, '/'))
|
std::string result = cached_realpath(info.dli_fname);
|
||||||
return cached_realpath(info.dli_fname);
|
if (!result.empty())
|
||||||
|
return result;
|
||||||
|
|
||||||
// Else absolute path. For all we know that's a binary.
|
// Else absolute path. For all we know that's a binary.
|
||||||
// Some people have dictionaries in binaries, this is how we find their
|
// Some people have dictionaries in binaries, this is how we find their
|
||||||
@ -1333,7 +1346,6 @@ namespace cling {
|
|||||||
FILE* pipe = popen(pipeCmd.c_str(), "r");
|
FILE* pipe = popen(pipeCmd.c_str(), "r");
|
||||||
if (!pipe)
|
if (!pipe)
|
||||||
return cached_realpath(info.dli_fname);
|
return cached_realpath(info.dli_fname);
|
||||||
std::string result;
|
|
||||||
while (fgets(buf, sizeof(buf), pipe))
|
while (fgets(buf, sizeof(buf), pipe))
|
||||||
result += buf;
|
result += buf;
|
||||||
|
|
||||||
|
176
test/DynamicLibraryManager/cached_realpath.C
Normal file
176
test/DynamicLibraryManager/cached_realpath.C
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// CLING - the C++ LLVM-based InterpreterG :)
|
||||||
|
//
|
||||||
|
// This file is dual-licensed: you can choose to license it under the University
|
||||||
|
// of Illinois Open Source License or the GNU Lesser General Public License. See
|
||||||
|
// LICENSE.TXT for details.
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// REQUIRES: not_system-windows
|
||||||
|
|
||||||
|
// RUN: cd %t-dir
|
||||||
|
|
||||||
|
// RUN: %mkdir %t-dir/dir1/dir11/dir111
|
||||||
|
// RUN: %mkdir %t-dir/dir1/dir11/dir112
|
||||||
|
// RUN: %mkdir %t-dir/dir1/dir12/dir121
|
||||||
|
// RUN: %mkdir %t-dir/dir1/dir12/dir122
|
||||||
|
// RUN: %mkdir %t-dir/dir2/dir21/dir211
|
||||||
|
// RUN: %mkdir %t-dir/dir2/dir21/dir212
|
||||||
|
|
||||||
|
// RUN: echo "a" > %t-dir/dir1/a.txt
|
||||||
|
// RUN: echo "b" > %t-dir/dir1/dir11/b.txt
|
||||||
|
// RUN: echo "c" > %t-dir/dir1/dir11/dir111/c.txt
|
||||||
|
// RUN: echo "d" > %t-dir/dir1/dir12/d.txt
|
||||||
|
// RUN: echo "e" > %t-dir/dir2/dir21/dir211/e.txt
|
||||||
|
|
||||||
|
// RUN: ln -f -s %t-dir/dir1/dir11 dir1/linkdir11
|
||||||
|
// RUN: ln -f -s -r %t-dir/dir1/dir11 dir1/rlinkdir11
|
||||||
|
// RUN: ln -f -s %t-dir/dir1/dir12 dir1/linkdir12
|
||||||
|
// RUN: ln -f -s %t-dir/dir1/dir11/dir111 dir1/dir11/linkdir111
|
||||||
|
// RUN: ln -f -s -r %t-dir/dir1/dir11/dir111 dir1/dir11/rlinkdir111
|
||||||
|
|
||||||
|
// RUN: ln -f -s %t-dir/dir1/dir11/dir111/c.txt dir1/dir11/dir111/linkc.txt
|
||||||
|
// RUN: ln -f -s -r %t-dir/dir1/dir11/dir111/c.txt dir1/dir11/dir111/rlinkc.txt
|
||||||
|
|
||||||
|
// RUN: ln -f -s %t-dir/dir1/dir11/dir111/nofile.txt dir1/dir11/dir111/linknofile.txt
|
||||||
|
// RUN: ln -f -s -r %t-dir/dir1/dir11/dir111/nofile.txt dir1/dir11/dir111/rlinknofile.txt
|
||||||
|
|
||||||
|
// RUN: ln -f -s %t-dir/dir2/dir21 dir2/linkdir21
|
||||||
|
// RUN: ln -f -s %t-dir/dir2/linkdir21 dir2/linkdir21a
|
||||||
|
// RUN: ln -f -s -r %t-dir/dir2/dir21 dir2/rlinkdir21
|
||||||
|
// RUN: ln -f -s -r %t-dir/dir2/rlinkdir21 dir2/rlinkdir21a
|
||||||
|
// RUN: ln -f -s %t-dir/dir2/linkdir21 dir2/linkdir21a1
|
||||||
|
|
||||||
|
// RUN: ln -f -s %t-dir/dir2 dir2/dir21/linkdir2
|
||||||
|
// RUN: ln -f -s -r %t-dir/dir2 dir2/dir21/rlinkdir2
|
||||||
|
|
||||||
|
// RUN: ln -f -s -r %t-dir/dir2/dir21/dir211 dir2/rlinkdir211
|
||||||
|
// RUN: ln -f -s %t-dir/dir2/dir21/dir211 dir2/linkdir211
|
||||||
|
// RUN: ln -f -s -r %t-dir/dir2/dir21/dir211/e.txt dir2/rlinke.txt
|
||||||
|
// RUN: ln -f -s %t-dir/dir2/dir21/dir211/e.txt dir2/linke.txt
|
||||||
|
|
||||||
|
// RUN: ln -f -s %t-dir/dir2/selfinfloop.txt dir2/selfinfloop.txt
|
||||||
|
// RUN: ln -f -s %t-dir/dir2/infloop2.txt dir2/infloop1.txt
|
||||||
|
// RUN: ln -f -s %t-dir/dir2/infloop1.txt dir2/infloop2.txt
|
||||||
|
// RUN: ln -f -s -r %t-dir/dir2/rselfinfloop.txt dir2/rselfinfloop.txt
|
||||||
|
|
||||||
|
// RUN: ln -f -s -r %t-dir/dir1/a.txt dir2/backtoa.txt
|
||||||
|
|
||||||
|
|
||||||
|
// RUN: cat %s | %cling -fno-rtti 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "../lib/Interpreter/DynamicLibraryManagerSymbol.cpp"
|
||||||
|
|
||||||
|
.rawInput 1
|
||||||
|
void test_realpath(std::string path) {
|
||||||
|
// system realpath
|
||||||
|
errno = 0;
|
||||||
|
char system_resolved_path[4096];
|
||||||
|
system_resolved_path[0] = '\0';
|
||||||
|
realpath(path.c_str(), system_resolved_path);
|
||||||
|
int err_s = errno;
|
||||||
|
if (err_s !=0 ) system_resolved_path[0] = '\0';
|
||||||
|
|
||||||
|
// cached_realpath
|
||||||
|
errno = 0;
|
||||||
|
std::string cached_resolved_path = cached_realpath(path);
|
||||||
|
int err_c = errno;
|
||||||
|
|
||||||
|
if (err_s != err_c || std::string(system_resolved_path) != cached_resolved_path) {
|
||||||
|
std::cout << "realpath: " << path.c_str() << "\n";
|
||||||
|
std::cout << " err_s=" << err_s << ", rp_s=" << system_resolved_path << "\n";
|
||||||
|
std::cout << " err_c=" << err_c << ", rp_c=" << cached_resolved_path.c_str() << "\n\n";
|
||||||
|
} else if (err_c != 0) {
|
||||||
|
std::cout << "ERROR\n";
|
||||||
|
} else {
|
||||||
|
std::cout << "OK\n";
|
||||||
|
}
|
||||||
|
std::cout << std::flush;
|
||||||
|
}
|
||||||
|
.rawInput 0
|
||||||
|
|
||||||
|
// Test: cached_realpath
|
||||||
|
|
||||||
|
test_realpath(""); // CHECK: ERROR
|
||||||
|
|
||||||
|
test_realpath("/"); // CHECK: OK
|
||||||
|
test_realpath("/tmp"); // CHECK: OK
|
||||||
|
|
||||||
|
test_realpath("."); // CHECK: OK
|
||||||
|
test_realpath(".."); // CHECK: OK
|
||||||
|
test_realpath("../"); // CHECK: OK
|
||||||
|
test_realpath("../."); // CHECK: OK
|
||||||
|
test_realpath("/."); // CHECK: OK
|
||||||
|
test_realpath("/.."); // CHECK: OK
|
||||||
|
test_realpath("/../"); // CHECK: OK
|
||||||
|
test_realpath("/../.."); // CHECK: OK
|
||||||
|
|
||||||
|
//test_realpath("~"); // OK
|
||||||
|
//test_realpath("~/tmp"); // OK
|
||||||
|
|
||||||
|
test_realpath("dir1"); // CHECK: OK
|
||||||
|
test_realpath("dir1/a.txt"); // CHECK: OK
|
||||||
|
test_realpath("dir1/dir11/b.txt"); // CHECK: OK
|
||||||
|
|
||||||
|
test_realpath("nodir"); // CHECK: ERROR
|
||||||
|
test_realpath("dir1/nodir/b.txt"); // CHECK: ERROR
|
||||||
|
|
||||||
|
test_realpath("dir1/linkdir11/b.txt"); // CHECK: OK
|
||||||
|
test_realpath("dir1/rlinkdir11/b.txt"); // CHECK: OK
|
||||||
|
test_realpath("dir1/linkdir11/dir111/c.txt"); // CHECK: OK
|
||||||
|
test_realpath("dir1/rlinkdir11/dir111/c.txt"); // CHECK: OK
|
||||||
|
|
||||||
|
test_realpath("dir1/linkdir11/dir111/nofile.txt"); // CHECK: ERROR
|
||||||
|
test_realpath("dir1/rlinkdir11/dir111/nofile.txt"); // CHECK: ERROR
|
||||||
|
test_realpath("dir1/linkdir12/nofile.txt"); // CHECK: ERROR
|
||||||
|
|
||||||
|
test_realpath("dir1/dir11/dir111/linkc.txt"); // CHECK: OK
|
||||||
|
test_realpath("dir1/dir11/dir111/rlinkc.txt"); // CHECK: OK
|
||||||
|
test_realpath("dir1/linkdir11/dir111/linkc.txt"); // CHECK: OK
|
||||||
|
test_realpath("dir1/linkdir11/dir111/rlinkc.txt"); // CHECK: OK
|
||||||
|
test_realpath("dir1/rlinkdir11/dir111/linkc.txt"); // CHECK: OK
|
||||||
|
test_realpath("dir1/rlinkdir11/dir111/rlinkc.txt"); // CHECK: OK
|
||||||
|
|
||||||
|
test_realpath("dir1/dir11/dir111/linknofile.txt"); // CHECK: ERROR
|
||||||
|
test_realpath("dir1/dir11/dir111/rlinknofile.txt"); // CHECK: ERROR
|
||||||
|
test_realpath("dir1/linkdir11/dir111/linknofile.txt"); // CHECK: ERROR
|
||||||
|
test_realpath("dir1/linkdir11/dir111/rlinknofile.txt"); // CHECK: ERROR
|
||||||
|
|
||||||
|
test_realpath("dir2/linkdir211/."); // CHECK: OK
|
||||||
|
test_realpath("dir2/rlinkdir211/."); // CHECK: OK
|
||||||
|
test_realpath("dir2/linkdir211/.."); // CHECK: OK
|
||||||
|
test_realpath("dir2/rlinkdir211/.."); // CHECK: OK
|
||||||
|
|
||||||
|
test_realpath("dir2/dir21/linkdir2"); // CHECK: OK
|
||||||
|
test_realpath("dir2/dir21/rlinkdir2"); // CHECK: OK
|
||||||
|
test_realpath("dir2/linkdir21a1"); // CHECK: OK
|
||||||
|
test_realpath("dir2/rlinkdir21a"); // CHECK: OK
|
||||||
|
|
||||||
|
test_realpath("dir2/dir21/dir211/dir211"); // CHECK: ERROR
|
||||||
|
test_realpath("dir2/dir21/dir211/dir211/e.txt"); // CHECK: ERROR
|
||||||
|
test_realpath("dir2/dir21/dir211/dir211/dir211"); // CHECK: ERROR
|
||||||
|
test_realpath("dir2/dir21/dir211/dir211/dir211/e.txt"); // CHECK: ERROR
|
||||||
|
test_realpath("dir2/dir21/dir211/dir211/dir211/dir211"); // CHECK: ERROR
|
||||||
|
test_realpath("dir2/dir21/dir211/dir211/dir211/dir211/e.txt"); // CHECK: ERROR
|
||||||
|
test_realpath("dir2/linke.txt"); // CHECK: OK
|
||||||
|
test_realpath("dir2/rlinke.txt"); // CHECK: OK
|
||||||
|
|
||||||
|
test_realpath("dir2/./backtoa.txt"); // CHECK: OK
|
||||||
|
test_realpath("dir2/dir21/../backtoa.txt"); // CHECK: OK
|
||||||
|
test_realpath("dir2//backtoa.txt"); // CHECK: OK
|
||||||
|
|
||||||
|
test_realpath("../nofile.txt"); // CHECK: ERROR
|
||||||
|
|
||||||
|
test_realpath("dir2/infloop1.txt"); // CHECK: ERROR
|
||||||
|
test_realpath("dir2/infloop2.txt"); // CHECK: ERROR
|
||||||
|
test_realpath("dir2/selfinfloop.txt"); // CHECK: ERROR
|
||||||
|
test_realpath("dir2/rselfinfloop.txt"); // CHECK: ERROR
|
||||||
|
|
||||||
|
.q
|
Loading…
Reference in New Issue
Block a user