Skip to content

Commit 07f4c1a

Browse files
authored
Merge pull request #2586 from weissi/jw-dont-rely-getdtablesize
don't rely on getdtablesize()
2 parents b45ce94 + 077775e commit 07f4c1a

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

Foundation/Process.swift

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,43 @@ extension CFSocketError {
6060
}
6161
#endif
6262

63+
#if !canImport(Darwin) && !os(Windows)
64+
private func findMaximumOpenFromProcSelfFD() -> CInt? {
65+
guard let dirPtr = opendir("/proc/self/fd") else {
66+
return nil
67+
}
68+
defer {
69+
closedir(dirPtr)
70+
}
71+
var highestFDSoFar = CInt(0)
72+
73+
while let dirEntPtr = readdir(dirPtr) {
74+
var entryName = dirEntPtr.pointee.d_name
75+
let thisFD = withUnsafeBytes(of: &entryName) { entryNamePtr -> CInt? in
76+
CInt(String(decoding: entryNamePtr.prefix(while: { $0 != 0 }), as: Unicode.UTF8.self))
77+
}
78+
highestFDSoFar = max(thisFD ?? -1, highestFDSoFar)
79+
}
80+
81+
return highestFDSoFar
82+
}
83+
84+
func findMaximumOpenFD() -> CInt {
85+
if let maxFD = findMaximumOpenFromProcSelfFD() {
86+
// the precise method worked, let's return this fd.
87+
return maxFD
88+
}
89+
90+
// We don't have /proc, let's go with the best estimate.
91+
#if os(Linux)
92+
return getdtablesize()
93+
#else
94+
return 4096
95+
#endif
96+
}
97+
#endif
98+
99+
63100
private func emptyRunLoopCallback(_ context : UnsafeMutableRawPointer?) -> Void {}
64101

65102

@@ -881,7 +918,7 @@ open class Process: NSObject {
881918
posix_spawnattr_init(&spawnAttrs)
882919
posix_spawnattr_setflags(&spawnAttrs, .init(POSIX_SPAWN_CLOEXEC_DEFAULT))
883920
#else
884-
for fd in 3 ..< getdtablesize() {
921+
for fd in 3 ... findMaximumOpenFD() {
885922
guard adddup2[fd] == nil &&
886923
!addclose.contains(fd) &&
887924
fd != taskSocketPair[1] else {

TestFoundation/xdgTestHelper/main.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,13 @@ func cat(_ args: ArraySlice<String>.Iterator) {
198198

199199
#if !os(Windows)
200200
func printOpenFileDescriptors() {
201-
for fd in 0..<getdtablesize() {
201+
let reasonableMaxFD: CInt
202+
#if os(Linux) || os(macOS)
203+
reasonableMaxFD = getdtablesize()
204+
#else
205+
reasonableMaxFD = 4096
206+
#endif
207+
for fd in 0..<reasonableMaxFD {
202208
if fcntl(fd, F_GETFD) != -1 {
203209
print(fd)
204210
}

0 commit comments

Comments
 (0)