Read about our upcoming Code of Conduct on this issue

Commit 328474f1 authored by Yuya Nishihara's avatar Yuya Nishihara
Browse files

rust-chg: send client side umask to server

This is equivalent to forwardumask() of hgclient.c.

Differential Revision: https://phab.mercurial-scm.org/D8382
parent 9ce613d648de
......@@ -5,9 +5,10 @@
//! cHg extensions to command server client.
use bytes::Bytes;
use bytes::{BufMut, Bytes, BytesMut};
use std::ffi::OsStr;
use std::io;
use std::mem;
use std::os::unix::ffi::OsStrExt;
use std::os::unix::io::AsRawFd;
use std::path::Path;
......@@ -41,6 +42,9 @@ where
I: IntoIterator<Item = (P, P)>,
P: AsRef<OsStr>;
/// Changes the umask of the server process.
fn set_umask(self, mask: u32) -> OneShotRequest<C>;
/// Runs the specified Mercurial command with cHg extension.
fn run_command_chg<I, P, H>(self, handler: H, args: I) -> ChgRunCommand<C, H>
where
......@@ -90,6 +94,12 @@ where
OneShotRequest::start_with_args(self, b"setenv", message::pack_env_vars_os(vars))
}
fn set_umask(self, mask: u32) -> OneShotRequest<C> {
let mut args = BytesMut::with_capacity(mem::size_of_val(&mask));
args.put_u32_be(mask);
OneShotRequest::start_with_args(self, b"setumask2", args)
}
fn run_command_chg<I, P, H>(self, handler: H, args: I) -> ChgRunCommand<C, H>
where
I: IntoIterator<Item = P>,
......
......@@ -24,8 +24,14 @@ use super::clientext::ChgClientExt;
use super::message::{Instruction, ServerSpec};
use super::procutil;
const REQUIRED_SERVER_CAPABILITIES: &[&str] =
&["attachio", "chdir", "runcommand", "setenv", "validate"];
const REQUIRED_SERVER_CAPABILITIES: &[&str] = &[
"attachio",
"chdir",
"runcommand",
"setenv",
"setumask2",
"validate",
];
/// Helper to connect to and spawn a server process.
#[derive(Clone, Debug)]
......
......@@ -73,6 +73,7 @@ fn main() {
}
fn run() -> io::Result<i32> {
let umask = unsafe { procutil::get_umask() }; // not thread safe
let mut loc = Locator::prepare_from_env()?;
loc.set_early_args(locator::collect_early_args(env::args_os().skip(1)));
let handler = ChgUiHandler::new();
......@@ -80,6 +81,7 @@ fn run() -> io::Result<i32> {
let fut = loc
.connect()
.and_then(|(_, client)| client.attach_io(io::stdin(), io::stdout(), io::stderr()))
.and_then(move |client| client.set_umask(umask))
.and_then(|client| {
let pid = client.server_spec().process_id.unwrap();
let pgid = client.server_spec().process_group_id;
......
......@@ -25,6 +25,19 @@ pub fn get_effective_uid() -> u32 {
unsafe { libc::geteuid() }
}
/// Returns the umask of the current process.
///
/// # Safety
///
/// This is unsafe because the umask value is temporarily changed, and
/// the change can be observed from the other threads. Don't call this in
/// multi-threaded context.
pub unsafe fn get_umask() -> u32 {
let mask = libc::umask(0);
libc::umask(mask);
mask
}
/// 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) };
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment