Resolve compiler source paths through file descriptors
This commit is contained in:
@@ -73,6 +73,16 @@ if [[ "$(http_marker)" != *"dependency-marker-a"* ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Compiler source canonicalization must retain symlink-target identity while
|
||||
# avoiding realpath's repeated per-segment probes on ordinary source graphs.
|
||||
printf '%s\n' 'String symlink_dependency_marker() { return("symlink-marker-a"); }' >"$source_dir/symlink-target-a.uce"
|
||||
printf '%s\n' 'String symlink_dependency_marker() { return("symlink-marker-b"); }' >"$source_dir/symlink-target-b.uce"
|
||||
ln -s "symlink-target-a.uce" "$source_dir/symlink-child.uce"
|
||||
printf '%s\n' '#load "symlink-child.uce"' 'CLI(Request& context) { print(symlink_dependency_marker()); }' >"$source_dir/symlink-parent.uce"
|
||||
assert_marker symlink-parent symlink-marker-a
|
||||
ln -sfn "symlink-target-b.uce" "$source_dir/symlink-child.uce"
|
||||
assert_marker symlink-parent symlink-marker-b
|
||||
|
||||
# HTTP entry units can resolve route/components dynamically. A changed dynamic
|
||||
# component must enter the demand-priority queue just like a changed entry unit;
|
||||
# otherwise a common dependency rebuild can leave the requested page stale for
|
||||
|
||||
+18
-1
@@ -158,6 +158,23 @@ bool compiler_source_readable(String file_name, const struct stat& info, int* re
|
||||
return(error == 0);
|
||||
}
|
||||
|
||||
String compiler_source_path_real(String file_name)
|
||||
{
|
||||
int fd = open(file_name.c_str(), O_PATH | O_CLOEXEC);
|
||||
if(fd < 0)
|
||||
return(path_real(file_name));
|
||||
String proc_path = "/proc/self/fd/" + std::to_string(fd);
|
||||
char resolved[PATH_MAX];
|
||||
ssize_t length = readlink(proc_path.c_str(), resolved, sizeof(resolved));
|
||||
close(fd);
|
||||
if(length <= 0 || length >= (ssize_t)sizeof(resolved))
|
||||
return(path_real(file_name));
|
||||
String result(resolved, (size_t)length);
|
||||
if(str_ends_with(result, " (deleted)"))
|
||||
return(path_real(file_name));
|
||||
return(result);
|
||||
}
|
||||
|
||||
UnitSourceSignatureEntry compiler_unit_source_entry(String file_name, bool allow_recent_stat)
|
||||
{
|
||||
auto checked_at = std::chrono::steady_clock::now();
|
||||
@@ -204,7 +221,7 @@ void compiler_append_unit_source_signature(String file_name, std::set<String>& v
|
||||
bool recent = allow_recent_stat && compiler_recent_unit_source_entry(normalized, entry);
|
||||
if(!recent)
|
||||
{
|
||||
normalized = path_real(file_name);
|
||||
normalized = compiler_source_path_real(file_name);
|
||||
if(normalized == "")
|
||||
normalized = file_name;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user