Show More
@@ -5,9 +5,10 b'' | |||||
5 |
|
5 | |||
6 | //! cHg extensions to command server client. |
|
6 | //! cHg extensions to command server client. | |
7 |
|
7 | |||
8 | use bytes::Bytes; |
|
8 | use bytes::{BufMut, Bytes, BytesMut}; | |
9 | use std::ffi::OsStr; |
|
9 | use std::ffi::OsStr; | |
10 | use std::io; |
|
10 | use std::io; | |
|
11 | use std::mem; | |||
11 | use std::os::unix::ffi::OsStrExt; |
|
12 | use std::os::unix::ffi::OsStrExt; | |
12 | use std::os::unix::io::AsRawFd; |
|
13 | use std::os::unix::io::AsRawFd; | |
13 | use std::path::Path; |
|
14 | use std::path::Path; | |
@@ -41,6 +42,9 b' where' | |||||
41 | I: IntoIterator<Item = (P, P)>, |
|
42 | I: IntoIterator<Item = (P, P)>, | |
42 | P: AsRef<OsStr>; |
|
43 | P: AsRef<OsStr>; | |
43 |
|
44 | |||
|
45 | /// Changes the umask of the server process. | |||
|
46 | fn set_umask(self, mask: u32) -> OneShotRequest<C>; | |||
|
47 | ||||
44 | /// Runs the specified Mercurial command with cHg extension. |
|
48 | /// Runs the specified Mercurial command with cHg extension. | |
45 | fn run_command_chg<I, P, H>(self, handler: H, args: I) -> ChgRunCommand<C, H> |
|
49 | fn run_command_chg<I, P, H>(self, handler: H, args: I) -> ChgRunCommand<C, H> | |
46 | where |
|
50 | where | |
@@ -90,6 +94,12 b' where' | |||||
90 | OneShotRequest::start_with_args(self, b"setenv", message::pack_env_vars_os(vars)) |
|
94 | OneShotRequest::start_with_args(self, b"setenv", message::pack_env_vars_os(vars)) | |
91 | } |
|
95 | } | |
92 |
|
96 | |||
|
97 | fn set_umask(self, mask: u32) -> OneShotRequest<C> { | |||
|
98 | let mut args = BytesMut::with_capacity(mem::size_of_val(&mask)); | |||
|
99 | args.put_u32_be(mask); | |||
|
100 | OneShotRequest::start_with_args(self, b"setumask2", args) | |||
|
101 | } | |||
|
102 | ||||
93 | fn run_command_chg<I, P, H>(self, handler: H, args: I) -> ChgRunCommand<C, H> |
|
103 | fn run_command_chg<I, P, H>(self, handler: H, args: I) -> ChgRunCommand<C, H> | |
94 | where |
|
104 | where | |
95 | I: IntoIterator<Item = P>, |
|
105 | I: IntoIterator<Item = P>, |
@@ -24,8 +24,14 b' use super::clientext::ChgClientExt;' | |||||
24 | use super::message::{Instruction, ServerSpec}; |
|
24 | use super::message::{Instruction, ServerSpec}; | |
25 | use super::procutil; |
|
25 | use super::procutil; | |
26 |
|
26 | |||
27 | const REQUIRED_SERVER_CAPABILITIES: &[&str] = |
|
27 | const REQUIRED_SERVER_CAPABILITIES: &[&str] = &[ | |
28 | &["attachio", "chdir", "runcommand", "setenv", "validate"]; |
|
28 | "attachio", | |
|
29 | "chdir", | |||
|
30 | "runcommand", | |||
|
31 | "setenv", | |||
|
32 | "setumask2", | |||
|
33 | "validate", | |||
|
34 | ]; | |||
29 |
|
35 | |||
30 | /// Helper to connect to and spawn a server process. |
|
36 | /// Helper to connect to and spawn a server process. | |
31 | #[derive(Clone, Debug)] |
|
37 | #[derive(Clone, Debug)] |
@@ -73,6 +73,7 b' fn main() {' | |||||
73 | } |
|
73 | } | |
74 |
|
74 | |||
75 | fn run() -> io::Result<i32> { |
|
75 | fn run() -> io::Result<i32> { | |
|
76 | let umask = unsafe { procutil::get_umask() }; // not thread safe | |||
76 | let mut loc = Locator::prepare_from_env()?; |
|
77 | let mut loc = Locator::prepare_from_env()?; | |
77 | loc.set_early_args(locator::collect_early_args(env::args_os().skip(1))); |
|
78 | loc.set_early_args(locator::collect_early_args(env::args_os().skip(1))); | |
78 | let handler = ChgUiHandler::new(); |
|
79 | let handler = ChgUiHandler::new(); | |
@@ -80,6 +81,7 b' fn run() -> io::Result<i32> {' | |||||
80 | let fut = loc |
|
81 | let fut = loc | |
81 | .connect() |
|
82 | .connect() | |
82 | .and_then(|(_, client)| client.attach_io(io::stdin(), io::stdout(), io::stderr())) |
|
83 | .and_then(|(_, client)| client.attach_io(io::stdin(), io::stdout(), io::stderr())) | |
|
84 | .and_then(move |client| client.set_umask(umask)) | |||
83 | .and_then(|client| { |
|
85 | .and_then(|client| { | |
84 | let pid = client.server_spec().process_id.unwrap(); |
|
86 | let pid = client.server_spec().process_id.unwrap(); | |
85 | let pgid = client.server_spec().process_group_id; |
|
87 | let pgid = client.server_spec().process_group_id; |
@@ -25,6 +25,19 b' pub fn get_effective_uid() -> u32 {' | |||||
25 | unsafe { libc::geteuid() } |
|
25 | unsafe { libc::geteuid() } | |
26 | } |
|
26 | } | |
27 |
|
27 | |||
|
28 | /// Returns the umask of the current process. | |||
|
29 | /// | |||
|
30 | /// # Safety | |||
|
31 | /// | |||
|
32 | /// This is unsafe because the umask value is temporarily changed, and | |||
|
33 | /// the change can be observed from the other threads. Don't call this in | |||
|
34 | /// multi-threaded context. | |||
|
35 | pub unsafe fn get_umask() -> u32 { | |||
|
36 | let mask = libc::umask(0); | |||
|
37 | libc::umask(mask); | |||
|
38 | mask | |||
|
39 | } | |||
|
40 | ||||
28 | /// Changes the given fd to blocking mode. |
|
41 | /// Changes the given fd to blocking mode. | |
29 | pub fn set_blocking_fd(fd: RawFd) -> io::Result<()> { |
|
42 | pub fn set_blocking_fd(fd: RawFd) -> io::Result<()> { | |
30 | let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) }; |
|
43 | let flags = unsafe { libc::fcntl(fd, libc::F_GETFL) }; |
General Comments 0
You need to be logged in to leave comments.
Login now