aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
authorJonas Maier <>2026-03-05 17:37:52 +0100
committerJonas Maier <>2026-03-05 17:37:52 +0100
commit07c802b93a241d566161d3077b3254df4067fa1e (patch)
treeebe370181c9660d3b6657d2de12e5adc3b884946 /src/main.rs
parentf919c3e5d10db7afe41a14b94b99cd38e44d2720 (diff)
downloadpish-07c802b93a241d566161d3077b3254df4067fa1e.tar.gz
lots of shenanigans to have proper execve reload
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs38
1 files changed, 37 insertions, 1 deletions
diff --git a/src/main.rs b/src/main.rs
index 81cc5d3..6687937 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -248,6 +248,35 @@ fn event_loop() {
se.raw.disable();
}
+#[cfg(debug_assertions)]
+fn reload_shell() {
+ use std::{env, ffi::CString, ptr};
+
+ // path to this executable
+ let exe = env::current_exe().unwrap();
+ let exe_c = CString::new(exe.as_os_str().as_bytes()).unwrap();
+
+ // argv
+ let args: Vec<CString> = env::args().map(|a| CString::new(a).unwrap()).collect();
+
+ let mut argv: Vec<*const libc::c_char> = args.iter().map(|a| a.as_ptr()).collect();
+ argv.push(ptr::null());
+
+ // environment
+ let env: Vec<CString> = env::vars()
+ .map(|(k, v)| CString::new(format!("{}={}", k, v)).unwrap())
+ .collect();
+
+ let mut envp: Vec<*const libc::c_char> = env.iter().map(|e| e.as_ptr()).collect();
+ envp.push(ptr::null());
+
+ unsafe {
+ libc::execve(exe_c.as_ptr(), argv.as_ptr(), envp.as_ptr());
+ }
+
+ eprintln!("exec failed");
+}
+
fn main() {
if !io::stdin().is_terminal() {
println!("need to run in a tty");
@@ -261,7 +290,14 @@ fn main() {
let res = std::panic::catch_unwind(event_loop);
match res {
Ok(_) => break,
- Err(_) => continue,
+ Err(_) =>
+ {
+ #[cfg(debug_assertions)]
+ if run::RELOAD.load(std::sync::atomic::Ordering::SeqCst) {
+ reload_shell();
+ println!("failed to reload shell");
+ }
+ }
}
}