Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

281
Views
Abriendo un nuevo archivo de dispositivo pseudo-terminal en macOS con swift

Estoy tratando de mantener un shell ( bash / zsh / etc ) en ejecución mediante el uso de Process de la biblioteca Foundation.

Sé cómo usar Pipe para entrada/salida/error estándar para otros ejecutables de línea de comando, pero parece que los programas de shell requieren que el archivo de entrada/salida/error estándar sea un archivo de dispositivo terminal.

Parece que estos son los archivos llamados /dev/ttys<3 digit number> que se crean para cada nueva instancia de shell. ¿Cómo puedo crear estos archivos yo mismo y usarlos rápidamente?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

SOLUCIÓN:

Así que esto resultó ser mucho más fácil de lo que pensé que sería. Estos son los pasos necesarios para crear un par de objetos FileHandle de pseudo-terminal maestro y esclavo:

  1. Importe el módulo Darwin .
  2. Llame a posix_openpt(int oflag) para obtener un descriptor de archivo para un dispositivo pseudo-terminal maestro disponible.
  3. Llame a grantpt(int filedes) para establecer la propiedad del dispositivo pseudo-terminal esclavo correspondiente.
  4. Llame a unlockpt(int filedes) para desbloquear el dispositivo pseudo-terminal esclavo.
  5. Llame a ptsname(int filedes) para obtener la ruta al dispositivo pseudo-terminal esclavo.
  6. Cree objetos FileHandle utilizando el descriptor de archivo del paso 2 y la ruta del paso 5.

En los pasos 3 a 5, filedes es el descriptor de archivo devuelto por la llamada a posix_openpt(int oflag) del paso 1. Use O_RDRW para el parámetro oflag en el paso 1 para obtener permisos de lectura y escritura en el archivo del dispositivo pseudo-terminal maestro.

Código de ejemplo en el que mantenemos activa una sesión de bash y hacemos que ejecute el comando 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()
over 4 years ago · Santiago Trujillo Report

0

Una respuesta aún más simple que es compatible con Playground.

 import PlaygroundSupport import Foundation import Darwin // use socat to create psudo echo device // socat -d -d -x pty,raw,nonblock,ispeed=115200,echo=0,link=/dev/ttys000 EXEC:/bin/cat print("Started:\n") var masterFile: FileHandle? var masterFD: Int32 = 0 masterFD = open("/dev/ttys000",O_RDWR|O_NONBLOCK) grantpt(masterFD) unlockpt(masterFD) masterFile = FileHandle.init(fileDescriptor: masterFD) masterFile!.write("tty\u{0D}".data(using: String.Encoding.utf8)!) sleep(1) let data1 = masterFile!.availableData let strData1 = String(data: data1, encoding: String.Encoding.utf8)! print("Output: "+strData1)
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!