SwiftSlash
SwiftSlash copied to clipboard
Unable to execute "getting started" commands
I'm just looking into using SwiftSlash and am having trouble with getting any commands to execute.
do {
let command = try Command("ps", arguments: ["aux"])
let commandResult = try await command.runSync()
if (commandResult.exitCode == 0) {
let data = commandResult.stdout[0]
print("data: \(data)")
} else {
print("exitCode: \(commandResult.exitCode)")
}
} catch {
print("error: \(error)")
}
This command (along with any others I've tried) results in the resourceUncertainty
error.
I can see that this error is only thrown when getfdlimit(&utilized, &limit)
(of ProcessSpawner.swift
- line #376
) returns a value other than 0. On my machine this is always coming back with a value of 5. I'm assuming getfdlimit
is for getting the file descriptor limit but not sure where to go from here or work out what the underlying issue is.
Machine: MacBook Pro M2 macOS: 13.2.1 Xcode: 14.2 SwiftSlash: 3.4.0
Interesting.....this project was forged from needs I had in backend processes on Linux. I never considered that people may take this and try to run it in a MacOS sandbox. But it appears that is what you have done here. And with this use-case in mind, its hard to imagine how SwiftSlash would work.
Overall, you are looking in the right places and definitely have the right understanding of the problem.
SwiftSlash does a brief "safety dance" for each command that is launched, to ensure the system is able to safely facilitate another concurrent command. One of the first steps of this "safety dance" is throwing, because SwiftSlash cannot read /dev/fd
, which it uses to count vacant file descriptors based against the systems soft limit.
Even if I am to omit (or fix) this safety step, SwiftSlash still will not run, beause ps
is a command that exists outside your sandbox.
If I carry a blind assumption that fork()
is allowed in the MacOS sandbox (a very bad and very blind assumption), the only commands SwiftSlash would be able to run are binaries you precompile and bundle into your application directly.
Sadly, SwiftSlash is subject to sandboxing just like any other library - and while it's not an issue for most libraries, it's (indeed) a huge problem for a shell scripting library. Its just the nature of the beast.
I should document that this use case is not supported (unless you're willing to ship an embedded shell, with additional binaries, as a resource in your app. In which case, there is a slightly nonzero % chance it works).
Thinking I'm closer to closing this ticket. Probably the only reason its not closed is because I'm carrying this vague notion that perhaps I should deliberately check for the sandbox and throw a fatalError
just to make things as clear as possible.
Maybe this is a little reckless but its hard to imagine how else I could clarify this failure path for devs.
re: sandbox, would this be possible through a helper app? https://developer.apple.com/documentation/xcode/embedding-a-helper-tool-in-a-sandboxed-app
That doesn’t look practical for a cross platform Swift package.
If you are serious about going that route, you should fork SwiftSlash and convert it into an Xcode project that only runs on MacOS. Because it looks like the work to do that would be a project just by itself.
This issue will close with the release of the v4.0.0 update. In this release, when built in a debug configuration, SwiftSlash check for the environment variable APP_SANDBOX_CONTAINER_ID
and throw a fatal error if a value is found under this key.