rust/chg/src/procutil.rs
author Yuya Nishihara <yuya@tcha.org>
Fri, 14 Dec 2018 21:19:19 +0900
changeset 40955 e48fdeb08c77
parent 40121 89742f1fa6cb
child 43836 ce088b38f92b
permissions -rw-r--r--
py3: fix bad escapes of sub() replacement pattern in test-template-basic.t Python 3.7 starts complaining about it. We have to double the backslash or '\x5c' to get around.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
39971
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     1
// Copyright 2018 Yuya Nishihara <yuya@tcha.org>
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     2
//
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     3
// This software may be used and distributed according to the terms of the
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     4
// GNU General Public License version 2 or any later version.
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     5
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     6
//! Low-level utility for signal and process handling.
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     7
40121
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
     8
use libc::{self, c_int, pid_t, size_t, ssize_t};
39971
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
     9
use std::io;
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    10
use std::os::unix::io::RawFd;
40121
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    11
use std::sync;
39971
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    12
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    13
#[link(name = "procutil", kind = "static")]
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    14
extern "C" {
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    15
    // sendfds.c
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    16
    fn sendfds(sockfd: c_int, fds: *const c_int, fdlen: size_t) -> ssize_t;
40121
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    17
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    18
    // sighandlers.c
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    19
    fn setupsignalhandler(pid: pid_t, pgid: pid_t) -> c_int;
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    20
    fn restoresignalhandler() -> c_int;
39971
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    21
}
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    22
39977
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents: 39974
diff changeset
    23
/// Returns the effective uid of the current process.
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents: 39974
diff changeset
    24
pub fn get_effective_uid() -> u32 {
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents: 39974
diff changeset
    25
    unsafe { libc::geteuid() }
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents: 39974
diff changeset
    26
}
44840bcc411a rust-chg: port basic socket path handling from cHg of C
Yuya Nishihara <yuya@tcha.org>
parents: 39974
diff changeset
    27
39974
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39971
diff changeset
    28
/// Changes the given fd to blocking mode.
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39971
diff changeset
    29
pub fn set_blocking_fd(fd: RawFd) -> io::Result<()> {
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39971
diff changeset
    30
    let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) };
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39971
diff changeset
    31
    if flags < 0 {
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39971
diff changeset
    32
        return Err(io::Error::last_os_error());
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39971
diff changeset
    33
    }
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39971
diff changeset
    34
    let r = unsafe { libc::fcntl(fd, libc::F_SETFL, flags & !libc::O_NONBLOCK) };
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39971
diff changeset
    35
    if r < 0 {
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39971
diff changeset
    36
        return Err(io::Error::last_os_error())
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39971
diff changeset
    37
    }
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39971
diff changeset
    38
    Ok(())
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39971
diff changeset
    39
}
ba447b83cd56 rust-chg: add low-level function to set pager fd blocking
Yuya Nishihara <yuya@tcha.org>
parents: 39971
diff changeset
    40
39971
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    41
/// Sends file descriptors via the given socket.
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    42
pub fn send_raw_fds(sock_fd: RawFd, fds: &[RawFd]) -> io::Result<()> {
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    43
    let r = unsafe { sendfds(sock_fd, fds.as_ptr(), fds.len() as size_t) };
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    44
    if r < 0 {
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    45
        return Err(io::Error::last_os_error());
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    46
    }
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    47
    Ok(())
a8be2cff613f rust-chg: add wrapper around C function
Yuya Nishihara <yuya@tcha.org>
parents:
diff changeset
    48
}
40121
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    49
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    50
static SETUP_SIGNAL_HANDLER: sync::Once = sync::Once::new();
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    51
static RESTORE_SIGNAL_HANDLER: sync::Once = sync::Once::new();
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    52
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    53
/// Installs signal handlers to forward signals to the server.
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    54
///
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    55
/// # Safety
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    56
///
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    57
/// This touches global states, and thus synchronized as a one-time
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    58
/// initialization function.
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    59
pub fn setup_signal_handler_once(pid: u32, pgid: Option<u32>) -> io::Result<()> {
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    60
    let pid_signed = pid as i32;
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    61
    let pgid_signed = pgid.map(|n| n as i32).unwrap_or(0);
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    62
    let mut r = 0;
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    63
    SETUP_SIGNAL_HANDLER.call_once(|| {
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    64
        r = unsafe { setupsignalhandler(pid_signed, pgid_signed) };
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    65
    });
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    66
    if r < 0 {
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    67
        return Err(io::Error::last_os_error());
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    68
    }
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    69
    Ok(())
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    70
}
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    71
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    72
/// Restores the original signal handlers.
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    73
///
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    74
/// # Safety
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    75
///
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    76
/// This touches global states, and thus synchronized as a one-time
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    77
/// initialization function.
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    78
pub fn restore_signal_handler_once() -> io::Result<()> {
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    79
    let mut r = 0;
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    80
    RESTORE_SIGNAL_HANDLER.call_once(|| {
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    81
        r = unsafe { restoresignalhandler() };
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    82
    });
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    83
    if r < 0 {
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    84
        return Err(io::Error::last_os_error());
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    85
    }
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    86
    Ok(())
89742f1fa6cb rust-chg: install signal handlers to forward signals to server
Yuya Nishihara <yuya@tcha.org>
parents: 39977
diff changeset
    87
}