Skip to content

Commit f954b76

Browse files
authored
Use _NSGetExecutablePath() instead of proc_pidpath() to get the main executable path. (#374)
This PR switches to `_NSGetExecutablePath()` when getting the path to the current process. `_NSGetExecutablePath()` pulls from the current process' address space, while `proc_pidpath()` involves a syscall and potential sandbox checks. ### 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 286de8c commit f954b76

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

Sources/Testing/Support/Additions/CommandLineAdditions.swift

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,20 @@ extension CommandLine {
2828
static var executablePath: String {
2929
get throws {
3030
#if os(macOS)
31-
return try withUnsafeTemporaryAllocation(of: CChar.self, capacity: Int(PATH_MAX) * 2) { buffer in
32-
guard 0 != proc_pidpath(getpid(), buffer.baseAddress!, UInt32(buffer.count)) else {
33-
throw CError(rawValue: swt_errno())
31+
var result: String?
32+
var bufferCount = UInt32(1024)
33+
while result == nil {
34+
result = withUnsafeTemporaryAllocation(of: CChar.self, capacity: Int(bufferCount)) { buffer in
35+
// _NSGetExecutablePath returns 0 on success and -1 if bufferCount is
36+
// too small. If that occurs, we'll return nil here and loop with the
37+
// new value of bufferCount.
38+
if 0 == _NSGetExecutablePath(buffer.baseAddress, &bufferCount) {
39+
return String(cString: buffer.baseAddress!)
40+
}
41+
return nil
3442
}
35-
return String(cString: buffer.baseAddress!)
3643
}
44+
return result!
3745
#elseif os(Linux)
3846
return try withUnsafeTemporaryAllocation(of: CChar.self, capacity: Int(PATH_MAX) * 2) { buffer in
3947
let readCount = readlink("/proc/\(getpid())/exe", buffer.baseAddress!, buffer.count - 1)
@@ -49,7 +57,7 @@ extension CommandLine {
4957
throw Win32Error(rawValue: GetLastError())
5058
}
5159
guard let path = String.decodeCString(buffer.baseAddress!, as: UTF16.self)?.result else {
52-
throw CError(rawValue: ERROR_ILLEGAL_CHARACTER)
60+
throw Win32Error(rawValue: ERROR_ILLEGAL_CHARACTER)
5361
}
5462
return path
5563
}

0 commit comments

Comments
 (0)