3个不稳定版本
0.1.1 | 2020年3月26日 |
---|---|
0.1.0 | 2020年3月26日 |
0.0.1 | 2020年3月25日 |
#376 in Unix APIs
用于 krecik
49KB
421 行代码(不含注释)
Addy
一个用于优雅处理内核中断的库。
快速入门
use addy::SIGWINCH;
use std::io::{Read, stdin};
fn main() -> Result<(), addy::Error> {
/* SIGWINCH is a POSIX interrupt signal for window resized */
addy::mediate(SIGWINCH)
.register("print", |_signal| { println!("Screen Resized!"); })?
.enable()?;
/* Block so the program doesn't exit immediately
* Try resizing your terminal window :)
*/
let mut buffer = [0; 1];
loop {
stdin().read(&mut buffer);
}
Ok(())
}
函数
中介
这为您提供了一个SignalHandle,表示您想要交互的中断处理器。SignalHandles是线程安全的!您可以从任何地方调用/创建/移动它们!
use addy::SIGWINCH;
use std::io::{Read, stdin};
fn main() -> Result<(), addy::Error> {
addy::mediate(SIGWINCH)
.register("resized", |_signal| { println!("Screen Resized!"); })?
.enable()?;
/* Block so the program doesn't exit immediately
* Try resizing your terminal window :)
*/
let mut buffer = [0; 1];
loop {
stdin().read(&mut buffer);
}
Ok(())
}
注册
将回调注册到关联的Signal的中断处理器。如果您使用相同的名称调用register,它将替换先前的回调。
use addy::{Signal, SIGWINCH};
fn my_func(signal: Signal) {
/* Does a thing */
}
fn main() -> Result<(), addy::Error> {
addy::mediate(SIGWINCH)
.register("print", |_signal| { println!("Screen Resized!"); })?
.register("my_func", my_func)?
.enable()?;
Ok(())
}
启用
开始捕获中断并调用任何关联的回调。通常在调用.register()之后使用。
等同于 .resume()
use addy::SIGINT;
fn main() -> Result<(), addy::Error> {
addy::mediate(SIGINT)
.register("print", |_signal| { println!("Interrupted!"); })?
.enable()?;
Ok(())
}
移除
从关联的Signal中删除一个命名的回调。如果不存在该名称的回调,则不执行任何操作。
use addy::{Signal, SIGWINCH};
fn my_func(signal: Signal) {
/* Does a thing */
}
fn main() -> Result<(), addy::Error> {
addy::mediate(SIGWINCH)
.register("print", |_signal| { println!("Screen Resized!"); })?
.register("my_func", my_func)?
.enable()?;
//-- Later --//
// Stop calling "print" when the process receives a SIGWINCH signal
addy::mediate(SIGWINCH).remove("print")?;
Ok(())
}
清除
从关联的Signal中删除所有回调。功能上类似于调用.ignore()
,但您不需要在稍后添加新回调时调用.enable()
。
use addy::{Signal, SIGWINCH};
fn my_func(signal: Signal) {
/* Does a thing */
}
fn main() -> Result<(), addy::Error> {
addy::mediate(SIGWINCH)
.register("print", |_signal| { println!("Screen Resized!"); })?
.register("my_func", my_func)?
.enable()?;
//-- Later --//
// Capture the signal, but stop calling anything
addy::mediate(SIGWINCH)
.clear()?
.register("solo_callback", |_signal| { println!("ALONE!"); })?;
Ok(())
}
释放
从关联的Signal中删除所有回调并将中断处理器重置为默认行为。功能上等同于调用.clear()
和.default()
。您需要重新注册回调后再次调用.enable()
。
use addy::SIGWINCH;
fn main() -> Result<(), addy::Error> {
addy::mediate(SIGWINCH)
.register("print", |_signal| { println!("Screen Resized!"); })?
.enable()?;
//-- Later --//
// Stop capturing the signal
addy::mediate(SIGWINCH).release()?;
//-- Later Still --//
// Start catpuring again
addy::mediate(SIGWINCH)
.register("new", |_signal| { println!("New callback!"); })?
.enable()?;
Ok(())
}
忽略
告诉进程忽略此中断。保留所有回调。调用.resume()
将重新启用它们。
use addy::SIGWINCH;
fn main() -> Result<(), addy::Error> {
addy::mediate(SIGWINCH)
.register("print", |_signal| { println!("Screen Resized!"); })?
.enable()?;
//-- Later --//
// Ignore the signal
addy::mediate(SIGWINCH).ignore()?;
//-- Later Still --//
// Start catpuring again
addy::mediate(SIGWINCH).resume()?;
Ok(())
}
默认
将中断处理器恢复到系统默认设置。并非所有中断都有默认设置,有些中断的默认设置是忽略。保留所有回调。调用.resume()
将重新启用它们。
use addy::SIGINT;
fn main() -> Result<(), addy::Error> {
addy::mediate(SIGINT)
.register("print", |_signal| { println!("Interrupted!"); })?
.enable()?;
//-- Later --//
// Set the signal to its default
addy::mediate(SIGINT).default()?;
//-- Later Still --//
// Start catpuring again
addy::mediate(SIGINT).resume()?;
Ok(())
}
恢复
捕获中断并调用任何相关回调的简历。通常在调用 .ignore() 和 .default() 之后使用。
是 .enable() 的别名。
use addy::SIGINT;
fn main() -> Result<(), addy::Error> {
addy::mediate(SIGINT)
.register("print", |_signal| { println!("Interrupted!"); })?
.enable()?;
//-- Later --//
// Set the signal to its default
addy::mediate(SIGINT).default()?;
//-- Later Still --//
// Start catpuring and printing "Interrupted!" again
addy::mediate(SIGINT).resume()?;
Ok(())
}
注意事项
我爱你,并祝你一切顺利。无论你选择做什么,希望你觉得值得花时间去做好它。
Addy 是线程安全的!
你可以在任何地方、任何时候调用它!你可以将 SignalHandle(来自 addy::mediate(signal))存储在变量中并传递它。
use addy::{SIGWINCH, SIGINT};
use std::io::{Read, stdin};
static QUOTE: &'static str = "Look at you, hacker: a pathetic creature of meat \
and bone, panting and sweating as you run through \
my corridors. How can you challenge a perfect, \
immortal machine?";
fn main() -> Result<(), addy::Error> {
/* When the window resizes */
addy::mediate(SIGWINCH)
.register("hello", |_signal| { println!("Hello, World!"); })?
.register("girls", |_signal| { println!("Hello, Girls!"); })?
.enable()?;
/* SIGINT is sent when the user presses Ctrl + C. The default behavior is
* to interrupt the program's execution.
*/
let mut ctrl_c = addy::mediate(SIGINT);
ctrl_c.register("no_interruptions", |_signal| { println!("{}", QUOTE); })?.enable()?;
/* Let the user use Ctrl + C to kill the program after 10 seconds */
std::thread::spawn(move || -> Result<(), addy::Error> {
std::thread::sleep(std::time::Duration::from_secs(10));
ctrl_c.default()?;
Ok(())
});
/* Stop saying "Hello, World!" on resize after 5 seconds */
std::thread::spawn(move || -> Result<(), addy::Error> {
std::thread::sleep(std::time::Duration::from_secs(5));
addy::mediate(SIGWINCH).remove("hello")?;
Ok(())
});
/* Capture the input so we don't exit the program immediately */
let mut buffer = [0; 1];
loop {
stdin().read(&mut buffer);
}
Ok(())
}
支持的信号
并非所有平台/架构都支持所有信号。你的平台支持哪些信号?运行:kill -l
来查找!
- SIGHUP
- SIGINT
- SIGQUIT
- SIGILL
- SIGTRAP
- SIGABRT
- SIGBUS
- SIGFPE
- SIGKILL
- SIGUSR1
- SIGSEGV
- SIGUSR2
- SIGPIPE
- SIGALRM
- SIGTERM
- SIGSTKF
- SIGCHLD
- SIGCONT
- SIGSTOP
- SIGTSTP
- SIGTTIN
- SIGTTOU
- SIGURG
- SIGXCPU
- SIGXFSZ
- SIGVTAL
- SIGPROF
- SIGWINC
- SIGIO
- SIGPWR
- SIGSYS
- SIGEMT
- SIGINFO
错误
如果 MPSC 通道关闭或事件循环线程关闭,将无法恢复,任何未来的 Addy 调用都将返回 addy::Error。
依赖关系
~69KB