Skip to content

Commit

Permalink
Merge pull request #329 from serpent-os/feat/ignore-signals-during-blit
Browse files Browse the repository at this point in the history
moss: Ignore SIGINT during blit
  • Loading branch information
ikeycode authored Aug 16, 2024
2 parents c5cef12 + 51057c1 commit 4966f0f
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 3 deletions.
8 changes: 6 additions & 2 deletions moss/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ use self::verify::verify;
use crate::{
db, environment, installation, package,
registry::plugin::{self, Plugin},
repository, runtime,
repository, runtime, signal,
state::{self, Selection},
Installation, Package, Registry, State,
Installation, Package, Registry, Signal, State,
};

pub mod boot;
Expand Down Expand Up @@ -277,6 +277,8 @@ impl Client {
///
/// Returns `None` if the client is ephemeral
pub fn new_state(&self, selections: &[Selection], summary: impl ToString) -> Result<Option<State>, Error> {
let _guard = signal::ignore([Signal::SIGINT])?;

let old_state = self.installation.active_state;

let fstree = self.blit_root(selections.iter().map(|s| &s.package))?;
Expand Down Expand Up @@ -948,4 +950,6 @@ pub enum Error {
/// The operation was explicitly cancelled at the user's request
#[error("cancelled")]
Cancelled,
#[error("ignore signals during blit")]
BlitSignalIgnore(#[from] signal::Error),
}
4 changes: 3 additions & 1 deletion moss/src/client/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use vfs::tree::BlitFile;

use crate::{
client::{self, cache},
package, runtime, state, Client,
package, runtime, signal, state, Client, Signal,
};

pub fn verify(client: &Client, yes: bool, verbose: bool) -> Result<(), client::Error> {
Expand Down Expand Up @@ -224,6 +224,8 @@ pub fn verify(client: &Client, yes: bool, verbose: bool) -> Result<(), client::E

println!("Reblitting affected states");

let _guard = signal::ignore([Signal::SIGINT])?;

// Reblit each state
for id in issue_states {
let state = states
Expand Down
2 changes: 2 additions & 0 deletions moss/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub use self::installation::Installation;
pub use self::package::Package;
pub use self::registry::Registry;
pub use self::repository::Repository;
pub use self::signal::Signal;
pub use self::state::State;

pub mod client;
Expand All @@ -20,4 +21,5 @@ pub mod registry;
pub mod repository;
pub mod request;
pub mod runtime;
pub mod signal;
pub mod state;
53 changes: 53 additions & 0 deletions moss/src/signal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-FileCopyrightText: Copyright © 2020-2024 Serpent OS Developers
//
// SPDX-License-Identifier: MPL-2.0

//! Signal handling
use nix::sys::signal::{sigaction, SaFlags, SigAction, SigHandler, SigSet};
use thiserror::Error;

pub use nix::sys::signal::Signal;

/// Ignore the provided signals until [`Guard`] is dropped
pub fn ignore(signals: impl IntoIterator<Item = Signal>) -> Result<Guard, Error> {
Ok(Guard(
signals
.into_iter()
.map(|signal| unsafe {
let action = sigaction(
signal,
&SigAction::new(SigHandler::SigIgn, SaFlags::empty(), SigSet::empty()),
)
.map_err(Error::Ignore)?;

Ok(PrevHandler { signal, action })
})
.collect::<Result<_, Error>>()?,
))
}

/// A guard which restores the previous signal
/// handlers when dropped
pub struct Guard(Vec<PrevHandler>);

impl Drop for Guard {
fn drop(&mut self) {
for PrevHandler { signal, action } in &self.0 {
unsafe {
let _ = sigaction(*signal, action);
};
}
}
}

struct PrevHandler {
signal: Signal,
action: SigAction,
}

#[derive(Debug, Error)]
pub enum Error {
#[error("ignore signal")]
Ignore(#[source] nix::Error),
}

0 comments on commit 4966f0f

Please sign in to comment.