diff options
| author | Jeremy Soller <jackpot51@gmail.com> | 2016-11-23 08:21:15 -0700 |
|---|---|---|
| committer | Jeremy Soller <jackpot51@gmail.com> | 2016-11-23 08:21:15 -0700 |
| commit | b3c91dfb6a2e21c82966d0a13f9cd3e51da94654 (patch) | |
| tree | 08bb76f6d05c6295b9ee7c3690b78a9ff52c7693 /src/libstd/sys | |
| parent | ae2029fc62d744e252a5a077ce0dfbf2d1683d25 (diff) | |
| parent | 9fba8df2115141173ad60837f129f18e74424531 (diff) | |
| download | rust-b3c91dfb6a2e21c82966d0a13f9cd3e51da94654.tar.gz rust-b3c91dfb6a2e21c82966d0a13f9cd3e51da94654.zip | |
Merge branch 'master' into redox
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/unix/fs.rs | 5 | ||||
| -rw-r--r-- | src/libstd/sys/windows/c.rs | 10 | ||||
| -rw-r--r-- | src/libstd/sys/windows/fs.rs | 18 | ||||
| -rw-r--r-- | src/libstd/sys/windows/pipe.rs | 33 |
4 files changed, 58 insertions, 8 deletions
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 0b43fd2ac8c..9ee0458b5da 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -526,6 +526,11 @@ impl File { pub fn fd(&self) -> &FileDesc { &self.0 } pub fn into_fd(self) -> FileDesc { self.0 } + + pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> { + cvt_r(|| unsafe { libc::fchmod(self.0.raw(), perm.mode) })?; + Ok(()) + } } impl DirBuilder { diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs index ce563dc7b16..1a563127f7f 100644 --- a/src/libstd/sys/windows/c.rs +++ b/src/libstd/sys/windows/c.rs @@ -182,6 +182,7 @@ pub const ERROR_INVALID_HANDLE: DWORD = 6; pub const ERROR_NO_MORE_FILES: DWORD = 18; pub const ERROR_HANDLE_EOF: DWORD = 38; pub const ERROR_FILE_EXISTS: DWORD = 80; +pub const ERROR_INVALID_PARAMETER: DWORD = 87; pub const ERROR_BROKEN_PIPE: DWORD = 109; pub const ERROR_CALL_NOT_IMPLEMENTED: DWORD = 120; pub const ERROR_INSUFFICIENT_BUFFER: DWORD = 122; @@ -389,6 +390,15 @@ pub enum FILE_INFO_BY_HANDLE_CLASS { } #[repr(C)] +pub struct FILE_BASIC_INFO { + pub CreationTime: LARGE_INTEGER, + pub LastAccessTime: LARGE_INTEGER, + pub LastWriteTime: LARGE_INTEGER, + pub ChangeTime: LARGE_INTEGER, + pub FileAttributes: DWORD, +} + +#[repr(C)] pub struct FILE_END_OF_FILE_INFO { pub EndOfFile: LARGE_INTEGER, } diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 98fd15f863b..7d7d78bbd87 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -417,6 +417,24 @@ impl File { Ok(PathBuf::from(OsString::from_wide(subst))) } } + + pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> { + let mut info = c::FILE_BASIC_INFO { + CreationTime: 0, + LastAccessTime: 0, + LastWriteTime: 0, + ChangeTime: 0, + FileAttributes: perm.attrs, + }; + let size = mem::size_of_val(&info); + cvt(unsafe { + c::SetFileInformationByHandle(self.handle.raw(), + c::FileBasicInfo, + &mut info as *mut _ as *mut _, + size as c::DWORD) + })?; + Ok(()) + } } impl FromInner<c::HANDLE> for File { diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index ed7e88e72cd..1eb17305476 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -43,6 +43,7 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { let reader; let mut name; let mut tries = 0; + let mut reject_remote_clients_flag = c::PIPE_REJECT_REMOTE_CLIENTS; loop { tries += 1; let key: u64 = rand::thread_rng().gen(); @@ -56,12 +57,12 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { let handle = c::CreateNamedPipeW(wide_name.as_ptr(), c::PIPE_ACCESS_INBOUND | - c::FILE_FLAG_FIRST_PIPE_INSTANCE | - c::FILE_FLAG_OVERLAPPED, + c::FILE_FLAG_FIRST_PIPE_INSTANCE | + c::FILE_FLAG_OVERLAPPED, c::PIPE_TYPE_BYTE | - c::PIPE_READMODE_BYTE | - c::PIPE_WAIT | - c::PIPE_REJECT_REMOTE_CLIENTS, + c::PIPE_READMODE_BYTE | + c::PIPE_WAIT | + reject_remote_clients_flag, 1, 4096, 4096, @@ -76,11 +77,27 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> { // // Don't try again too much though as this could also perhaps be a // legit error. + // If ERROR_INVALID_PARAMETER is returned, this probably means we're + // running on pre-Vista version where PIPE_REJECT_REMOTE_CLIENTS is + // not supported, so we continue retrying without it. This implies + // reduced security on Windows versions older than Vista by allowing + // connections to this pipe from remote machines. + // Proper fix would increase the number of FFI imports and introduce + // significant amount of Windows XP specific code with no clean + // testing strategy + // for more info see https://github.com/rust-lang/rust/pull/37677 if handle == c::INVALID_HANDLE_VALUE { let err = io::Error::last_os_error(); - if tries < 10 && - err.raw_os_error() == Some(c::ERROR_ACCESS_DENIED as i32) { - continue + let raw_os_err = err.raw_os_error(); + if tries < 10 { + if raw_os_err == Some(c::ERROR_ACCESS_DENIED as i32) { + continue + } else if reject_remote_clients_flag != 0 && + raw_os_err == Some(c::ERROR_INVALID_PARAMETER as i32) { + reject_remote_clients_flag = 0; + tries -= 1; + continue + } } return Err(err) } |
