From c6584dad8714cac53558433a56f140f624f6baca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hozda?= Date: Tue, 18 Aug 2020 18:17:43 +0200 Subject: [PATCH] rust command launching --- src/main.rs | 145 +++++++++++----------------------------------------- 1 file changed, 30 insertions(+), 115 deletions(-) diff --git a/src/main.rs b/src/main.rs index fab2590..8451c62 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ extern crate simple_input; use std::env; use std::path::Path; -use std::process::exit; +use std::process::{exit, Command}; use std::thread::sleep; use std::time::Duration; use std::ffi::{CStr, CString}; @@ -28,12 +28,6 @@ use simple_input::input; use tempfile::NamedTempFile; extern "C" { - #[no_mangle] - fn waitpid( - __pid: __pid_t, - __stat_loc: *mut libc::c_int, - __options: libc::c_int, - ) -> __pid_t; #[no_mangle] fn socket( __domain: libc::c_int, @@ -62,23 +56,8 @@ extern "C" { #[no_mangle] fn write(__fd: libc::c_int, __buf: *const libc::c_void, __n: size_t) -> ssize_t; #[no_mangle] - fn execvp( - __file: *const libc::c_char, - __argv: *const *mut libc::c_char, - ) -> libc::c_int; - #[no_mangle] - fn execlp( - __file: *const libc::c_char, - __arg: *const libc::c_char, - _: ... - ) -> libc::c_int; - #[no_mangle] - fn fork() -> __pid_t; - #[no_mangle] fn __errno_location() -> *mut libc::c_int; #[no_mangle] - fn printf(_: *const libc::c_char, _: ...) -> libc::c_int; - #[no_mangle] fn snprintf( _: *mut libc::c_char, _: libc::c_ulong, @@ -86,10 +65,6 @@ extern "C" { _: ... ) -> libc::c_int; #[no_mangle] - fn puts(__s: *const libc::c_char) -> libc::c_int; - #[no_mangle] - fn calloc(_: libc::c_ulong, _: libc::c_ulong) -> *mut libc::c_void; - #[no_mangle] fn memset( _: *mut libc::c_void, _: libc::c_int, @@ -106,12 +81,6 @@ extern "C" { _: libc::c_ulong, ) -> libc::c_int; #[no_mangle] - fn strdup(_: *const libc::c_char) -> *mut libc::c_char; - #[no_mangle] - fn strrchr(_: *const libc::c_char, _: libc::c_int) -> *mut libc::c_char; - #[no_mangle] - fn strcasecmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int; - #[no_mangle] fn strlen(_: *const libc::c_char) -> libc::c_ulong; #[no_mangle] fn strerror(_: libc::c_int) -> *mut libc::c_char; @@ -514,79 +483,31 @@ impl BrowserState { mut port: usize, mut selector: &str, ) { - let mut pid: pid_t = 0; - let mut status: libc::c_int = 0; - let mut i: libc::c_int = 0; - let mut j: libc::c_int = 0; - let mut buffer: [libc::c_char; 1024] = [0; 1024]; - let mut argv: [*mut libc::c_char; 32] = [0 as *mut libc::c_char; 32]; - let mut p: *mut libc::c_char = 0 as *mut libc::c_char; - if self.config.verbose - { - println!("h({}) p({}) s({})", host, port, selector); - } if !self.download_temp(host, port, selector) { return; } - /* parsed command line string */ - argv[0 as libc::c_int as usize] = - &mut *buffer.as_mut_ptr().offset(0 as libc::c_int as isize) - as *mut libc::c_char; - p = cmd as *mut libc::c_char; - i = 0 as libc::c_int; - j = 1 as libc::c_int; - while *p as libc::c_int != 0 - && (i as libc::c_ulong) - < (mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong) - .wrapping_sub(1 as libc::c_int as libc::c_ulong) - && j < 30 as libc::c_int + + if self.config.verbose { - if *p as libc::c_int == ' ' as i32 || *p as libc::c_int == '\t' as i32 { - let fresh5 = i; - i = i + 1; - buffer[fresh5 as usize] = 0 as libc::c_int as libc::c_char; - let fresh6 = j; - j = j + 1; - argv[fresh6 as usize] = - &mut *buffer.as_mut_ptr().offset(i as isize) as *mut libc::c_char; - while *p as libc::c_int == ' ' as i32 || *p as libc::c_int == '\t' as i32 - { - p = p.offset(1) - } - } else { - let fresh7 = p; - p = p.offset(1); - let fresh8 = i; - i = i + 1; - buffer[fresh8 as usize] = *fresh7 - } + println!("h({}) p({}) s({})", host, port, selector); } - buffer[i as usize] = 0 as libc::c_int as libc::c_char; - let fresh9 = j; - j = j + 1; - argv[fresh9 as usize] = - CString::new(self.tmpfilename.clone()).unwrap().into_raw(); - argv[j as usize] = 0 as *mut libc::c_char; - /* fork and execute */ if self.config.verbose { println!("executing: {} {}", cmd, self.tmpfilename); - /* to wait for browsers etc. that return immediately */ } - pid = fork(); - if pid == 0 as libc::c_int { - if execvp( - argv[0 as libc::c_int as usize], - argv.as_mut_ptr() as *const *mut libc::c_char, - ) == -(1 as libc::c_int) - { - eprintln!("error: execvp() failed!"); - } - } else if pid == -(1 as libc::c_int) { - eprintln!("error: fork() failed!"); + /* execute */ + match Command::new(cmd) + .arg(&self.tmpfilename) + .spawn() + { + Ok(mut c) => if let Err(e) = c.wait() { + eprintln!("failed to wait for command to exit: {}", e); + }, + Err(e) => eprintln!("error: failed to run command: {}", e), } + + /* to wait for browsers etc. that return immediately */ sleep(Duration::from_secs(1)); - waitpid(pid, &mut status, 0 as libc::c_int); fs::remove_file(&self.tmpfilename).expect("failed to delete temp file"); } @@ -773,7 +694,7 @@ impl BrowserState { match w { '0' => { self.view_file( - &self.config.cmd_text, + &self.config.cmd_text.clone(), &(*l).host, (*l).port, &(*l).selector, @@ -798,7 +719,7 @@ impl BrowserState { } 'f' | 'I' | 'p' => { self.view_file( - &self.config.cmd_image, + &self.config.cmd_image.clone(), &(*l).host, (*l).port, &(*l).selector, @@ -806,7 +727,7 @@ impl BrowserState { } 'h' => { self.view_file( - &self.config.cmd_browser, + &self.config.cmd_browser.clone(), &(*l).host, (*l).port, &(*l).selector, @@ -814,7 +735,7 @@ impl BrowserState { } 's' => { self.view_file( - &self.config.cmd_player, + &self.config.cmd_player.clone(), &(*l).host, (*l).port, &(*l).selector, @@ -1207,25 +1128,19 @@ pub unsafe fn is_valid_directory_entry(mut line: *const libc::c_char) -> libc::c } pub unsafe fn view_telnet(mut host: &str, mut port: usize) { - let mut pid: pid_t = 0; - let mut status: libc::c_int = 0; println!("executing: telnet {} {}", host, port); - pid = fork(); - if pid == 0 as libc::c_int { - if execlp( - b"telnet\x00" as *const u8 as *const libc::c_char, - b"telnet\x00" as *const u8 as *const libc::c_char, - host, - port, - 0 as *mut libc::c_void, - ) == -(1 as libc::c_int) - { - println!("error: execlp() failed!"); - } - } else if pid == -(1 as libc::c_int) { - eprintln!("error: fork() failed"); + + // TODO check stdio + match Command::new("telnet") + .arg(host) + .arg(port.to_string()) + .spawn() + { + Ok(mut c) => if let Err(e) = c.wait() { + eprintln!("failed to wait for telnet: {}", e); + }, + Err(e) => eprintln!("failed to start telnet: {}", e), } - waitpid(pid, &mut status, 0 as libc::c_int); println!("(done)"); }