mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
reap the exit statuses from 'onevent' child processes
This commit is contained in:
parent
a4e0f582a8
commit
eaac599ce3
3 changed files with 39 additions and 6 deletions
21
src/child_wait_future.rs
Normal file
21
src/child_wait_future.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use futures::{Async, Future};
|
||||||
|
use std::io;
|
||||||
|
use std::process::{Child, ExitStatus};
|
||||||
|
|
||||||
|
/// A future that resolves to a child process's exit status once it exits.
|
||||||
|
pub struct ChildWaitFuture {
|
||||||
|
pub child: Child,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Future for ChildWaitFuture {
|
||||||
|
type Item = ExitStatus;
|
||||||
|
type Error = io::Error;
|
||||||
|
|
||||||
|
fn poll(&mut self) -> Result<Async<Self::Item>, Self::Error> {
|
||||||
|
match self.child.try_wait() {
|
||||||
|
Ok(Some(status)) => Ok(Async::Ready(status)),
|
||||||
|
Ok(None) => Ok(Async::NotReady),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
src/main.rs
14
src/main.rs
|
@ -39,6 +39,9 @@ use librespot::playback::config::{Bitrate, PlayerConfig};
|
||||||
use librespot::playback::mixer::{self, Mixer};
|
use librespot::playback::mixer::{self, Mixer};
|
||||||
use librespot::playback::player::{Player, PlayerEvent};
|
use librespot::playback::player::{Player, PlayerEvent};
|
||||||
|
|
||||||
|
mod child_wait_future;
|
||||||
|
use child_wait_future::ChildWaitFuture;
|
||||||
|
|
||||||
mod player_event_handler;
|
mod player_event_handler;
|
||||||
use player_event_handler::run_program_on_events;
|
use player_event_handler::run_program_on_events;
|
||||||
|
|
||||||
|
@ -466,7 +469,16 @@ impl Future for Main {
|
||||||
if let Some(ref mut player_event_channel) = self.player_event_channel {
|
if let Some(ref mut player_event_channel) = self.player_event_channel {
|
||||||
if let Async::Ready(Some(event)) = player_event_channel.poll().unwrap() {
|
if let Async::Ready(Some(event)) = player_event_channel.poll().unwrap() {
|
||||||
if let Some(ref program) = self.player_event_program {
|
if let Some(ref program) = self.player_event_program {
|
||||||
run_program_on_events(event, program);
|
let child = run_program_on_events(event, program)
|
||||||
|
.expect("program failed to start");
|
||||||
|
|
||||||
|
let wait_future = ChildWaitFuture { child }
|
||||||
|
.map(|status| if !status.success() {
|
||||||
|
error!("child exited with status {:?}", status.code());
|
||||||
|
})
|
||||||
|
.map_err(|e| error!("failed to wait on child process: {}", e));
|
||||||
|
|
||||||
|
self.handle.spawn(wait_future);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
use librespot::playback::player::PlayerEvent;
|
use librespot::playback::player::PlayerEvent;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::process::Command;
|
use std::io;
|
||||||
|
use std::process::{Child, Command};
|
||||||
|
|
||||||
fn run_program(program: &str, env_vars: HashMap<&str, String>) {
|
fn run_program(program: &str, env_vars: HashMap<&str, String>) -> io::Result<Child> {
|
||||||
let mut v: Vec<&str> = program.split_whitespace().collect();
|
let mut v: Vec<&str> = program.split_whitespace().collect();
|
||||||
info!("Running {:?} with environment variables {:?}", v, env_vars);
|
info!("Running {:?} with environment variables {:?}", v, env_vars);
|
||||||
Command::new(&v.remove(0))
|
Command::new(&v.remove(0))
|
||||||
.args(&v)
|
.args(&v)
|
||||||
.envs(env_vars.iter())
|
.envs(env_vars.iter())
|
||||||
.spawn()
|
.spawn()
|
||||||
.expect("program failed to start");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_program_on_events(event: PlayerEvent, onevent: &str) {
|
pub fn run_program_on_events(event: PlayerEvent, onevent: &str) -> io::Result<Child> {
|
||||||
let mut env_vars = HashMap::new();
|
let mut env_vars = HashMap::new();
|
||||||
match event {
|
match event {
|
||||||
PlayerEvent::Changed {
|
PlayerEvent::Changed {
|
||||||
|
@ -32,5 +32,5 @@ pub fn run_program_on_events(event: PlayerEvent, onevent: &str) {
|
||||||
env_vars.insert("TRACK_ID", track_id.to_base16());
|
env_vars.insert("TRACK_ID", track_id.to_base16());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
run_program(onevent, env_vars);
|
run_program(onevent, env_vars)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue