diff options
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/unix/ext/io.rs | 15 | ||||
| -rw-r--r-- | src/libstd/sys/unix/ext/net.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/unix/process/process_common.rs | 16 | ||||
| -rw-r--r-- | src/libstd/sys/unix/process/process_unix.rs | 11 | ||||
| -rw-r--r-- | src/libstd/sys/windows/process.rs | 9 | ||||
| -rw-r--r-- | src/libstd/sys/windows/stdio.rs | 92 |
6 files changed, 88 insertions, 59 deletions
diff --git a/src/libstd/sys/unix/ext/io.rs b/src/libstd/sys/unix/ext/io.rs index 296235e173d..75aa72e3cff 100644 --- a/src/libstd/sys/unix/ext/io.rs +++ b/src/libstd/sys/unix/ext/io.rs @@ -73,6 +73,13 @@ pub trait IntoRawFd { } #[stable(feature = "rust1", since = "1.0.0")] +impl AsRawFd for RawFd { + fn as_raw_fd(&self) -> RawFd { + *self + } +} + +#[stable(feature = "rust1", since = "1.0.0")] impl AsRawFd for fs::File { fn as_raw_fd(&self) -> RawFd { self.as_inner().fd().raw() @@ -84,6 +91,14 @@ impl FromRawFd for fs::File { fs::File::from_inner(sys::fs::File::from_inner(fd)) } } + +#[stable(feature = "into_raw_os", since = "1.4.0")] +impl IntoRawFd for RawFd { + fn into_raw_fd(self) -> RawFd { + self + } +} + #[stable(feature = "into_raw_os", since = "1.4.0")] impl IntoRawFd for fs::File { fn into_raw_fd(self) -> RawFd { diff --git a/src/libstd/sys/unix/ext/net.rs b/src/libstd/sys/unix/ext/net.rs index 55118829eee..d688f2fa504 100644 --- a/src/libstd/sys/unix/ext/net.rs +++ b/src/libstd/sys/unix/ext/net.rs @@ -641,7 +641,7 @@ impl UnixListener { let inner = Socket::new_raw(libc::AF_UNIX, libc::SOCK_STREAM)?; let (addr, len) = sockaddr_un(path)?; - cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len))?; + cvt(libc::bind(*inner.as_inner(), &addr as *const _ as *const _, len as _))?; cvt(libc::listen(*inner.as_inner(), 128))?; Ok(UnixListener(inner)) @@ -920,7 +920,7 @@ impl UnixDatagram { let socket = UnixDatagram::unbound()?; let (addr, len) = sockaddr_un(path)?; - cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len))?; + cvt(libc::bind(*socket.0.as_inner(), &addr as *const _ as *const _, len as _))?; Ok(socket) } diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 5f1a6c2f746..e9f41009064 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -417,13 +417,27 @@ mod tests { } } + // Android with api less than 21 define sig* functions inline, so it is not + // available for dynamic link. Implementing sigemptyset and sigaddset allow us + // to support older Android version (independent of libc version). + // The following implementations are based on https://git.io/vSkNf + #[cfg(not(target_os = "android"))] extern { + #[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")] + fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int; + #[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")] fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int; } #[cfg(target_os = "android")] + unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int { + libc::memset(set as *mut _, 0, mem::size_of::<libc::sigset_t>()); + return 0; + } + + #[cfg(target_os = "android")] unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int { use slice; @@ -450,7 +464,7 @@ mod tests { let mut set: libc::sigset_t = mem::uninitialized(); let mut old_set: libc::sigset_t = mem::uninitialized(); - t!(cvt(libc::sigemptyset(&mut set))); + t!(cvt(sigemptyset(&mut set))); t!(cvt(sigaddset(&mut set, libc::SIGINT))); t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, &mut old_set))); diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index a213273aac8..edd322ca6fa 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -193,7 +193,16 @@ impl Command { // need to clean things up now to avoid confusing the program // we're about to run. let mut set: libc::sigset_t = mem::uninitialized(); - t!(cvt(libc::sigemptyset(&mut set))); + if cfg!(target_os = "android") { + // Implementing sigemptyset allow us to support older Android + // versions. See the comment about Android and sig* functions in + // process_common.rs + libc::memset(&mut set as *mut _ as *mut _, + 0, + mem::size_of::<libc::sigset_t>()); + } else { + t!(cvt(libc::sigemptyset(&mut set))); + } t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, ptr::null_mut()))); let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL); diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs index 1afb3728c9d..dfbc1b581ee 100644 --- a/src/libstd/sys/windows/process.rs +++ b/src/libstd/sys/windows/process.rs @@ -257,8 +257,13 @@ impl Stdio { // INVALID_HANDLE_VALUE. Stdio::Inherit => { match stdio::get(stdio_id) { - Ok(io) => io.handle().duplicate(0, true, - c::DUPLICATE_SAME_ACCESS), + Ok(io) => { + let io = Handle::new(io.handle()); + let ret = io.duplicate(0, true, + c::DUPLICATE_SAME_ACCESS); + io.into_raw(); + return ret + } Err(..) => Ok(Handle::new(c::INVALID_HANDLE_VALUE)), } } diff --git a/src/libstd/sys/windows/stdio.rs b/src/libstd/sys/windows/stdio.rs index b1a57c349fb..d72e4b4438b 100644 --- a/src/libstd/sys/windows/stdio.rs +++ b/src/libstd/sys/windows/stdio.rs @@ -22,42 +22,43 @@ use sys::cvt; use sys::handle::Handle; use sys_common::io::read_to_end_uninitialized; -pub struct NoClose(Option<Handle>); - pub enum Output { - Console(NoClose), - Pipe(NoClose), + Console(c::HANDLE), + Pipe(c::HANDLE), } pub struct Stdin { - handle: Output, utf8: Mutex<io::Cursor<Vec<u8>>>, } -pub struct Stdout(Output); -pub struct Stderr(Output); +pub struct Stdout; +pub struct Stderr; pub fn get(handle: c::DWORD) -> io::Result<Output> { let handle = unsafe { c::GetStdHandle(handle) }; if handle == c::INVALID_HANDLE_VALUE { Err(io::Error::last_os_error()) } else if handle.is_null() { - Err(io::Error::new(io::ErrorKind::Other, - "no stdio handle available for this process")) + Err(io::Error::from_raw_os_error(c::ERROR_INVALID_HANDLE as i32)) } else { - let ret = NoClose::new(handle); let mut out = 0; match unsafe { c::GetConsoleMode(handle, &mut out) } { - 0 => Ok(Output::Pipe(ret)), - _ => Ok(Output::Console(ret)), + 0 => Ok(Output::Pipe(handle)), + _ => Ok(Output::Console(handle)), } } } -fn write(out: &Output, data: &[u8]) -> io::Result<usize> { - let handle = match *out { - Output::Console(ref c) => c.get().raw(), - Output::Pipe(ref p) => return p.get().write(data), +fn write(handle: c::DWORD, data: &[u8]) -> io::Result<usize> { + let handle = match try!(get(handle)) { + Output::Console(c) => c, + Output::Pipe(p) => { + let handle = Handle::new(p); + let ret = handle.write(data); + handle.into_raw(); + return ret + } }; + // As with stdin on windows, stdout often can't handle writes of large // sizes. For an example, see #14940. For this reason, don't try to // write the entire output buffer on windows. @@ -93,18 +94,20 @@ fn write(out: &Output, data: &[u8]) -> io::Result<usize> { impl Stdin { pub fn new() -> io::Result<Stdin> { - get(c::STD_INPUT_HANDLE).map(|handle| { - Stdin { - handle: handle, - utf8: Mutex::new(Cursor::new(Vec::new())), - } + Ok(Stdin { + utf8: Mutex::new(Cursor::new(Vec::new())), }) } pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - let handle = match self.handle { - Output::Console(ref c) => c.get().raw(), - Output::Pipe(ref p) => return p.get().read(buf), + let handle = match try!(get(c::STD_INPUT_HANDLE)) { + Output::Console(c) => c, + Output::Pipe(p) => { + let handle = Handle::new(p); + let ret = handle.read(buf); + handle.into_raw(); + return ret + } }; let mut utf8 = self.utf8.lock().unwrap(); // Read more if the buffer is empty @@ -125,11 +128,9 @@ impl Stdin { Ok(utf8) => utf8.into_bytes(), Err(..) => return Err(invalid_encoding()), }; - if let Output::Console(_) = self.handle { - if let Some(&last_byte) = data.last() { - if last_byte == CTRL_Z { - data.pop(); - } + if let Some(&last_byte) = data.last() { + if last_byte == CTRL_Z { + data.pop(); } } *utf8 = Cursor::new(data); @@ -158,11 +159,11 @@ impl<'a> Read for &'a Stdin { impl Stdout { pub fn new() -> io::Result<Stdout> { - get(c::STD_OUTPUT_HANDLE).map(Stdout) + Ok(Stdout) } pub fn write(&self, data: &[u8]) -> io::Result<usize> { - write(&self.0, data) + write(c::STD_OUTPUT_HANDLE, data) } pub fn flush(&self) -> io::Result<()> { @@ -172,11 +173,11 @@ impl Stdout { impl Stderr { pub fn new() -> io::Result<Stderr> { - get(c::STD_ERROR_HANDLE).map(Stderr) + Ok(Stderr) } pub fn write(&self, data: &[u8]) -> io::Result<usize> { - write(&self.0, data) + write(c::STD_ERROR_HANDLE, data) } pub fn flush(&self) -> io::Result<()> { @@ -197,27 +198,12 @@ impl io::Write for Stderr { } } -impl NoClose { - fn new(handle: c::HANDLE) -> NoClose { - NoClose(Some(Handle::new(handle))) - } - - fn get(&self) -> &Handle { self.0.as_ref().unwrap() } -} - -impl Drop for NoClose { - fn drop(&mut self) { - self.0.take().unwrap().into_raw(); - } -} - impl Output { - pub fn handle(&self) -> &Handle { - let nc = match *self { - Output::Console(ref c) => c, - Output::Pipe(ref c) => c, - }; - nc.0.as_ref().unwrap() + pub fn handle(&self) -> c::HANDLE { + match *self { + Output::Console(c) => c, + Output::Pipe(c) => c, + } } } |
