Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

54
vendor/ctrlc/src/error.rs vendored Normal file
View File

@@ -0,0 +1,54 @@
use crate::platform;
use std::fmt;
/// Ctrl-C error.
#[derive(Debug)]
pub enum Error {
/// Signal could not be found from the system.
NoSuchSignal(crate::SignalType),
/// Ctrl-C signal handler already registered.
MultipleHandlers,
/// Unexpected system error.
System(std::io::Error),
}
impl Error {
fn describe(&self) -> &str {
match *self {
Error::NoSuchSignal(_) => "Signal could not be found from the system",
Error::MultipleHandlers => "Ctrl-C signal handler already registered",
Error::System(_) => "Unexpected system error",
}
}
}
impl From<platform::Error> for Error {
fn from(e: platform::Error) -> Error {
#[cfg(not(windows))]
if e == platform::Error::EEXIST {
return Error::MultipleHandlers;
}
let system_error = std::io::Error::new(std::io::ErrorKind::Other, e);
Error::System(system_error)
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Ctrl-C error: {}", self.describe())
}
}
impl std::error::Error for Error {
fn description(&self) -> &str {
self.describe()
}
fn cause(&self) -> Option<&dyn std::error::Error> {
match *self {
Error::System(ref e) => Some(e),
_ => None,
}
}
}

148
vendor/ctrlc/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,148 @@
// Copyright (c) 2017 CtrlC developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
#![warn(missing_docs)]
//! Cross platform handling of Ctrl-C signals.
//!
//! [HandlerRoutine]:https://msdn.microsoft.com/en-us/library/windows/desktop/ms683242.aspx
//!
//! [set_handler()](fn.set_handler.html) allows setting a handler closure which is executed on
//! `Ctrl+C`. On Unix, this corresponds to a `SIGINT` signal. On windows, `Ctrl+C` corresponds to
//! [`CTRL_C_EVENT`][HandlerRoutine] or [`CTRL_BREAK_EVENT`][HandlerRoutine].
//!
//! Setting a handler will start a new dedicated signal handling thread where we
//! execute the handler each time we receive a `Ctrl+C` signal. There can only be
//! one handler, you would typically set one at the start of your program.
//!
//! # Example
//! ```no_run
//! # #[allow(clippy::needless_doctest_main)]
//! use std::sync::atomic::{AtomicBool, Ordering};
//! use std::sync::Arc;
//!
//! fn main() {
//! let running = Arc::new(AtomicBool::new(true));
//! let r = running.clone();
//!
//! ctrlc::set_handler(move || {
//! r.store(false, Ordering::SeqCst);
//! }).expect("Error setting Ctrl-C handler");
//!
//! println!("Waiting for Ctrl-C...");
//! while running.load(Ordering::SeqCst) {}
//! println!("Got it! Exiting...");
//! }
//! ```
//!
//! # Handling SIGTERM and SIGHUP
//! Handling of `SIGTERM` and `SIGHUP` can be enabled with `termination` feature. If this is enabled,
//! the handler specified by `set_handler()` will be executed for `SIGINT`, `SIGTERM` and `SIGHUP`.
//!
#[macro_use]
mod error;
mod platform;
pub use platform::Signal;
mod signal;
pub use signal::*;
pub use error::Error;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Mutex;
use std::thread;
static INIT: AtomicBool = AtomicBool::new(false);
static INIT_LOCK: Mutex<()> = Mutex::new(());
/// Register signal handler for Ctrl-C.
///
/// Starts a new dedicated signal handling thread. Should only be called once,
/// typically at the start of your program.
///
/// # Example
/// ```no_run
/// ctrlc::set_handler(|| println!("Hello world!")).expect("Error setting Ctrl-C handler");
/// ```
///
/// # Warning
/// On Unix, the handler registration for `SIGINT`, (`SIGTERM` and `SIGHUP` if termination feature
/// is enabled) or `SA_SIGINFO` posix signal handlers will be overwritten. On Windows, multiple
/// handler routines are allowed, but they are called on a last-registered, first-called basis
/// until the signal is handled.
///
/// ctrlc::try_set_handler will error (on Unix) if another signal handler exists for the same
/// signal(s) that ctrlc is trying to attach the handler to.
///
/// On Unix, signal dispositions and signal handlers are inherited by child processes created via
/// `fork(2)` on, but not by child processes created via `execve(2)`.
/// Signal handlers are not inherited on Windows.
///
/// # Errors
/// Will return an error if a system error occurred while setting the handler.
///
/// # Panics
/// Any panic in the handler will not be caught and will cause the signal handler thread to stop.
pub fn set_handler<F>(user_handler: F) -> Result<(), Error>
where
F: FnMut() + 'static + Send,
{
init_and_set_handler(user_handler, true)
}
/// The same as ctrlc::set_handler but errors if a handler already exists for the signal(s).
///
/// # Errors
/// Will return an error if another handler exists or if a system error occurred while setting the
/// handler.
pub fn try_set_handler<F>(user_handler: F) -> Result<(), Error>
where
F: FnMut() + 'static + Send,
{
init_and_set_handler(user_handler, false)
}
fn init_and_set_handler<F>(user_handler: F, overwrite: bool) -> Result<(), Error>
where
F: FnMut() + 'static + Send,
{
if !INIT.load(Ordering::Acquire) {
let _guard = INIT_LOCK.lock().unwrap();
if !INIT.load(Ordering::Relaxed) {
set_handler_inner(user_handler, overwrite)?;
INIT.store(true, Ordering::Release);
return Ok(());
}
}
Err(Error::MultipleHandlers)
}
fn set_handler_inner<F>(mut user_handler: F, overwrite: bool) -> Result<(), Error>
where
F: FnMut() + 'static + Send,
{
unsafe {
platform::init_os_handler(overwrite)?;
}
thread::Builder::new()
.name("ctrl-c".into())
.spawn(move || loop {
unsafe {
platform::block_ctrl_c().expect("Critical system error while waiting for Ctrl-C");
}
user_handler();
})
.map_err(Error::System)?;
Ok(())
}

