Fix embed terminal in macos

Pseudoterminal wasn't created correctly on macos
pull/144/head
Manos Pitsidianakis 2022-07-31 18:16:11 +03:00
parent ca84906d7d
commit daa900ec9a
2 changed files with 39 additions and 17 deletions

View File

@ -181,7 +181,7 @@ pub mod shellexpand {
use smallvec::SmallVec; use smallvec::SmallVec;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::os::unix::ffi::OsStrExt; use std::os::unix::ffi::OsStrExt;
#[cfg(not(target_os = "netbsd"))] #[cfg(not(any(target_os = "netbsd", target_os = "macos")))]
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};

View File

@ -23,10 +23,15 @@ use crate::terminal::position::*;
use melib::{error::*, log, ERROR}; use melib::{error::*, log, ERROR};
use smallvec::SmallVec; use smallvec::SmallVec;
use nix::fcntl::{open, OFlag}; #[cfg(not(target_os = "macos"))]
use nix::{
fcntl::{open, OFlag},
pty::{grantpt, posix_openpt, ptsname, unlockpt},
sys::stat,
};
use nix::libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO}; use nix::libc::{STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO};
use nix::pty::{grantpt, posix_openpt, ptsname, unlockpt, Winsize}; use nix::pty::Winsize;
use nix::sys::stat;
use nix::unistd::{dup2, fork, ForkResult}; use nix::unistd::{dup2, fork, ForkResult};
use nix::{ioctl_none_bad, ioctl_write_ptr_bad}; use nix::{ioctl_none_bad, ioctl_write_ptr_bad};
use std::ffi::{CString, OsStr}; use std::ffi::{CString, OsStr};
@ -43,6 +48,8 @@ pub use grid::{EmbedGrid, EmbedTerminal};
use libc::TIOCSCTTY; use libc::TIOCSCTTY;
// ioctl request code to set window size of pty: // ioctl request code to set window size of pty:
use libc::TIOCSWINSZ; use libc::TIOCSWINSZ;
#[cfg(not(target_os = "macos"))]
use std::path::Path; use std::path::Path;
use std::convert::TryFrom; use std::convert::TryFrom;
@ -60,19 +67,33 @@ pub fn create_pty(
height: usize, height: usize,
command: String, command: String,
) -> Result<Arc<Mutex<EmbedTerminal>>> { ) -> Result<Arc<Mutex<EmbedTerminal>>> {
// Open a new PTY master #[cfg(not(target_os = "macos"))]
let master_fd = posix_openpt(OFlag::O_RDWR)?; let (master_fd, slave_name) = {
// Open a new PTY master
let master_fd = posix_openpt(OFlag::O_RDWR)?;
// Allow a slave to be generated for it // Allow a slave to be generated for it
grantpt(&master_fd)?; grantpt(&master_fd)?;
unlockpt(&master_fd)?; unlockpt(&master_fd)?;
// Get the name of the slave // Get the name of the slave
let slave_name = unsafe { ptsname(&master_fd) }?; let slave_name = unsafe { ptsname(&master_fd) }?;
// Try to open the slave {
//let _slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, Mode::empty())?; let winsize = Winsize {
{ ws_row: <u16>::try_from(height).unwrap(),
ws_col: <u16>::try_from(width).unwrap(),
ws_xpixel: 0,
ws_ypixel: 0,
};
let master_fd = master_fd.as_raw_fd();
unsafe { set_window_size(master_fd, &winsize)? };
}
(master_fd, slave_name)
};
#[cfg(target_os = "macos")]
let (master_fd, slave_fd) = {
let winsize = Winsize { let winsize = Winsize {
ws_row: <u16>::try_from(height).unwrap(), ws_row: <u16>::try_from(height).unwrap(),
ws_col: <u16>::try_from(width).unwrap(), ws_col: <u16>::try_from(width).unwrap(),
@ -80,12 +101,13 @@ pub fn create_pty(
ws_ypixel: 0, ws_ypixel: 0,
}; };
let master_fd = master_fd.as_raw_fd(); let ends = nix::pty::openpty(Some(&winsize), None)?;
unsafe { set_window_size(master_fd, &winsize)? }; (ends.master, ends.slave)
} };
let child_pid = match unsafe { fork()? } { let child_pid = match unsafe { fork()? } {
ForkResult::Child => { ForkResult::Child => {
#[cfg(not(target_os = "macos"))]
/* Open slave end for pseudoterminal */ /* Open slave end for pseudoterminal */
let slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, stat::Mode::empty())?; let slave_fd = open(Path::new(&slave_name), OFlag::O_RDWR, stat::Mode::empty())?;