diff --git a/src/bin/windows_service.rs b/src/bin/windows_service.rs index 7a1a8e9..7a57ef4 100644 --- a/src/bin/windows_service.rs +++ b/src/bin/windows_service.rs @@ -1,63 +1,82 @@ -#![windows_subsystem = "windows"] - -#[macro_use] -extern crate windows_service; - -use irc_rpc::start_loop; - -use std::ffi::OsString; -use std::time::Duration; -use windows_service::{ - define_windows_service, - service::{ - ServiceControl, ServiceControlAccept, ServiceExitCode, ServiceState, ServiceStatus, - ServiceType, - }, - service_control_handler::{self, ServiceControlHandlerResult}, - service_dispatcher, Result, -}; - -const SERVICE_TYPE: ServiceType = ServiceType::OWN_PROCESS; - -define_windows_service!(ffi_service_main, my_service_main); - -fn my_service_main(arguments: Vec) { - // The entry point where execution will start on a background thread after a call to - // `service_dispatcher::start` from `main`. - - let event_handler = move |control_event| -> ServiceControlHandlerResult { - match control_event { - // Notifies a service to report its current status information to the service - // control manager. Always return NoError even if not implemented. - ServiceControl::Interrogate => ServiceControlHandlerResult::NoError, - - // Handle stop - ServiceControl::Stop => { - ServiceControlHandlerResult::NoError - } - - _ => ServiceControlHandlerResult::NotImplemented, - } - }; - - let status_handle = service_control_handler::register("irc-rpc", event_handler).unwrap(); - - status_handle.set_service_status(ServiceStatus { - service_type: SERVICE_TYPE, - current_state: ServiceState::Running, - controls_accepted: ServiceControlAccept::STOP, - exit_code: ServiceExitCode::Win32(0), - checkpoint: 0, - wait_hint: Duration::default(), - process_id: None, - }).unwrap(); - - start_loop(); +#[cfg(windows)] +fn main() -> windows_service::Result<()> { + winserv::run() } -fn main() -> windows_service::Result<()> { - // Register generated `ffi_service_main` with the system and start the service, blocking - // this thread until the service is stopped. - service_dispatcher::start("irc-rpc", ffi_service_main)?; - Ok(()) -} \ No newline at end of file +#[cfg(not(windows))] +fn main() { + //do nothing on *nix +} + +#[cfg(windows)] +mod winserv { + + use std::ffi::OsString; + use std::time::Duration; + use windows_service::{ + define_windows_service, + service::{ + ServiceControl, ServiceControlAccept, ServiceExitCode, ServiceState, ServiceStatus, + ServiceType, + }, + service_control_handler::{self, ServiceControlHandlerResult}, + service_dispatcher, Result, + }; + use irc_rpc::start_loop; + + const SERVICE_TYPE: ServiceType = ServiceType::OWN_PROCESS; + + define_windows_service!(ffi_service_main, my_service_main); + + pub fn run() -> Result<()> { + service_dispatcher::start("irc-rpc", ffi_service_main) + } + + fn my_service_main(arguments: Vec) { + // The entry point where execution will start on a background thread after a call to + // `service_dispatcher::start` from `main`. + + let event_handler = move |control_event| -> ServiceControlHandlerResult { + match control_event { + // Notifies a service to report its current status information to the service + // control manager. Always return NoError even if not implemented. + ServiceControl::Interrogate => ServiceControlHandlerResult::NoError, + + // Handle stop + ServiceControl::Stop => ServiceControlHandlerResult::NoError, + + _ => ServiceControlHandlerResult::NotImplemented, + } + }; + + let status_handle = service_control_handler::register("irc-rpc", event_handler).unwrap(); + + status_handle + .set_service_status(ServiceStatus { + service_type: SERVICE_TYPE, + current_state: ServiceState::Running, + controls_accepted: ServiceControlAccept::STOP, + exit_code: ServiceExitCode::Win32(0), + checkpoint: 0, + wait_hint: Duration::default(), + process_id: None, + }) + .unwrap(); + + if let Err(_) = start_loop() { + //log error + } + + status_handle + .set_service_status(ServiceStatus { + service_type: SERVICE_TYPE, + current_state: ServiceState::Stopped, + controls_accepted: ServiceControlAccept::empty(), + exit_code: ServiceExitCode::Win32(0), + checkpoint: 0, + wait_hint: Duration::default(), + process_id: None, + }) + .unwrap(); + } +} diff --git a/src/lib.rs b/src/lib.rs index 81b07e7..299ec68 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,14 +4,12 @@ use std::{collections::HashMap, process}; static ART: &str = include_str!("ouch.txt"); -pub fn start_loop() { +pub fn start_loop() -> Result<(), failure::Error> { tokio::runtime::Builder::new_multi_thread() .enable_all() .build() .unwrap() - .block_on(async { - event_loop().await.unwrap(); - }); + .block_on(async { event_loop().await }) } async fn event_loop() -> Result<(), failure::Error> { diff --git a/src/main.rs b/src/main.rs index 37d091f..43e9e0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,5 +3,5 @@ use irc_rpc::start_loop; fn main() { - start_loop(); -} \ No newline at end of file + start_loop().unwrap(); +}