Created
April 17, 2024 19:42
-
-
Save amomchilov/661ea7fd85f1d60292ebaafce263293f to your computer and use it in GitHub Desktop.
List open file descriptors for a process using LibProc's `proc_pidinfo` and `PROC_PIDLISTFDS`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Darwin | |
struct ProcFileDescriptorInfo { | |
let fd: Int32 | |
let path: String | |
} | |
func getFileDescriptors(pid: pid_t) -> [ProcFileDescriptorInfo] { | |
let bufferSize = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, nil, 0) | |
if bufferSize < 0 { | |
print("Error: Failed to get file descriptors") | |
return [] | |
} | |
let stride = MemoryLayout<proc_fdinfo>.stride | |
let allFDs = Array<proc_fdinfo>( | |
unsafeUninitializedCapacity: Int(bufferSize) / stride | |
) { buffer, initializedCount in | |
let initialzedByteCount = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, buffer.baseAddress!, bufferSize) | |
assert(Int(initialzedByteCount).isMultiple(of: stride)) | |
initializedCount = Int(initialzedByteCount) / stride | |
print("count: \(initializedCount) / \(Int(bufferSize) / stride) entries") | |
print("size: \(initialzedByteCount) / \(bufferSize) bytes") | |
} | |
return allFDs.compactMap { fdinfo -> ProcFileDescriptorInfo? in | |
let fd = fdinfo.proc_fd | |
let type = fdinfo.proc_fdtype | |
switch Int32(type) { | |
case PROX_FDTYPE_VNODE: | |
var vnodeInfo = vnode_fdinfowithpath() | |
let vnodeInfoSize = UInt32(MemoryLayout<vnode_fdinfowithpath>.size) | |
let ret = proc_pidfdinfo(pid, fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, Int32(vnodeInfoSize)) | |
if ret <= 0 { | |
print("Error: Failed to retrieve vnode info for file descriptor \(fd) of PID \(pid)") | |
return nil | |
} | |
let path = withUnsafeBytes(of: &vnodeInfo.pvip.vip_path) { rawPtr in | |
let ptr = rawPtr.baseAddress!.assumingMemoryBound(to: CChar.self) | |
return String(cString: ptr) | |
} | |
return ProcFileDescriptorInfo(fd: fd, path: path) | |
case PROX_FDTYPE_ATALK: | |
print("apple talk"); return nil | |
case PROX_FDTYPE_SOCKET: | |
print("socket"); return nil | |
case PROX_FDTYPE_PSHM: | |
print("pshm"); return nil | |
case PROX_FDTYPE_PSEM: | |
print("psem"); return nil | |
case PROX_FDTYPE_KQUEUE: | |
print("kqueue"); return nil | |
case PROX_FDTYPE_PIPE: | |
print("pipe"); return nil | |
case PROX_FDTYPE_FSEVENTS: | |
print("fsevents"); return nil | |
case PROX_FDTYPE_NETPOLICY: | |
print("netpolicy"); return nil | |
case PROX_FDTYPE_CHANNEL: | |
print("channel"); return nil | |
case PROX_FDTYPE_NEXUS: | |
print("nexus"); return nil | |
default: | |
print("unkonwn \(type)"); return nil | |
} | |
} | |
} | |
for info in getFileDescriptors(pid: 1597) { | |
print(info.fd, info.path) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment