从 swift 调用 nettop:"Unable to allocate a kernel control socket"
Calling nettop from swift: "Unable to allocate a kernel control socket"
我正在为命令行 nettop
实用程序编写一个 macOS GUI 包装器。
当我通过 zsh 从终端应用程序调用 nettop -P -L 1
时,它会显示正确的输出,但是当我从我的 Swift 应用程序中启动进程时,它会在我的应用程序中显示以下内容:
nettop[19213:2351456] [NetworkStatistics] Unable to allocate a kernel control socket nettop: NStatManagerCreate failed
这是某种权限或沙盒问题吗?如果是,我如何让我的应用请求适当的权限?
代码片段:
func shell(launchPath: String, arguments: [String] = []) -> (String? , Int32) {
let task = Process()
task.launchPath = launchPath
task.arguments = arguments
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)
task.waitUntilExit()
return (output, task.terminationStatus)
}
...
struct ContentView: View {
var body: some View {
Text(shell(launchPath: "/usr/bin/nettop", arguments: ["-P", "-L", "1"]).0 ?? "No Output")
}
}
这确实是一个沙箱问题:nettop 通过创建一个 com.apple.network.statistics PF_SYSTEM/SYSPROTO_CONTROL 套接字进行操作(来源示例可以在 http://newosxbook.com/code/listings/17-1-lsock.c 中看到),它可以是沙盒化。
对该套接字的访问受到两层限制:
当 net.statistics_privcheck sysctl 设置为 1 时,将强制执行 com.apple.private.network.statistics 权利。这不是你的情况,因为你正在执行 nettop,它无论如何都有权利
除非
明确允许,否则沙盒配置文件会阻止创建系统套接字
(allow network-outbound
(control-name "com.apple.network.statistics")
(control-name "com.apple.netsrc"))
规则。
您的情况似乎是后一种情况,但从您的详细信息来看,尚不清楚故障是在您自己的应用程序的沙箱配置文件中还是在 exec'ed nettop 中。要确定这一点,请尝试自己创建套接字 - 如果您可以这样做,那就是 exec 的问题。如果你不能,那就是你自己的个人资料。可以创建您自己的沙盒配置文件,但 Apple 永远不会公开允许这样做,并且可能会让您被踢出 App Store。
另一项测试 - 运行 直接从命令行运行您的应用。 (也就是说,在终端中,然后是 /Applications/path/to/your.app/Contents/MacOS/yourApp)。这样,它就不会被 xpcproxy 启动,并且会受到较少的沙箱限制。
我正在为命令行 nettop
实用程序编写一个 macOS GUI 包装器。
当我通过 zsh 从终端应用程序调用 nettop -P -L 1
时,它会显示正确的输出,但是当我从我的 Swift 应用程序中启动进程时,它会在我的应用程序中显示以下内容:
nettop[19213:2351456] [NetworkStatistics] Unable to allocate a kernel control socket nettop: NStatManagerCreate failed
这是某种权限或沙盒问题吗?如果是,我如何让我的应用请求适当的权限?
代码片段:
func shell(launchPath: String, arguments: [String] = []) -> (String? , Int32) {
let task = Process()
task.launchPath = launchPath
task.arguments = arguments
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.launch()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)
task.waitUntilExit()
return (output, task.terminationStatus)
}
...
struct ContentView: View {
var body: some View {
Text(shell(launchPath: "/usr/bin/nettop", arguments: ["-P", "-L", "1"]).0 ?? "No Output")
}
}
这确实是一个沙箱问题:nettop 通过创建一个 com.apple.network.statistics PF_SYSTEM/SYSPROTO_CONTROL 套接字进行操作(来源示例可以在 http://newosxbook.com/code/listings/17-1-lsock.c 中看到),它可以是沙盒化。
对该套接字的访问受到两层限制:
当 net.statistics_privcheck sysctl 设置为 1 时,将强制执行 com.apple.private.network.statistics 权利。这不是你的情况,因为你正在执行 nettop,它无论如何都有权利
除非
明确允许,否则沙盒配置文件会阻止创建系统套接字(allow network-outbound (control-name "com.apple.network.statistics") (control-name "com.apple.netsrc"))
规则。
您的情况似乎是后一种情况,但从您的详细信息来看,尚不清楚故障是在您自己的应用程序的沙箱配置文件中还是在 exec'ed nettop 中。要确定这一点,请尝试自己创建套接字 - 如果您可以这样做,那就是 exec 的问题。如果你不能,那就是你自己的个人资料。可以创建您自己的沙盒配置文件,但 Apple 永远不会公开允许这样做,并且可能会让您被踢出 App Store。
另一项测试 - 运行 直接从命令行运行您的应用。 (也就是说,在终端中,然后是 /Applications/path/to/your.app/Contents/MacOS/yourApp)。这样,它就不会被 xpcproxy 启动,并且会受到较少的沙箱限制。