Skip to content

Commit

Permalink
Add module to invoke a command with piped stdin and stdout.
Browse files Browse the repository at this point in the history
  • Loading branch information
misalcedo authored Dec 18, 2023
1 parent 4f54897 commit c3f8510
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 10 deletions.
2 changes: 2 additions & 0 deletions examples/debug.cgi
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ p ARGV

puts "STDIN:"
p STDIN.read

STDERR.puts "Done"
30 changes: 30 additions & 0 deletions src/cgi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::process::{Command, Stdio};
use std::io::Write;
use std::path::PathBuf;

pub fn run(script: &PathBuf) {
println!("Running script {}...",script.display());

let mut child = Command::new(script)
.arg("-test")
.arg("echo hello")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.expect("failed to start script {script}");

let mut stdin = child.stdin.take().expect("Failed to open stdin");

std::thread::spawn(move || {
stdin.write_all("Hello, world!".as_bytes()).expect("Failed to write to stdin");
});

let output = child.wait_with_output().expect("Failed to read stdout");

let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);

println!("Exit code: {}", output.status);
println!("STDOUT: {stdout}");
println!("STDERR: {stderr}");
}
33 changes: 23 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use clap::{Parser, Subcommand};
use std::path::PathBuf;

mod cgi;
mod server;

#[derive(Parser)]
Expand All @@ -21,6 +22,12 @@ enum Commands {
#[arg(short, long, value_name = "SCRIPT")]
script: PathBuf,
},
/// Tests a CGI script.
Test {
/// Sets a CGI script file
#[arg(short, long, value_name = "SCRIPT")]
script: PathBuf,
},
}

pub fn main() {
Expand All @@ -30,15 +37,21 @@ pub fn main() {

// You can check for the existence of subcommands, and if found use their
// matches just as you would the top level cmd
if let Some(Commands::Serve { script }) = &options.command {
// Configure a runtime for the server that runs everything on the current thread
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("build runtime");

// Combine it with a `LocalSet, which means it can spawn !Send futures...
let local = tokio::task::LocalSet::new();
local.block_on(&rt, server::serve(script)).unwrap();
match &options.command {
Some(Commands::Serve { script }) => {
// Configure a runtime for the server that runs everything on the current thread
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("build runtime");

// Combine it with a `LocalSet, which means it can spawn !Send futures...
let local = tokio::task::LocalSet::new();
local.block_on(&rt, server::serve(script)).unwrap();
}
Some(Commands::Test { script }) => {
cgi::run(script);
}
_ => {}
}
}
1 change: 1 addition & 0 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use tokio::net::TcpListener;
use tokio::pin;

async fn hello(_: Request<hyper::body::Incoming>) -> Result<Response<Full<Bytes>>, Infallible> {

Ok(Response::new(Full::new(Bytes::from("Hello, World!"))))
}

Expand Down

0 comments on commit c3f8510

Please sign in to comment.