Skip to content

SR-1005: [Foundation] Replace posix_spawn by NSTask #303

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

Closed
wants to merge 8 commits into from
Closed
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
4 changes: 2 additions & 2 deletions Sources/Build/misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/

import func POSIX.getenv
import func POSIX.popen
import func Utility.popen
import func POSIX.mkdir
import PackageType
import Utility
Expand All @@ -24,7 +24,7 @@ public protocol Toolchain {
func platformFrameworksPath() throws -> String {
// Lazily compute the platform the first time it is needed.
struct Static {
static let value = { try? POSIX.popen(["xcrun", "--sdk", "macosx", "--show-sdk-platform-path"]) }()
static let value = { try? Utility.popen(["xcrun", "--sdk", "macosx", "--show-sdk-platform-path"]) }()
}
guard let popened = Static.value, let chuzzled = popened.chuzzle() else {
throw Error.InvalidPlatformPath
Expand Down
23 changes: 12 additions & 11 deletions Sources/ManifestSerializer/Manifest+parse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import PackageDescription
import PackageType
import Utility
import func Utility.fopen
import Foundation

extension Manifest {
public init(path pathComponents: String..., baseURL: String, swiftc: String, libdir: String) throws {
Expand Down Expand Up @@ -66,17 +67,17 @@ private func parse(path manifestPath: String, swiftc: String, libdir: String) th
#endif
cmd += [manifestPath]

//Create and open a temporary file to write toml to
let filePath = Path.join(manifestPath.parentDirectory, ".Package.toml")
let fp = try fopen(filePath, mode: .Write)
defer { fp.closeFile() }

//Pass the fd in arguments
cmd += ["-fileno", "\(fp.fileDescriptor)"]
try system(cmd)

let toml = try fopen(filePath).reduce("") { $0 + "\n" + $1 }
try unlink(filePath) //Delete the temp file after reading it
//Previous implementation used a temporary file, however NSTask doesn't
//allow child process to access parent's file descriptors. So instruct
//swiftc to dump the package information on stdout.
#if os(OSX) || os(iOS)
let handle = NSFileHandle.standardOutput()
#else
let handle = NSFileHandle.fileHandleWithStandardOutput()
#endif

cmd += ["-fileno", String(handle.fileDescriptor)]
let toml = try Utility.popen(cmd)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is rather unfortunate, it was actually a benefit that we could do this through a special file descriptor which also meant logging output could go on stdout and not break anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem here is that NSTask (Cocoa) closes all file descriptors on the child process. A different way would be to pass the path of a temporary file to which the toml is written. Is that fine as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It just doesn't seem worth it to me. I think this is a case where it makes the most sense to use posix_spawn directly rather than work harder just to use NSTask.


return toml != "" ? toml : nil
}
6 changes: 3 additions & 3 deletions Sources/POSIX/Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ extension SystemError: CustomStringConvertible {


public enum Error: ErrorProtocol {
case ExitStatus(Int32, [String])
case ExitStatus(Int32, String, [String])
case ExitSignal
}

Expand All @@ -120,8 +120,8 @@ public enum ShellError: ErrorProtocol {
extension Error: CustomStringConvertible {
public var description: String {
switch self {
case .ExitStatus(let code, let args):
return "exit(\(code)): \(prettyArguments(args))"
case .ExitStatus(let code, let path, let args):
return "exit(\(code)): \(path) \(prettyArguments(args))"

case .ExitSignal:
return "Child process exited with signal"
Expand Down
103 changes: 0 additions & 103 deletions Sources/POSIX/popen.swift

This file was deleted.

117 changes: 0 additions & 117 deletions Sources/POSIX/system.swift

This file was deleted.

2 changes: 2 additions & 0 deletions Sources/Utility/Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public enum Error: ErrorProtocol {
case UnicodeEncodingError
case CouldNotCreateFile(path: String)
case FileDoesNotExist(path: String)
case UnknownCommand(arg0: String)
}

extension Error: CustomStringConvertible {
Expand All @@ -28,6 +29,7 @@ extension Error: CustomStringConvertible {
case .UnicodeEncodingError: return "Could not encode string into unicode"
case .CouldNotCreateFile(let path): return "Could not create file: \(path)"
case .FileDoesNotExist(let path): return "File does not exist: \(path)"
case .UnknownCommand(let arg0): return "Command is not found on the PATH: \(arg0)"
}
}
}
2 changes: 0 additions & 2 deletions Sources/Utility/Platform.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
*/

import func POSIX.popen

public enum Platform {
case Darwin
case Linux(LinuxFlavor)
Expand Down
Loading