diff options
Diffstat (limited to 'src/reload.rs')
| -rw-r--r-- | src/reload.rs | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/reload.rs b/src/reload.rs new file mode 100644 index 0000000..effc8fd --- /dev/null +++ b/src/reload.rs @@ -0,0 +1,46 @@ +use std::{ + env, + ffi::CString, + io::Write, + panic, ptr, + sync::atomic::{AtomicBool, Ordering}, +}; + +static RELOAD: AtomicBool = AtomicBool::new(false); + +pub fn begin_reload() { + RELOAD.store(true, Ordering::SeqCst); + panic::resume_unwind(Box::new(42)); +} + +/// ONLY TO BE CALLED FROM MAIN WHEN NOT A SINGLE RESOURCE IS HELD +pub unsafe fn continue_reload() { + if !RELOAD.load(Ordering::SeqCst) { + return; + } + + eprintln!("reloading..."); + let _ = std::io::stdout().lock().flush(); + + unsafe { exec() } + + eprintln!("exec failed."); +} + +unsafe fn exec() { + // path to this executable + let exe = env::current_exe() + .unwrap() + .to_string_lossy() + .replace(" (deleted)", ""); + let exe_c = CString::new(exe).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()); + + unsafe { + libc::execv(exe_c.as_ptr(), argv.as_ptr()); + } +} |