20
vendor/ctrlc/src/platform/mod.rs vendored Normal file
View File

@@ -0,0 +1,20 @@
// Copyright (c) 2017 CtrlC developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
#[cfg(unix)]
mod unix;
#[cfg(windows)]
mod windows;
#[cfg(unix)]
pub use self::unix::*;
#[cfg(windows)]
pub use self::windows::*;

138
vendor/ctrlc/src/platform/unix/mod.rs vendored Normal file
View File

@@ -0,0 +1,138 @@
// Copyright (c) 2017 CtrlC developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
use crate::error::Error as CtrlcError;
#[cfg(not(target_vendor = "apple"))]
#[allow(static_mut_refs)] // rust-version = "1.69.0"
mod implementation {
static mut SEMAPHORE: nix::libc::sem_t = unsafe { std::mem::zeroed() };
const SEM_THREAD_SHARED: nix::libc::c_int = 0;
pub unsafe fn sem_init() {
nix::libc::sem_init(&mut SEMAPHORE as *mut _, SEM_THREAD_SHARED, 0);
}
pub unsafe fn sem_post() {
// No errors apply. EOVERFLOW is hypothetically possible but it's equivalent to a success for our oneshot use-case.
let _ = nix::libc::sem_post(&mut SEMAPHORE as *mut _);
}
pub unsafe fn sem_wait_forever() {
// The only realistic error is EINTR, which is restartable.
while nix::libc::sem_wait(&mut SEMAPHORE as *mut _) == -1 {}
}
}
#[cfg(target_vendor = "apple")]
mod implementation {
static mut SEMAPHORE: dispatch::ffi::dispatch_semaphore_t = std::ptr::null_mut();
pub unsafe fn sem_init() {
SEMAPHORE = dispatch::ffi::dispatch_semaphore_create(0);
}
pub unsafe fn sem_post() {
dispatch::ffi::dispatch_semaphore_signal(SEMAPHORE);
}
pub unsafe fn sem_wait_forever() {
dispatch::ffi::dispatch_semaphore_wait(SEMAPHORE, dispatch::ffi::DISPATCH_TIME_FOREVER);
}
}
/// Platform specific error type
pub type Error = nix::Error;
/// Platform specific signal type
pub type Signal = nix::sys::signal::Signal;
extern "C" fn os_handler(_: nix::libc::c_int) {
unsafe {
implementation::sem_post();
}
}
/// Register os signal handler.
///
/// Must be called before calling [`block_ctrl_c()`](fn.block_ctrl_c.html)
/// and should only be called once.
///
/// # Errors
/// Will return an error if a system error occurred.
///
#[inline]
pub unsafe fn init_os_handler(overwrite: bool) -> Result<(), Error> {
use nix::sys::signal;
implementation::sem_init();
let handler = signal::SigHandler::Handler(os_handler);
#[cfg(not(target_os = "nto"))]
let new_action = signal::SigAction::new(
handler,
signal::SaFlags::SA_RESTART,
signal::SigSet::empty(),
);
// SA_RESTART is not supported on QNX Neutrino 7.1 and before
#[cfg(target_os = "nto")]
let new_action =
signal::SigAction::new(handler, signal::SaFlags::empty(), signal::SigSet::empty());
let sigint_old = signal::sigaction(signal::Signal::SIGINT, &new_action)?;
if !overwrite && sigint_old.handler() != signal::SigHandler::SigDfl {
signal::sigaction(signal::Signal::SIGINT, &sigint_old).unwrap();
return Err(nix::Error::EEXIST);
}
#[cfg(feature = "termination")]
{
let sigterm_old = match signal::sigaction(signal::Signal::SIGTERM, &new_action) {
Ok(old) => old,
Err(e) => {
signal::sigaction(signal::Signal::SIGINT, &sigint_old).unwrap();
return Err(e);
}
};
if !overwrite && sigterm_old.handler() != signal::SigHandler::SigDfl {
signal::sigaction(signal::Signal::SIGINT, &sigint_old).unwrap();
signal::sigaction(signal::Signal::SIGTERM, &sigterm_old).unwrap();
return Err(nix::Error::EEXIST);
}
let sighup_old = match signal::sigaction(signal::Signal::SIGHUP, &new_action) {
Ok(old) => old,
Err(e) => {
signal::sigaction(signal::Signal::SIGINT, &sigint_old).unwrap();
signal::sigaction(signal::Signal::SIGTERM, &sigterm_old).unwrap();
return Err(e);
}
};
if !overwrite && sighup_old.handler() != signal::SigHandler::SigDfl {
signal::sigaction(signal::Signal::SIGINT, &sigint_old).unwrap();
signal::sigaction(signal::Signal::SIGTERM, &sigterm_old).unwrap();
signal::sigaction(signal::Signal::SIGHUP, &sighup_old).unwrap();
return Err(nix::Error::EEXIST);
}
}
Ok(())
}
/// Blocks until a Ctrl-C signal is received.
///
/// Must be called after calling [`init_os_handler()`](fn.init_os_handler.html).
///
/// # Errors
/// None.
///
#[inline]
pub unsafe fn block_ctrl_c() -> Result<(), CtrlcError> {
implementation::sem_wait_forever();
Ok(())
}

