From c0e44dc9010016e000e17a1d761d9a83cfd493ff Mon Sep 17 00:00:00 2001 From: Samasaur1 <30577766+Samasaur1@users.noreply.github.com> Date: Sun, 23 Oct 2022 22:29:39 -0700 Subject: [PATCH 1/2] Convert to posix_spawn --- Sources/REPL/main.swift | 71 +++++++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 21 deletions(-) diff --git a/Sources/REPL/main.swift b/Sources/REPL/main.swift index f3ed3a8..d15d65a 100644 --- a/Sources/REPL/main.swift +++ b/Sources/REPL/main.swift @@ -177,35 +177,22 @@ func prompt() -> String { // waitpid(pid, nil, 0) //} -var task: Process = Process() -func exec(_ command: String) -> String { - task = Process() - task.launchPath = "/bin/bash" - task.arguments = ["-c", command] - - let pipe = Pipe() - task.standardOutput = pipe - task.launch() - - let data = pipe.fileHandleForReading.readDataToEndOfFile() - let output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue)! as String - - return output -} - // MARK: - Begin REPL print("Initializing REPL with command: \(command)") print("Use ^D to exit") print() -var key: Int = 0 -let c: cc_t = 0 -let cct = (c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c) // Set of 20 Special Characters -var originalTerm: termios = termios(c_iflag: 0, c_oflag: 0, c_cflag: 0, c_lflag: 0, c_cc: cct, c_ispeed: 0, c_ospeed: 0) +var originalTerm = termios() tcgetattr(STDIN_FILENO, &originalTerm) //this gets the current settings + print(originalTerm.c_lflag & UInt(ECHO)) + print(originalTerm.c_lflag & UInt(ICANON)) var term = originalTerm term.c_lflag &= ~(UInt(Darwin.ECHO) | UInt(Darwin.ICANON)) //turn off ECHO and ICANON tcsetattr(STDIN_FILENO, TCSANOW, &term) //set these new settings +dump(originalTerm) +dump(term) + +var __t = termios() func resetTermAndExitWith(sig: Int32) { tcsetattr(STDIN_FILENO, TCSANOW, &originalTerm) @@ -216,6 +203,47 @@ signal(SIGTERM, resetTermAndExitWith(sig:)) signal(SIGQUIT, resetTermAndExitWith(sig:)) signal(SIGSTOP, resetTermAndExitWith(sig:)) +var task: Process = Process() +func exec(_ command: String) -> String { + /* + task = Process() + task.launchPath = "/bin/bash" + task.arguments = ["-c", command] + + let pipe = Pipe() + task.standardOutput = pipe + task.launch() + + let data = pipe.fileHandleForReading.readDataToEndOfFile() + let output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue)! as String + + return output + */ + var pid = pid_t() + let args = ["/usr/bin/env"] + command.split(separator: " ").map(String.init) + let c_args = args.map { $0.withCString(strdup)! } + defer { for arg in c_args { free(arg) } } + tcgetattr(STDIN_FILENO, &__t) + dump(__t) + print(__t.c_lflag & UInt(ECHO)) + print(__t.c_lflag & UInt(ICANON)) + //__t.c_lflag |= + tcsetattr(STDIN_FILENO, TCSANOW, &originalTerm) + tcgetattr(STDIN_FILENO, &__t) + dump(__t) + print(__t.c_lflag & UInt(ECHO)) + print(__t.c_lflag & UInt(ICANON)) + posix_spawn(&pid, c_args[0], nil, nil, c_args + [nil], environ) + tcsetattr(STDIN_FILENO, TCSANOW, &term) + tcgetattr(STDIN_FILENO, &__t) + dump(__t) + print(__t.c_lflag & UInt(ECHO)) + print(__t.c_lflag & UInt(ICANON)) + waitpid(pid, nil, 0) + return "" +} + + var chars: [Int32] = [] var charIdx = 0 var commands: [String] = [""] @@ -307,7 +335,8 @@ while true { print() if !chars.isEmpty { let input = String(chars.map { Character(UnicodeScalar(UInt32($0))!) }) - print(exec("\(command) \(input)"), terminator: "") + //print(exec("\(command) \(input)"), terminator: "") + exec("\(command) \(input)") commands.append(input) } chars = [] From dabf1ead76721981632b10e4177f93dafb3f8e4a Mon Sep 17 00:00:00 2001 From: Samasaur1 <30577766+Samasaur1@users.noreply.github.com> Date: Sun, 23 Oct 2022 22:58:00 -0700 Subject: [PATCH 2/2] Remove dumped info For some reason, this does not correctly turn on ECHO although for programs that set the term on their own (e.g., neovim), they run fine anyway --- Sources/REPL/main.swift | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/Sources/REPL/main.swift b/Sources/REPL/main.swift index d15d65a..989a3d6 100644 --- a/Sources/REPL/main.swift +++ b/Sources/REPL/main.swift @@ -184,13 +184,9 @@ print() var originalTerm = termios() tcgetattr(STDIN_FILENO, &originalTerm) //this gets the current settings - print(originalTerm.c_lflag & UInt(ECHO)) - print(originalTerm.c_lflag & UInt(ICANON)) var term = originalTerm term.c_lflag &= ~(UInt(Darwin.ECHO) | UInt(Darwin.ICANON)) //turn off ECHO and ICANON tcsetattr(STDIN_FILENO, TCSANOW, &term) //set these new settings -dump(originalTerm) -dump(term) var __t = termios() @@ -224,21 +220,14 @@ func exec(_ command: String) -> String { let c_args = args.map { $0.withCString(strdup)! } defer { for arg in c_args { free(arg) } } tcgetattr(STDIN_FILENO, &__t) - dump(__t) - print(__t.c_lflag & UInt(ECHO)) - print(__t.c_lflag & UInt(ICANON)) - //__t.c_lflag |= - tcsetattr(STDIN_FILENO, TCSANOW, &originalTerm) - tcgetattr(STDIN_FILENO, &__t) - dump(__t) - print(__t.c_lflag & UInt(ECHO)) - print(__t.c_lflag & UInt(ICANON)) + __t.c_lflag |= (UInt(ECHO) | UInt(ICANON)) + //tcsetattr(STDIN_FILENO, TCSANOW, &originalTerm) + tcsetattr(STDIN_FILENO, TCSANOW, &__t) posix_spawn(&pid, c_args[0], nil, nil, c_args + [nil], environ) - tcsetattr(STDIN_FILENO, TCSANOW, &term) tcgetattr(STDIN_FILENO, &__t) - dump(__t) - print(__t.c_lflag & UInt(ECHO)) - print(__t.c_lflag & UInt(ICANON)) + __t.c_lflag &= ~(UInt(ECHO) | UInt(ICANON)) + //tcsetattr(STDIN_FILENO, TCSANOW, &term) + tcsetattr(STDIN_FILENO, TCSANOW, &__t) waitpid(pid, nil, 0) return "" }