From patchwork Tue Oct 2 14:25:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [07,of,13] rust-chg: add low-level function to set pager fd blocking From: Yuya Nishihara X-Patchwork-Id: 35313 Message-Id: To: mercurial-devel@mercurial-scm.org Date: Tue, 02 Oct 2018 23:25:46 +0900 # HG changeset patch # User Yuya Nishihara # Date 1538225947 -32400 # Sat Sep 29 21:59:07 2018 +0900 # Node ID caec87128374791fb7a9d1fa8a43d115a8e899ef # Parent 1a03fbcfeb85eddff5ecd5dd62944d2827cf1816 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. diff --git a/rust/chg/src/procutil.rs b/rust/chg/src/procutil.rs --- a/rust/chg/src/procutil.rs +++ b/rust/chg/src/procutil.rs @@ -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 @@ extern "C" { 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) };