View File

@@ -0,0 +1,81 @@
// Copyright (c) 2017 CtrlC developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
use std::io;
use std::ptr;
use windows_sys::core::BOOL;
use windows_sys::Win32::Foundation::{CloseHandle, HANDLE, WAIT_FAILED, WAIT_OBJECT_0};
use windows_sys::Win32::System::Console::SetConsoleCtrlHandler;
use windows_sys::Win32::System::Threading::{
CreateSemaphoreA, ReleaseSemaphore, WaitForSingleObject, INFINITE,
};
/// Platform specific error type
pub type Error = io::Error;
/// Platform specific signal type
pub type Signal = u32;
const MAX_SEM_COUNT: i32 = 255;
static mut SEMAPHORE: HANDLE = 0 as HANDLE;
const TRUE: BOOL = 1;
const FALSE: BOOL = 0;
unsafe extern "system" fn os_handler(_: u32) -> BOOL {
// Assuming this always succeeds. Can't really handle errors in any meaningful way.
ReleaseSemaphore(SEMAPHORE, 1, ptr::null_mut());
TRUE
}
/// Register os signal handler.
///
/// Must be called before calling [`block_ctrl_c()`](fn.block_ctrl_c.html)
/// and should only be called once.
///
/// # Errors
/// Will return an error if a system error occurred.
///
#[inline]
pub unsafe fn init_os_handler(_overwrite: bool) -> Result<(), Error> {
SEMAPHORE = CreateSemaphoreA(ptr::null_mut(), 0, MAX_SEM_COUNT, ptr::null());
if SEMAPHORE.is_null() {
return Err(io::Error::last_os_error());
}
if SetConsoleCtrlHandler(Some(os_handler), TRUE) == FALSE {
let e = io::Error::last_os_error();
CloseHandle(SEMAPHORE);
SEMAPHORE = 0 as HANDLE;
return Err(e);
}
Ok(())
}
/// Blocks until a Ctrl-C signal is received.
///
/// Must be called after calling [`init_os_handler()`](fn.init_os_handler.html).
///
/// # Errors
/// Will return an error if a system error occurred.
///
#[inline]
pub unsafe fn block_ctrl_c() -> Result<(), Error> {
match WaitForSingleObject(SEMAPHORE, INFINITE) {
WAIT_OBJECT_0 => Ok(()),
WAIT_FAILED => Err(io::Error::last_os_error()),
ret => Err(io::Error::new(
io::ErrorKind::Other,
format!(
"WaitForSingleObject(), unexpected return value \"{:x}\"",
ret
),
)),
}
}

23
vendor/ctrlc/src/signal.rs vendored Normal file
View File

@@ -0,0 +1,23 @@
// Copyright (c) 2017 CtrlC developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
use crate::platform;
/// A cross-platform way to represent Ctrl-C or program termination signal. Other
/// signals/events are supported via `Other`-variant.
#[derive(Debug)]
pub enum SignalType {
/// Ctrl-C
Ctrlc,
/// Program termination
/// Maps to `SIGTERM` and `SIGHUP` on *nix, `CTRL_CLOSE_EVENT` on Windows.
Termination,
/// Other signal/event using platform-specific data
Other(platform::Signal),
}