Skip to content

Commit 961d9fa

Browse files
authored
Merge pull request #1812 from ddunbar/process-result-is-uint8
[Basic] Use UInt8 as the native process output type.
2 parents 7d8757c + 9566554 commit 961d9fa

File tree

2 files changed

+15
-32
lines changed

2 files changed

+15
-32
lines changed

Sources/Basic/Process.swift

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,20 @@ public struct ProcessResult: CustomStringConvertible {
4242

4343
/// The output bytes of the process. Available only if the process was
4444
/// asked to redirect its output and no stdout output closure was set.
45-
public let output: Result<[Int8], AnyError>
45+
public let output: Result<[UInt8], AnyError>
4646

4747
/// The output bytes of the process. Available only if the process was
4848
/// asked to redirect its output and no stderr output closure was set.
49-
public let stderrOutput: Result<[Int8], AnyError>
49+
public let stderrOutput: Result<[UInt8], AnyError>
5050

5151
/// Create an instance using a POSIX process exit status code and output result.
5252
///
5353
/// See `waitpid(2)` for information on the exit status code.
5454
public init(
5555
arguments: [String],
5656
exitStatusCode: Int32,
57-
output: Result<[Int8], AnyError>,
58-
stderrOutput: Result<[Int8], AnyError>
57+
output: Result<[UInt8], AnyError>,
58+
stderrOutput: Result<[UInt8], AnyError>
5959
) {
6060
let exitStatus: ExitStatus
6161
if WIFSIGNALED(exitStatusCode) {
@@ -72,8 +72,8 @@ public struct ProcessResult: CustomStringConvertible {
7272
public init(
7373
arguments: [String],
7474
exitStatus: ExitStatus,
75-
output: Result<[Int8], AnyError>,
76-
stderrOutput: Result<[Int8], AnyError>
75+
output: Result<[UInt8], AnyError>,
76+
stderrOutput: Result<[UInt8], AnyError>
7777
) {
7878
self.arguments = arguments
7979
self.output = output
@@ -82,28 +82,13 @@ public struct ProcessResult: CustomStringConvertible {
8282
}
8383

8484
/// Converts stdout output bytes to string, assuming they're UTF8.
85-
///
86-
/// - Throws: Error while reading the process output or if output is not a valid UTF8 sequence.
8785
public func utf8Output() throws -> String {
88-
return try utf8Result(output)
86+
return String(decoding: try output.dematerialize(), as: Unicode.UTF8.self)
8987
}
9088

9189
/// Converts stderr output bytes to string, assuming they're UTF8.
92-
///
93-
/// - Throws: Error while reading the process output or if output is not a valid UTF8 sequence.
9490
public func utf8stderrOutput() throws -> String {
95-
return try utf8Result(stderrOutput)
96-
}
97-
98-
/// Returns UTF8 string from given result or throw.
99-
private func utf8Result(_ result: Result<[Int8], AnyError>) throws -> String {
100-
var bytes = try result.dematerialize()
101-
// Null terminate it.
102-
bytes.append(0)
103-
if let output = String(validatingUTF8: bytes) {
104-
return output
105-
}
106-
throw Error.illegalUTF8Sequence
91+
return String(decoding: try stderrOutput.dematerialize(), as: Unicode.UTF8.self)
10792
}
10893

10994
public var description: String {
@@ -157,7 +142,7 @@ public final class Process: ObjectIdentifierProtocol {
157142
public typealias ProcessID = pid_t
158143

159144
/// Typealias for stdout/stderr output closure.
160-
public typealias OutputClosure = ([Int8]) -> Void
145+
public typealias OutputClosure = ([UInt8]) -> Void
161146

162147
/// Global default setting for verbose.
163148
public static var verbose = false
@@ -198,10 +183,10 @@ public final class Process: ObjectIdentifierProtocol {
198183
private var _result: ProcessResult?
199184

200185
/// If redirected, stdout result and reference to the thread reading the output.
201-
private var stdout: (result: Result<[Int8], AnyError>, thread: Thread?) = (Result([]), nil)
186+
private var stdout: (result: Result<[UInt8], AnyError>, thread: Thread?) = (Result([]), nil)
202187

203188
/// If redirected, stderr result and reference to the thread reading the output.
204-
private var stderr: (result: Result<[Int8], AnyError>, thread: Thread?) = (Result([]), nil)
189+
private var stderr: (result: Result<[UInt8], AnyError>, thread: Thread?) = (Result([]), nil)
205190

206191
/// Queue to protect concurrent reads.
207192
private let serialQueue = DispatchQueue(label: "org.swift.swiftpm.process")
@@ -440,12 +425,12 @@ public final class Process: ObjectIdentifierProtocol {
440425
/// Reads the given fd and returns its result.
441426
///
442427
/// Closes the fd before returning.
443-
private func readOutput(onFD fd: Int32, outputClosure: OutputClosure?) -> Result<[Int8], AnyError> {
428+
private func readOutput(onFD fd: Int32, outputClosure: OutputClosure?) -> Result<[UInt8], AnyError> {
444429
// Read all of the data from the output pipe.
445430
let N = 4096
446-
var buf = [Int8](repeating: 0, count: N + 1)
431+
var buf = [UInt8](repeating: 0, count: N + 1)
447432

448-
var out = [Int8]()
433+
var out = [UInt8]()
449434
var error: Swift.Error? = nil
450435
loop: while true {
451436
let n = read(fd, &buf, N)

Sources/SourceControl/GitRepository.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,7 @@ public class GitRepository: Repository, WorkingCheckout {
414414
let result = try Process.popen(arguments: argsWithSh)
415415
let output = try result.output.dematerialize()
416416

417-
let outputs: [String] = output.split(separator: 0).map(Array.init).map({ (bytes: [Int8]) -> String in
418-
return String(cString: bytes + [0])
419-
})
417+
let outputs: [String] = output.split(separator: 0).map({ String(decoding: $0, as: Unicode.UTF8.self) })
420418

421419
guard result.exitStatus == .terminated(code: 0) || result.exitStatus == .terminated(code: 1) else {
422420
throw GitInterfaceError.fatalError

0 commit comments

Comments
 (0)