Add open-file option

Todo: This is absolutely atrocious code. Fix it.
master
itycodes 2 weeks ago
parent 51ece96554
commit 3f8dad6b9a

@ -1,3 +1,5 @@
#![allow(static_mut_refs)]
use chrono::Local; use chrono::Local;
use libc::kill; use libc::kill;
use nix::poll::{PollFd, PollFlags, PollTimeout, poll}; use nix::poll::{PollFd, PollFlags, PollTimeout, poll};
@ -13,6 +15,7 @@ use std::ptr;
static mut USE_KERNEL_ORDERING: bool = false; static mut USE_KERNEL_ORDERING: bool = false;
static mut PLAIN_MODE: bool = false; static mut PLAIN_MODE: bool = false;
static mut OUT_FILE: Mutex<Option<Box<dyn Write>>> = Mutex::new(Option::None);
#[derive(Debug, Default)] #[derive(Debug, Default)]
struct Ptys { struct Ptys {
@ -43,7 +46,15 @@ fn handle_data(mut stream: StdioStream) -> Result<(), bool> {
Ok(n) => { Ok(n) => {
let bufc = &buf[..n]; let bufc = &buf[..n];
if unsafe {PLAIN_MODE} { if unsafe {PLAIN_MODE} {
std::io::stdout().write_all(bufc).unwrap(); if unsafe{OUT_FILE.get_mut().unwrap().is_none()} {
std::io::stdout().write_all(bufc).unwrap();
} else {
unsafe {
OUT_FILE.lock().unwrap().as_mut().map(|f| {
f.write_all(bufc).unwrap();
});
};
}
} else { } else {
for c in bufc { for c in bufc {
stream.buffer.push(*c); stream.buffer.push(*c);
@ -63,8 +74,22 @@ fn handle_data(mut stream: StdioStream) -> Result<(), bool> {
} }
}; };
let now = Local::now().format(&format).to_string(); let now = Local::now().format(&format).to_string();
std::io::stdout().write_all(now.as_bytes()).unwrap(); if unsafe{OUT_FILE.lock().unwrap().is_none()} {
std::io::stdout().write_all(&stream.buffer).unwrap(); let mut data: Vec<u8> = Vec::new();
data.extend(now.as_bytes());
data.extend_from_slice(&stream.buffer);
std::io::stdout().write_all(&data).unwrap();
} else {
unsafe {
OUT_FILE.lock().unwrap().as_mut().map(|f| {
let mut data: Vec<u8> = Vec::new();
data.extend(now.as_bytes());
data.extend_from_slice(&stream.buffer);
//std::io::stdout().write_all(data.as_slice()).unwrap();
f.write_all(&data).unwrap();
});
};
}
stream.buffer.clear(); stream.buffer.clear();
} }
} }
@ -130,6 +155,7 @@ fn handle_poll(
} }
} }
#[allow(unreachable_code)]
fn spawn_child(ptys: &Ptys, user_cmd: String) { fn spawn_child(ptys: &Ptys, user_cmd: String) {
let cmd = CString::new("/bin/bash").unwrap(); let cmd = CString::new("/bin/bash").unwrap();
let bcmd = user_cmd; let bcmd = user_cmd;
@ -285,12 +311,14 @@ fn main_loop(child: Pid, ptys: &Ptys) {
} }
use std::ffi::OsString; use std::ffi::OsString;
use std::sync::Mutex;
#[derive(Debug)] #[derive(Debug)]
struct Args { struct Args {
kernel_order: bool, kernel_order: bool,
plain: bool, plain: bool,
command: String, command: String,
file: Option<File>,
} }
fn parse_args() -> Args { fn parse_args() -> Args {
@ -300,15 +328,22 @@ fn parse_args() -> Args {
let mut kernel_order = false; let mut kernel_order = false;
let mut plain = false; let mut plain = false;
let mut command_parts: Vec<OsString> = Vec::new(); let mut command_parts: Vec<OsString> = Vec::new();
let mut parsing_open_file = false;
let mut file: Option<File> = Option::None;
while let Some(arg) = args.next() { while let Some(arg) = args.next() {
if arg == "--kernel-order" { if parsing_open_file {
file = Option::from(File::options().write(true).open(&arg).expect(format!("Failed to open {}", &arg.to_str().unwrap()).as_str()));
parsing_open_file = false;
} else if arg == "--kernel-order" {
kernel_order = true; kernel_order = true;
} else if arg == "--plain" { } else if arg == "--plain" {
plain = true; plain = true;
} else if arg == "-c" || arg == "--command" { } else if arg == "-c" || arg == "--command" {
command_parts.extend(args); command_parts.extend(args);
break; break;
} else if arg == "--open-file" {
parsing_open_file = true;
} else { } else {
command_parts.push(arg); command_parts.push(arg);
command_parts.extend(args); command_parts.extend(args);
@ -316,6 +351,11 @@ fn parse_args() -> Args {
} }
} }
if !kernel_order && file.is_some() {
eprintln!("--open-file has to be used with --kernel-order");
std::process::exit(-1);
}
let command = command_parts let command = command_parts
.into_iter() .into_iter()
.map(|s| s.to_string_lossy().into_owned()) .map(|s| s.to_string_lossy().into_owned())
@ -326,6 +366,7 @@ fn parse_args() -> Args {
kernel_order, kernel_order,
command, command,
plain, plain,
file,
}; };
parsed parsed
@ -337,9 +378,16 @@ fn main() {
let cmd = args.command; let cmd = args.command;
unsafe { unsafe {
IS_TTY = libc::isatty(libc::STDOUT_FILENO) != 0;
USE_KERNEL_ORDERING = args.kernel_order; USE_KERNEL_ORDERING = args.kernel_order;
PLAIN_MODE = args.plain; PLAIN_MODE = args.plain;
let is_open_file = args.file.is_some();
args.file.map(|f| {
IS_TTY = libc::isatty((&f).as_raw_fd()) != 0;
OUT_FILE = Mutex::new(Option::from(Box::new(f) as Box<dyn Write>));
});
if !is_open_file {
IS_TTY = libc::isatty(libc::STDOUT_FILENO) != 0;
}
}; };
let mut ptys = Ptys::default(); let mut ptys = Ptys::default();
open_ptys(&mut ptys); open_ptys(&mut ptys);

Loading…
Cancel
Save