inhouse pty
This commit is contained in:
@@ -9,7 +9,7 @@ default-run = "ming"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [ "wm", "wm/linux" ]
|
members = [ "wm", "linux" ]
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
bmp-rust = "0.5.0"
|
bmp-rust = "0.5.0"
|
||||||
@@ -18,16 +18,16 @@ bitcoin_hashes = { version = "0.16.0", default-features = false }
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
ming-wm-lib = { path = "ming-wm-lib" }
|
ming-wm-lib = { path = "ming-wm-lib" }
|
||||||
wm = { path = "wm", optional = true }
|
wm = { path = "wm", optional = true }
|
||||||
|
linux = { path = "linux", optional = true }
|
||||||
rodio = { version = "0.19.0", default-features = false, features = [ "flac", "mp3", "symphonia-vorbis", "wav" ], optional = true }
|
rodio = { version = "0.19.0", default-features = false, features = [ "flac", "mp3", "symphonia-vorbis", "wav" ], optional = true }
|
||||||
rand = { version = "0.9.0", default-features = false, features = [ "small_rng" ], optional = true }
|
rand = { version = "0.9.0", default-features = false, features = [ "small_rng" ], optional = true }
|
||||||
id3 = { version = "1.10.0", optional = true }
|
id3 = { version = "1.10.0", optional = true }
|
||||||
mp4ameta = { version = "0.11.0", optional = true }
|
mp4ameta = { version = "0.11.0", optional = true }
|
||||||
metaflac = { version = "0.2.5", optional = true }
|
metaflac = { version = "0.2.5", optional = true }
|
||||||
pty-process = { version = "0.5.1", optional = true }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "wm", "terminal" ]
|
default = [ "wm", "terminal" ]
|
||||||
terminal = [ "pty-process" ]
|
terminal = [ "linux" ]
|
||||||
audio_player = [ "id3", "mp4ameta", "metaflac", "rand", "rodio" ]
|
audio_player = [ "id3", "mp4ameta", "metaflac", "rand", "rodio" ]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 70 B After Width: | Height: | Size: 70 B |
|
Before Width: | Height: | Size: 250 B After Width: | Height: | Size: 250 B |
|
Before Width: | Height: | Size: 250 B After Width: | Height: | Size: 250 B |
@@ -69,5 +69,10 @@ More often than not, not relying on dependencies removes unnecessary bloat and c
|
|||||||
Expect to see more dependencies in Cargo.toml eliminated soon.
|
Expect to see more dependencies in Cargo.toml eliminated soon.
|
||||||
|
|
||||||
PS:
|
PS:
|
||||||
1. `rodio` is unlikely to ever be eliminated (simply because audio is *complex*), and it's optional (if the audio player is not wanted)
|
1. `rodio` is unlikely to ever be eliminated (simply because audio is *complex*), and it's optional (if the audio player is not wanted). The dependency which provides hashing will also not be removed as I am not a cryptographer and not (quite) stupid enough to pretend being one
|
||||||
2.`bmp-rust` is written by me and so isn't technically an external dependency
|
2. `bmp-rust` is written by me and so isn't technically an external dependency
|
||||||
|
|
||||||
|
> ### Update
|
||||||
|
> Ignoring the audio player dependencies and `bmp-rust`, the only dependencies not written by me are now `libc` for libc Rust bindings and `bitcoin-hashes` for SHA-512 password hashing (yes, I know SHA-512 is not the greatest password hash function, but it is lightweight, relatively).
|
||||||
|
>
|
||||||
|
> Prior dependencies like `termion`, `linux_framebuffer`, `pty-process`, have been removed and replaced by a me-written version in the `linux` crate. As of v1.1, the dependency removing goal has been achieved. Huzzah!
|
||||||
|
|||||||
3
docs/system/integration.md
Normal file
3
docs/system/integration.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
## Launch on Login
|
||||||
|
|
||||||
|
To launch on user login, simply add `ming` as the last line of `~/.profile`. This should work for most shells.
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
pub mod fb;
|
pub mod fb;
|
||||||
pub mod raw;
|
pub mod raw;
|
||||||
pub mod keys;
|
pub mod keys;
|
||||||
|
pub mod pty;
|
||||||
55
linux/src/pty.rs
Normal file
55
linux/src/pty.rs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
use std::ptr;
|
||||||
|
use std::process::{ Command, Child };
|
||||||
|
use std::fs::File;
|
||||||
|
use std::os::fd::{ OwnedFd, FromRawFd };
|
||||||
|
|
||||||
|
use libc::openpty;
|
||||||
|
|
||||||
|
//basically the master and slave are linked? slave behaves just like normal terminal
|
||||||
|
//I don't totally get it, I guess just attach the command's stdout and stderr to ptyslave for reading?
|
||||||
|
|
||||||
|
pub struct PtyMaster {
|
||||||
|
pub file: File,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PtyMaster {
|
||||||
|
pub fn new(fd: OwnedFd) -> Self {
|
||||||
|
Self {
|
||||||
|
file: File::from(fd),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PtySlave {
|
||||||
|
pub file: File,
|
||||||
|
fd: OwnedFd,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PtySlave {
|
||||||
|
pub fn new(fd: OwnedFd) -> Self {
|
||||||
|
Self {
|
||||||
|
file: File::from(fd.try_clone().unwrap()),
|
||||||
|
fd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//assume stdin is piped
|
||||||
|
pub fn attach_and_spawn(&self, command: &mut Command) -> std::io::Result<Child> {
|
||||||
|
command.stdout(self.fd.try_clone().unwrap());
|
||||||
|
command.stderr(self.fd.try_clone().unwrap());
|
||||||
|
command.spawn()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn open_pty() -> Result<(PtyMaster, PtySlave), ()> {
|
||||||
|
let mut master_fd = 0;
|
||||||
|
let mut slave_fd = 0;
|
||||||
|
let result = unsafe { openpty(&mut master_fd, &mut slave_fd, ptr::null_mut(), ptr::null_mut(), ptr::null_mut()) };
|
||||||
|
if result == -1 {
|
||||||
|
Err(())
|
||||||
|
} else {
|
||||||
|
let master_fd = unsafe { OwnedFd::from_raw_fd(master_fd) };
|
||||||
|
let slave_fd = unsafe { OwnedFd::from_raw_fd(slave_fd) };
|
||||||
|
Ok((PtyMaster::new(master_fd), PtySlave::new(slave_fd)))
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,12 +3,13 @@ use std::vec;
|
|||||||
use std::sync::mpsc::{ channel, Receiver, Sender };
|
use std::sync::mpsc::{ channel, Receiver, Sender };
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::process::{ Child, Stdio };
|
use std::process::{ Child, Stdio };
|
||||||
|
use std::process::Command;
|
||||||
use std::io::{ Read, Write };
|
use std::io::{ Read, Write };
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use pty_process::blocking;
|
use linux::pty::open_pty;
|
||||||
|
|
||||||
use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLikeType };
|
use ming_wm_lib::window_manager_types::{ DrawInstructions, WindowLike, WindowLikeType };
|
||||||
use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse, WindowManagerRequest, ShortcutType };
|
use ming_wm_lib::messages::{ WindowMessage, WindowMessageResponse, WindowManagerRequest, ShortcutType };
|
||||||
@@ -160,8 +161,8 @@ impl WindowLike for Terminal {
|
|||||||
//for now, ignore
|
//for now, ignore
|
||||||
//
|
//
|
||||||
} else if char::from(ci) == '\t' {
|
} else if char::from(ci) == '\t' {
|
||||||
//for now, ignore
|
//for now, interpret as space
|
||||||
//
|
self.process_current_line.push(b' ');
|
||||||
} else {
|
} else {
|
||||||
self.process_current_line.push(ci);
|
self.process_current_line.push(ci);
|
||||||
}
|
}
|
||||||
@@ -358,11 +359,13 @@ impl Terminal {
|
|||||||
}
|
}
|
||||||
Mode::Input
|
Mode::Input
|
||||||
} else {
|
} else {
|
||||||
let (pty, pts) = blocking::open().unwrap();
|
let (pty, pts) = open_pty().unwrap();
|
||||||
self.running_process = Some(blocking::Command::new("sh").arg("-c").arg(&self.current_input).current_dir(&self.current_path).stdin(Stdio::piped()).spawn(pts).unwrap());
|
let mut cmd = Command::new("sh");
|
||||||
|
let cmd = cmd.arg("-c").arg(&self.current_input).current_dir(&self.current_path).stdin(Stdio::piped());
|
||||||
|
self.running_process = Some(pts.attach_and_spawn(cmd).unwrap());
|
||||||
let (tx1, rx1) = channel();
|
let (tx1, rx1) = channel();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
for ci in pty.bytes() {
|
for ci in pty.file.bytes() {
|
||||||
if let Ok(ci) = ci {
|
if let Ok(ci) = ci {
|
||||||
tx1.send(ci).unwrap();
|
tx1.send(ci).unwrap();
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ use std::io::{ stdin, stdout, BufReader, BufRead, Write };
|
|||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
use wm::linux::fb::Framebuffer;
|
use linux::fb::Framebuffer;
|
||||||
use wm::linux::raw::RawStdout;
|
use linux::raw::RawStdout;
|
||||||
use wm::linux::keys::{ RawStdin, Key };
|
use linux::keys::{ RawStdin, Key };
|
||||||
use wm::framebuffer::{ FramebufferWriter, FramebufferInfo };
|
use wm::framebuffer::{ FramebufferWriter, FramebufferInfo };
|
||||||
use wm::window_manager::WindowManager;
|
use wm::window_manager::WindowManager;
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,6 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ming-wm-lib = { path = "../ming-wm-lib" }
|
ming-wm-lib = { path = "../ming-wm-lib" }
|
||||||
linux = { path = "linux" }
|
linux = { path = "../linux" }
|
||||||
bitcoin_hashes = { version = "0.16.0", default-features = false }
|
bitcoin_hashes = { version = "0.16.0", default-features = false }
|
||||||
bmp-rust = "0.5.0"
|
bmp-rust = "0.5.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user