rust-chg: add low-level function to set pager fd blocking
This is necessary because the server expects stdout/stderr to be blocking,
whereas we'll use async library to spawn pager, which makes pipes unblocking.
--- a/rust/chg/src/procutil.rs Mon Sep 24 16:59:12 2018 +0900
+++ b/rust/chg/src/procutil.rs Sat Sep 29 21:59:07 2018 +0900
@@ -5,7 +5,7 @@
//! Low-level utility for signal and process handling.
-use libc::{c_int, size_t, ssize_t};
+use libc::{self, c_int, size_t, ssize_t};
use std::io;
use std::os::unix::io::RawFd;
@@ -15,6 +15,19 @@
fn sendfds(sockfd: c_int, fds: *const c_int, fdlen: size_t) -> ssize_t;
}
+/// Changes the given fd to blocking mode.
+pub fn set_blocking_fd(fd: RawFd) -> io::Result<()> {
+ let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) };
+ if flags < 0 {
+ return Err(io::Error::last_os_error());
+ }
+ let r = unsafe { libc::fcntl(fd, libc::F_SETFL, flags & !libc::O_NONBLOCK) };
+ if r < 0 {
+ return Err(io::Error::last_os_error())
+ }
+ Ok(())
+}
+
/// Sends file descriptors via the given socket.
pub fn send_raw_fds(sock_fd: RawFd, fds: &[RawFd]) -> io::Result<()> {
let r = unsafe { sendfds(sock_fd, fds.as_ptr(), fds.len() as size_t) };