|
1 | 1 | use base::{ |
2 | | - error, |
| 2 | + ResultExt, error, |
3 | 3 | libc::{ |
4 | | - POLLIN, SFD_CLOEXEC, SIG_BLOCK, SIGWINCH, STDOUT_FILENO, TCSADRAIN, TCSAFLUSH, TIOCGWINSZ, |
5 | | - TIOCSWINSZ, cfmakeraw, close, poll, pollfd, raise, read, sigaddset, sigemptyset, signalfd, |
6 | | - sigprocmask, sigset_t, tcsetattr, winsize, write, |
| 4 | + POLLIN, SFD_CLOEXEC, SIG_BLOCK, SIGWINCH, TCSADRAIN, TCSAFLUSH, TIOCGWINSZ, TIOCSWINSZ, |
| 5 | + cfmakeraw, close, poll, pollfd, raise, sigaddset, sigemptyset, signalfd, sigprocmask, |
| 6 | + sigset_t, tcsetattr, winsize, |
7 | 7 | }, |
8 | | - libc::{STDIN_FILENO, ioctl, tcgetattr, termios}, |
| 8 | + libc::{STDIN_FILENO, STDOUT_FILENO, tcgetattr, termios}, |
9 | 9 | warn, |
10 | 10 | }; |
| 11 | +use std::fs::File; |
| 12 | +use std::io::{Read, Write}; |
| 13 | +use std::mem::ManuallyDrop; |
| 14 | +use std::os::fd::{FromRawFd, RawFd}; |
11 | 15 | use std::ptr::null_mut; |
12 | 16 |
|
13 | 17 | static mut OLD_STDIN: Option<termios> = None; |
| 18 | +const TIOCGPTN: u32 = 0x80045430; |
| 19 | + |
| 20 | +unsafe extern "C" { |
| 21 | + // Don't use the declaration from the libc crate as request should be u32 not i32 |
| 22 | + fn ioctl(fd: RawFd, request: u32, ...) -> i32; |
| 23 | +} |
14 | 24 |
|
15 | 25 | pub fn get_pty_num(fd: i32) -> i32 { |
16 | 26 | let mut pty_num = -1i32; |
17 | | - if unsafe { ioctl(fd, 0x80045430u32 as _, &mut pty_num) } != 0 { |
| 27 | + if unsafe { ioctl(fd, TIOCGPTN, &mut pty_num) } != 0 { |
18 | 28 | warn!("Failed to get pty number"); |
19 | 29 | } |
20 | 30 | pty_num |
@@ -64,8 +74,8 @@ pub fn restore_stdin() -> bool { |
64 | 74 |
|
65 | 75 | fn resize_pty(outfd: i32) { |
66 | 76 | let mut ws: winsize = unsafe { std::mem::zeroed() }; |
67 | | - if unsafe { ioctl(STDIN_FILENO, TIOCGWINSZ, &mut ws) } >= 0 { |
68 | | - unsafe { ioctl(outfd, TIOCSWINSZ, &ws) }; |
| 77 | + if unsafe { ioctl(STDIN_FILENO, TIOCGWINSZ as u32, &mut ws) } >= 0 { |
| 78 | + unsafe { ioctl(outfd, TIOCSWINSZ as u32, &ws) }; |
69 | 79 | } |
70 | 80 | } |
71 | 81 |
|
@@ -113,15 +123,19 @@ pub fn pump_tty(infd: i32, outfd: i32) { |
113 | 123 |
|
114 | 124 | for pfd in &pfds { |
115 | 125 | if pfd.revents & POLLIN != 0 { |
116 | | - let n = unsafe { read(pfd.fd, buf.as_mut_ptr() as _, buf.len()) }; |
117 | | - if n <= 0 { |
| 126 | + let mut in_file = ManuallyDrop::new(unsafe { File::from_raw_fd(pfd.fd) }); |
| 127 | + |
| 128 | + let Ok(n) = in_file.read(&mut buf) else { |
118 | 129 | error!("read error"); |
119 | 130 | break 'poll; |
120 | | - } |
| 131 | + }; |
| 132 | + |
121 | 133 | if pfd.fd == STDIN_FILENO { |
122 | | - unsafe { write(outfd, buf.as_ptr() as _, n as _) }; |
| 134 | + let mut out = ManuallyDrop::new(unsafe { File::from_raw_fd(outfd) }); |
| 135 | + out.write_all(&buf[..n]).log_ok(); |
123 | 136 | } else if pfd.fd == infd { |
124 | | - unsafe { write(STDOUT_FILENO, buf.as_ptr() as _, n as _) }; |
| 137 | + let mut out = ManuallyDrop::new(unsafe { File::from_raw_fd(STDOUT_FILENO) }); |
| 138 | + out.write_all(&buf[..n]).log_ok(); |
125 | 139 | } else if pfd.fd == sfd { |
126 | 140 | resize_pty(outfd); |
127 | 141 | } |
|
0 commit comments