Skip to content

Instantly share code, notes, and snippets.

@se1983
Created March 16, 2024 12:43
Show Gist options
  • Save se1983/bcf79058a1bb58010a8d67ce2f1c4b84 to your computer and use it in GitHub Desktop.
Save se1983/bcf79058a1bb58010a8d67ce2f1c4b84 to your computer and use it in GitHub Desktop.
Signal driven I/O
use nix::libc::{F_SETOWN, STDIN_FILENO};
use nix::sys::signal::{SigSet, Signal, SigHandler, SigAction, SaFlags, sigaction};
use nix::unistd::{getpid, read};
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;
use std::time::Duration;
use nix::fcntl::fcntl;
static SIGNAL_RECEIVED: AtomicBool = AtomicBool::new(false);
extern "C" fn sigio_handler(sig: i32) {
println!("received signal {sig}");
SIGNAL_RECEIVED.store(true, Ordering::SeqCst);
}
fn main() {
// Establish handler for "I/O possible" signal
fcntl(STDIN_FILENO, nix::fcntl::FcntlArg::F_SETFL(nix::fcntl::OFlag::O_ASYNC)).unwrap();
// Create a SigSet containing SIGIO
let sigset = SigSet::empty();
// Register the signal handler for SIGIO
let sigio_action = SigAction::new(
SigHandler::Handler(sigio_handler),
SaFlags::SA_RESTART,
sigset,
);
unsafe {
sigaction(Signal::SIGIO, &sigio_action).unwrap();
}
unsafe {
let _ = nix::libc::fcntl(STDIN_FILENO, F_SETOWN, getpid());
}
// https://man7.org/tlpi/code/online/dist/tty/tty_functions.c.html
// Chapter 62: Terminals
let mut t = termios::Termios::from_fd(STDIN_FILENO).unwrap();
t.c_lflag &= !(termios::ICANON | termios::ECHO);
t.c_lflag |= termios::ISIG;
t.c_iflag &= !termios::ICRNL;
t.c_cc[termios::VMIN] = 1;
t.c_cc[termios::VTIME] = 0;
termios::tcsetattr(STDIN_FILENO, termios::TCSAFLUSH, &t).unwrap();
let mut cnt = 0;
'outer: loop {
if SIGNAL_RECEIVED.load(Ordering::SeqCst){
let mut buf = vec![0u8; 1024];
SIGNAL_RECEIVED.store(false, Ordering::SeqCst);
while read(STDIN_FILENO, &mut buf[..]).unwrap() > 1 {
let content = String::from_utf8_lossy(&buf);
println!("cnt={cnt}; read={content}");
if content.contains("#") {
break 'outer;
}
cnt += 1;
}
}
thread::sleep(Duration::from_secs(1));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment