Skip to content

Revert "Add support for Process stdin stream" #143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 21 additions & 65 deletions Sources/TSCBasic/Process.swift
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,8 @@ public final class Process: ObjectIdentifierProtocol {
}
}

/// Launch the subprocess. Returns a WritableByteStream object that can be used to communicate to the process's
/// stdin. If needed, the stream can be closed using the close() API. Otherwise, the stream will be closed
/// automatically.
@discardableResult
public func launch() throws -> WritableByteStream {
/// Launch the subprocess.
public func launch() throws {
precondition(arguments.count > 0 && !arguments[0].isEmpty, "Need at least one argument to launch the process.")
precondition(!launched, "It is not allowed to launch the same process object again.")

Expand All @@ -354,15 +351,12 @@ public final class Process: ObjectIdentifierProtocol {
throw Process.Error.missingExecutableProgram(program: executable)
}

#if os(Windows)
#if os(Windows)
_process = Foundation.Process()
_process?.arguments = Array(arguments.dropFirst()) // Avoid including the executable URL twice.
_process?.executableURL = executablePath.asURL
_process?.environment = environment

let stdinPipe = Pipe()
_process?.standardInput = stdinPipe

if outputRedirection.redirectsOutput {
let stdoutPipe = Pipe()
let stderrPipe = Pipe()
Expand All @@ -385,8 +379,6 @@ public final class Process: ObjectIdentifierProtocol {
}

try _process?.run()

return stdinPipe.fileHandleForWriting
#else
// Initialize the spawn attributes.
#if canImport(Darwin) || os(Android)
Expand Down Expand Up @@ -461,17 +453,14 @@ public final class Process: ObjectIdentifierProtocol {
#endif
}

var stdinPipe: [Int32] = [-1, -1]
try open(pipe: &stdinPipe)

let stdinStream = try LocalFileOutputByteStream(filePointer: fdopen(stdinPipe[1], "wb"), closeOnDeinit: true)

// Dupe the read portion of the remote to 0.
posix_spawn_file_actions_adddup2(&fileActions, stdinPipe[0], 0)

// Close the other side's pipe since it was dupped to 0.
posix_spawn_file_actions_addclose(&fileActions, stdinPipe[0])
posix_spawn_file_actions_addclose(&fileActions, stdinPipe[1])
// Workaround for https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=89e435f3559c53084498e9baad22172b64429362
// Change allowing for newer version of glibc
guard let devNull = strdup("/dev/null") else {
throw SystemError.posix_spawn(0, arguments)
}
defer { free(devNull) }
// Open /dev/null as stdin.
posix_spawn_file_actions_addopen(&fileActions, 0, devNull, O_RDONLY, 0)

var outputPipe: [Int32] = [-1, -1]
var stderrPipe: [Int32] = [-1, -1]
Expand All @@ -482,7 +471,7 @@ public final class Process: ObjectIdentifierProtocol {
// Open the write end of the pipe.
posix_spawn_file_actions_adddup2(&fileActions, outputPipe[1], 1)

// Close the other ends of the pipe since they were dupped to 1.
// Close the other ends of the pipe.
posix_spawn_file_actions_addclose(&fileActions, outputPipe[0])
posix_spawn_file_actions_addclose(&fileActions, outputPipe[1])

Expand All @@ -494,7 +483,7 @@ public final class Process: ObjectIdentifierProtocol {
try open(pipe: &stderrPipe)
posix_spawn_file_actions_adddup2(&fileActions, stderrPipe[1], 2)

// Close the other ends of the pipe since they were dupped to 2.
// Close the other ends of the pipe.
posix_spawn_file_actions_addclose(&fileActions, stderrPipe[0])
posix_spawn_file_actions_addclose(&fileActions, stderrPipe[1])
}
Expand All @@ -511,14 +500,11 @@ public final class Process: ObjectIdentifierProtocol {
throw SystemError.posix_spawn(rv, arguments)
}

// Close the local read end of the input pipe.
try close(fd: stdinPipe[0])

if outputRedirection.redirectsOutput {
let outputClosures = outputRedirection.outputClosures

// Close the local write end of the output pipe.
try close(fd: outputPipe[1])
// Close the write end of the output pipe.
try close(fd: &outputPipe[1])

// Create a thread and start reading the output on it.
var thread = Thread { [weak self] in
Expand All @@ -531,8 +517,8 @@ public final class Process: ObjectIdentifierProtocol {

// Only schedule a thread for stderr if no redirect was requested.
if !outputRedirection.redirectStderr {
// Close the local write end of the stderr pipe.
try close(fd: stderrPipe[1])
// Close the write end of the stderr pipe.
try close(fd: &stderrPipe[1])

// Create a thread and start reading the stderr output on it.
thread = Thread { [weak self] in
Expand All @@ -544,8 +530,6 @@ public final class Process: ObjectIdentifierProtocol {
self.stderr.thread = thread
}
}

return stdinStream
#endif // POSIX implementation
}

Expand Down Expand Up @@ -747,15 +731,11 @@ private func open(pipe: inout [Int32]) throws {
}

/// Close the given fd.
private func close(fd: Int32) throws {
func innerClose(_ fd: inout Int32) throws {
let rv = TSCLibc.close(fd)
guard rv == 0 else {
throw SystemError.close(rv)
}
private func close(fd: inout Int32) throws {
let rv = TSCLibc.close(fd)
guard rv == 0 else {
throw SystemError.close(rv)
}
var innerFd = fd
try innerClose(&innerFd)
}

extension Process.Error: CustomStringConvertible {
Expand Down Expand Up @@ -808,27 +788,3 @@ extension ProcessResult.Error: CustomStringConvertible {
}
}
}

#if os(Windows)
extension FileHandle: WritableByteStream {
public var position: Int {
return Int(offsetInFile)
}

public func write(_ byte: UInt8) {
write(Data([byte]))
}

public func write<C: Collection>(_ bytes: C) where C.Element == UInt8 {
write(Data(bytes))
}

public func flush() {
synchronizeFile()
}

public func close() throws {
closeFile()
}
}
#endif
17 changes: 0 additions & 17 deletions Tests/TSCBasicTests/ProcessTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -188,23 +188,6 @@ class ProcessTests: XCTestCase {
XCTAssertEqual(result2, "hello\n")
}

func testStdin() throws {
var stdout = [UInt8]()
let process = Process(args: script("in-to-out"), outputRedirection: .stream(stdout: { stdoutBytes in
stdout += stdoutBytes
}, stderr: { _ in }))
let stdinStream = try process.launch()

stdinStream.write("hello\n")
stdinStream.flush()

try stdinStream.close()

try process.waitUntilExit()

XCTAssertEqual(String(decoding: stdout, as: UTF8.self), "hello\n")
}

func testStdoutStdErr() throws {
// A simple script to check that stdout and stderr are captured separatly.
do {
Expand Down
5 changes: 0 additions & 5 deletions Tests/TSCBasicTests/processInputs/in-to-out

This file was deleted.