Patchwork [07,of,13] rust-chg: add low-level function to set pager fd blocking

login
register
mail settings
Submitter Yuya Nishihara
Date Oct. 2, 2018, 2:25 p.m.
Message ID <caec87128374791fb7a9.1538490346@mimosa>
Download mbox | patch
Permalink /patch/35313/
State Accepted
Headers show

Comments

Yuya Nishihara - Oct. 2, 2018, 2:25 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# 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.

Patch

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) };