rust command launching

master
Lukáš Hozda 4 years ago
parent 139a5f1023
commit c6584dad87

@ -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)");
}

Loading…
Cancel
Save