Mercurial > hg
changeset 44683:065048e66f32
rust-chg: send client side umask to server
This is equivalent to forwardumask() of hgclient.c.
Differential Revision: https://phab.mercurial-scm.org/D8382
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Thu, 04 Oct 2018 22:44:37 +0900 |
parents | 9ce613d648de |
children | 80d6e3415636 |
files | rust/chg/src/clientext.rs rust/chg/src/locator.rs rust/chg/src/main.rs rust/chg/src/procutil.rs |
diffstat | 4 files changed, 34 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/chg/src/clientext.rs Sun Oct 07 16:14:21 2018 +0900 +++ b/rust/chg/src/clientext.rs Thu Oct 04 22:44:37 2018 +0900 @@ -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 @@ 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 @@ 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>,
--- a/rust/chg/src/locator.rs Sun Oct 07 16:14:21 2018 +0900 +++ b/rust/chg/src/locator.rs Thu Oct 04 22:44:37 2018 +0900 @@ -24,8 +24,14 @@ 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)]
--- a/rust/chg/src/main.rs Sun Oct 07 16:14:21 2018 +0900 +++ b/rust/chg/src/main.rs Thu Oct 04 22:44:37 2018 +0900 @@ -73,6 +73,7 @@ } 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 @@ 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;
--- a/rust/chg/src/procutil.rs Sun Oct 07 16:14:21 2018 +0900 +++ b/rust/chg/src/procutil.rs Thu Oct 04 22:44:37 2018 +0900 @@ -25,6 +25,19 @@ 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) };