Patchwork D8382: rust-chg: send client side umask to server

login
register
mail settings
Submitter phabricator
Date April 9, 2020, 7:26 p.m.
Message ID <d5e2d5281f4f6bbdaab8ea8ed683ce95@localhost.localdomain>
Download mbox | patch
Permalink /patch/46053/
State Not Applicable
Headers show

Comments

phabricator - April 9, 2020, 7:26 p.m.
Closed by commit rHG065048e66f32: rust-chg: send client side umask to server (authored by yuja).
This revision was automatically updated to reflect the committed changes.
This revision was not accepted when it landed; it landed in state "Needs Review".

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D8382?vs=20998&id=21020

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D8382/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D8382

AFFECTED FILES
  rust/chg/src/clientext.rs
  rust/chg/src/locator.rs
  rust/chg/src/main.rs
  rust/chg/src/procutil.rs

CHANGE DETAILS




To: yuja, #hg-reviewers, Alphare
Cc: mercurial-devel

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
@@ -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) };
diff --git a/rust/chg/src/main.rs b/rust/chg/src/main.rs
--- a/rust/chg/src/main.rs
+++ b/rust/chg/src/main.rs
@@ -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;
diff --git a/rust/chg/src/locator.rs b/rust/chg/src/locator.rs
--- a/rust/chg/src/locator.rs
+++ b/rust/chg/src/locator.rs
@@ -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)]
diff --git a/rust/chg/src/clientext.rs b/rust/chg/src/clientext.rs
--- a/rust/chg/src/clientext.rs
+++ b/rust/chg/src/clientext.rs
@@ -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>,