РЕШЕНИЕ:
Так что все оказалось намного проще, чем я думал.Вот шаги, необходимые для создания пары главных и подчиненных псевдотерминалов FileHandle
объектов:
- Импорт модуля
Darwin
. - Позвоните на
posix_openpt(int oflag)
, чтобы получитьдескриптор файла для доступного главного псевдо-терминального устройства. - Позвоните на
grantpt(int filedes)
, чтобы установить право собственности на соответствующее подчиненное псевдо-терминальное устройство. - Позвоните на
unlockpt(int filedes)
, чтобы разблокировать подчиненное псевдо-терминальное устройство.-терминальное устройство. - Вызовите
ptsname(int filedes)
, чтобы получить путь к подчиненному псевдотерминальному устройству. - Создание
FileHandle
объектов с использованием файлового дескриптора из шага 2 и пути из шага 5.
На шагах 3 - 5 filedes
- дескриптор файла, возвращаемый вызовом posix_openpt(int oflag)
с шага 1. Используйте O_RDRW
для параметра oflag
на шаге 1 для разрешений на чтение и записьв главном файле устройства псевдотерминала.
Пример кода, в котором мы поддерживаем сеанс bash
и запускаем команду tty
:
import Foundation
import Darwin
class A: NSObject {
var task: Process?
var slaveFile: FileHandle?
var masterFile: FileHandle?
override init() {
self.task = Process()
var masterFD: Int32 = 0
masterFD = posix_openpt(O_RDWR)
grantpt(masterFD)
unlockpt(masterFD)
self.masterFile = FileHandle.init(fileDescriptor: masterFD)
let slavePath = String.init(cString: ptsname(masterFD))
self.slaveFile = FileHandle.init(forUpdatingAtPath: slavePath)
self.task!.executableURL = URL(fileURLWithPath: "/bin/bash")
self.task!.arguments = ["-i"]
self.task!.standardOutput = slaveFile
self.task!.standardInput = slaveFile
self.task!.standardError = slaveFile
}
func run() {
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
guard let self = self else {
return
}
do {
try self.task!.run()
} catch {
print("Something went wrong.\n")
}
}
let data = self.masterFile!.availableData
let strData = String(data: data, encoding: String.Encoding.utf8)!
print("Output: "+strData)
self.masterFile!.write("tty\u{0D}".data(using: String.Encoding.utf8)!)
sleep(1)
let data1 = self.masterFile!.availableData
let strData1 = String(data: data1, encoding: String.Encoding.utf8)!
print("Output: "+strData1)
}
}
let a = A()
a.run()