Comments (9)
Hello @ccjensen thanks for the interest,
I think this will be in the posix spawn call https://github.com/oarrabi/Process/blob/291b63cf8233042537e5b8933c4d9d59c2b99375/Sources/Process/Run.swift#L36
I have researched this before and I remember that interactive was not possible but not 100% sure.
Would be awesome to do more research on it :)
from process.
I believe I had this working when I was working on the VaporToolbox and porting it to use posix spawn from system in the swift 2->3 transition. I believe this has been moved to https://github.com/vapor/console/blob/88e7b2347636c534ef3e8e537ffd31e551e9a161/Sources/Console/Terminal/Terminal.swift
I’ll have a look if I can dig this up again.
from process.
@feinstruktur That would be super helpful, I banged my head around this but couldnt figure it out :S
from process.
I’ve had a look through vapor console and extracted the function that runs the command and prints to the console just like system
used to. I haven’t looked into how this would be be integrated but it’s something that can be dropped in if you need the functionality:
// adopted from (with minor edits): https://github.com/vapor/console/blob/88e7b2347636c534ef3e8e537ffd31e551e9a161/Sources/Console/Terminal/Terminal.swift
import Foundation
public enum ExecuteError: Swift.Error {
case spawnProcess
case execute(code: Int)
case fileOrDirectoryNotFound
}
private var _pids: [UnsafeMutablePointer<pid_t>] = []
public func execute(program: String, arguments: [String]) throws {
let stdin = FileHandle.standardInput
let stdout = FileHandle.standardOutput
let stderr = FileHandle.standardError
try execute(
program: program,
arguments: arguments,
input: stdin.fileDescriptor,
output: stdout.fileDescriptor,
error: stderr.fileDescriptor
)
}
public func execute(program: String, arguments: [String], input: Int32? = nil, output: Int32? = nil, error: Int32? = nil) throws {
var pid = UnsafeMutablePointer<pid_t>.allocate(capacity: 1)
pid.initialize(to: pid_t())
defer {
pid.deinitialize()
pid.deallocate(capacity: 1)
}
let args = [program] + arguments
let argv: [UnsafeMutablePointer<CChar>?] = args.map{ $0.withCString(strdup) }
defer { for case let arg? in argv { free(arg) } }
var environment: [String: String] = ProcessInfo.processInfo.environment
let env: [UnsafeMutablePointer<CChar>?] = environment.map{ "\($0.0)=\($0.1)".withCString(strdup) }
defer { for case let arg? in env { free(arg) } }
#if os(macOS)
var fileActions: posix_spawn_file_actions_t? = nil
#else
var fileActions = posix_spawn_file_actions_t()
#endif
posix_spawn_file_actions_init(&fileActions);
defer {
posix_spawn_file_actions_destroy(&fileActions)
}
if let input = input {
posix_spawn_file_actions_adddup2(&fileActions, input, 0)
}
if let output = output {
posix_spawn_file_actions_adddup2(&fileActions, output, 1)
}
if let error = error {
posix_spawn_file_actions_adddup2(&fileActions, error, 2)
}
_pids.append(pid)
let spawned = posix_spawnp(pid, argv[0], &fileActions, nil, argv + [nil], env + [nil])
if spawned != 0 {
throw ExecuteError.spawnProcess
}
var result: Int32 = 0
_ = waitpid(pid.pointee, &result, 0)
result = result / 256
waitpid(pid.pointee, nil, 0)
if result == ENOENT {
throw ExecuteError.fileOrDirectoryNotFound
} else if result != 0 {
throw ExecuteError.execute(code: Int(result))
}
}
You can drop this into a file in this repo.
from process.
@feinstruktur This looks cool! Thanks for sharing.
This works interactively since it does not capture the stdout and stderr. Is that correct?
from process.
Yes, it essentially routes everything through to the terminal and I'm using it in cases where I want to show intermediate output. If you plug that in and run a longer running command with intermediate output, like for instance find / -name "*.sh"
, through it you'll see what I mean.
I haven't tried but I'm sure you can grab stdout and stdout for reading in order to still return them as a result.
I would offer to try and integrate that but I'm not sure if/when I'd find the time!
from process.
@feinstruktur I have added this on my todo list. I think that if we provide our own dup of the stdin, then the interactiveness will be lost.
I will try this flavour of posix spawn and report to this issue what I found.
Thank you for the hint :)
from process.
@nsomar Any updates?
from process.
@mominul I didnt really have a chance to look into this. I am afraid I wont have enough time to look at this anytime soon :(
from process.
Related Issues (4)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from process.