Skip to content

Commit 10970ce

Browse files
authored
Avoid PATH_MAX when getting the executable path on Linux and OpenBSD. (#1403)
This PR adjusts the implementations of `CommandLine.executablePath` on Linux and OpenBSD to avoid an artificial upper bound based on `PATH_MAX`. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
1 parent e727d1a commit 10970ce

File tree

2 files changed

+21
-9
lines changed

2 files changed

+21
-9
lines changed

Sources/Testing/Support/Additions/CommandLineAdditions.swift

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,27 @@ extension CommandLine {
3333
}
3434
return result!
3535
#elseif os(Linux) || os(Android)
36-
return try withUnsafeTemporaryAllocation(of: CChar.self, capacity: Int(PATH_MAX) * 2) { buffer in
37-
let readCount = readlink("/proc/self/exe", buffer.baseAddress!, buffer.count - 1)
38-
guard readCount >= 0 else {
39-
throw CError(rawValue: swt_errno())
36+
var result: String?
37+
#if DEBUG
38+
var bufferCount = Int(1) // force looping
39+
#else
40+
var bufferCount = Int(PATH_MAX)
41+
#endif
42+
while result == nil {
43+
try withUnsafeTemporaryAllocation(of: CChar.self, capacity: bufferCount) { buffer in
44+
let readCount = readlink("/proc/self/exe", buffer.baseAddress!, buffer.count)
45+
guard readCount >= 0 else {
46+
throw CError(rawValue: swt_errno())
47+
}
48+
if readCount < buffer.count {
49+
buffer[readCount] = 0 // NUL-terminate the string.
50+
result = String(cString: buffer.baseAddress!)
51+
} else {
52+
bufferCount += Int(PATH_MAX) // add more space and try again
53+
}
4054
}
41-
buffer[readCount] = 0 // NUL-terminate the string.
42-
return String(cString: buffer.baseAddress!)
4355
}
56+
return result!
4457
#elseif os(FreeBSD)
4558
var mib = [CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1]
4659
return try mib.withUnsafeMutableBufferPointer { mib in

Sources/_TestingInternals/ExecutablePath.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@ static constinit std::atomic<const char *> earlyCWD { nullptr };
2424
/// path (which can occur when manually invoking the test executable.)
2525
__attribute__((__constructor__(101), __used__))
2626
static void captureEarlyCWD(void) {
27-
static char buffer[PATH_MAX * 2];
28-
if (getcwd(buffer, sizeof(buffer))) {
29-
earlyCWD.store(buffer);
27+
if (auto cwd = getcwd(nil, 0)) {
28+
earlyCWD.store(cwd);
3029
}
3130
}
3231
#endif

0 commit comments

Comments
 (0)