~zethra/stargazer

16a7fc9f2c341df0356c0d2463c499b98e23e0a7 — Ben Aaron Goldberg 19 days ago ac838db
Switched to signal-hook-async-std

My patch to signal-hook-async-std was merged, so it's not equivalant to
mt vendored version, which I have now deleted.
4 files changed, 15 insertions(+), 105 deletions(-)

M Cargo.lock
M Cargo.toml
M src/main.rs
D src/signal.rs
M Cargo.lock => Cargo.lock +13 -0
@@ 993,6 993,18 @@ dependencies = [
]

[[package]]
name = "signal-hook-async-std"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90526e74631c69a79b38212e3d4fda4b00de9d6be56b3cead133bf67ad371af1"
dependencies = [
 "async-io",
 "futures-lite",
 "libc",
 "signal-hook 0.3.4",
]

[[package]]
name = "signal-hook-registry"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 1039,6 1051,7 @@ dependencies = [
 "rust-ini",
 "sha2",
 "signal-hook 0.3.4",
 "signal-hook-async-std",
 "structopt",
 "uriparse",
 "users",

M Cargo.toml => Cargo.toml +1 -0
@@ 49,6 49,7 @@ rcgen = "0.8"
dirs = "3.0"
rust-ini = "0.16"
signal-hook = "0.3"
signal-hook-async-std = "~0.2.1"
regex = "1.4"
x509-parser = "0.9"
sha2 = "0.9"

M src/main.rs => src/main.rs +1 -3
@@ 22,8 22,6 @@ mod error;
mod get_file;
mod logger;
mod router;
#[cfg(unix)]
mod signal;
mod tls;

use crate::error::{bad_req, ErrorConv, GemError, Result};


@@ 204,7 202,7 @@ fn main() {

#[cfg(unix)]
async fn exit_on_sig() -> Result<()> {
    use crate::signal::Signals;
    use signal_hook_async_std::Signals;
    use signal_hook::consts::{SIGINT, SIGTERM};

    let mut signals = Signals::new(&[SIGTERM, SIGINT])?;

D src/signal.rs => src/signal.rs +0 -102
@@ 1,102 0,0 @@
#![allow(dead_code)]

//! A smol port of signal_hook_async_std

use std::borrow::Borrow;
use std::io::Error;
use std::os::unix::net::UnixStream;
use std::pin::Pin;
use std::task::{Context, Poll};

use libc::c_int;

pub use signal_hook::iterator::backend::Handle;
use signal_hook::iterator::backend::{
    OwningSignalIterator, PollResult, SignalDelivery,
};
use signal_hook::iterator::exfiltrator::{Exfiltrator, SignalOnly};

use async_io::Async;
use futures_lite::io::AsyncRead;
use futures_lite::Stream;

/// An asynchronous [`Stream`] of arriving signals.
///
/// The stream doesn't return the signals in the order they were recieved by
/// the process and may merge signals received multiple times.
pub struct SignalsInfo<E: Exfiltrator = SignalOnly>(
    OwningSignalIterator<Async<UnixStream>, E>,
);

impl<E: Exfiltrator> SignalsInfo<E> {
    /// Create a `Signals` instance.
    ///
    /// This registers all the signals listed. The same restrictions (panics, errors) apply
    /// as with [`Handle::add_signal`].
    pub fn new<I, S>(signals: I) -> Result<Self, Error>
    where
        I: IntoIterator<Item = S>,
        S: Borrow<c_int>,
        E: Default,
    {
        Self::with_exfiltrator(signals, E::default())
    }

    /// A constructor with explicit exfiltrator.
    pub fn with_exfiltrator<I, S>(
        signals: I,
        exfiltrator: E,
    ) -> Result<Self, Error>
    where
        I: IntoIterator<Item = S>,
        S: Borrow<c_int>,
    {
        let (read, write) = Async::<UnixStream>::pair()?;
        let inner =
            SignalDelivery::with_pipe(read, write, exfiltrator, signals)?;
        Ok(Self(OwningSignalIterator::new(inner)))
    }

    /// Get a shareable [`Handle`] for this `Signals` instance.
    ///
    /// This can be used to add further signals or close the [`Signals`] instance
    /// which terminates the whole signal stream.
    pub fn handle(&self) -> Handle {
        self.0.handle()
    }
}

impl SignalsInfo {
    fn has_signals(
        read: &mut Async<UnixStream>,
        ctx: &mut Context<'_>,
    ) -> Result<bool, Error> {
        match Pin::new(read).poll_read(ctx, &mut [0u8]) {
            Poll::Pending => Ok(false),
            Poll::Ready(Ok(num_read)) => Ok(num_read > 0),
            Poll::Ready(Err(error)) => Err(error),
        }
    }
}

impl Stream for SignalsInfo {
    type Item = c_int;

    fn poll_next(
        mut self: Pin<&mut Self>,
        ctx: &mut Context<'_>,
    ) -> Poll<Option<Self::Item>> {
        match self.0.poll_signal(&mut |read| Self::has_signals(read, ctx)) {
            PollResult::Signal(sig) => Poll::Ready(Some(sig)),
            PollResult::Closed => Poll::Ready(None),
            PollResult::Pending => Poll::Pending,
            PollResult::Err(error) => panic!("Unexpected error: {}", error),
        }
    }
}

/// Simplified version of the signals stream.
///
/// This one simply returns the signal numbers, while [`SignalsInfo`] can provide additional
/// information.
pub type Signals = SignalsInfo<SignalOnly>;