diff options
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/ascii.rs | 24 | ||||
| -rw-r--r-- | src/libstd/os/raw.rs | 10 | ||||
| -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 | ||||
| -rw-r--r-- | src/libstd/sys_common/net.rs | 4 |
8 files changed, 96 insertions, 74 deletions
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index af21d6d906e..1cac11f668d 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -17,7 +17,7 @@ use mem; use ops::Range; use iter::FusedIterator; -/// Extension methods for ASCII-subset only operations on string slices. +/// Extension methods for ASCII-subset only operations. /// /// Be aware that operations on seemingly non-ASCII characters can sometimes /// have unexpected results. Consider this example: @@ -54,19 +54,21 @@ pub trait AsciiExt { /// /// let ascii = 'a'; /// let utf8 = '❤'; + /// let int_ascii = 97; /// /// assert!(ascii.is_ascii()); /// assert!(!utf8.is_ascii()); + /// assert!(int_ascii.is_ascii()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] fn is_ascii(&self) -> bool; - /// Makes a copy of the string in ASCII upper case. + /// Makes a copy of the value in its ASCII upper case equivalent. /// /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', /// but non-ASCII letters are unchanged. /// - /// To uppercase the string in-place, use [`make_ascii_uppercase`]. + /// To uppercase the value in-place, use [`make_ascii_uppercase`]. /// /// To uppercase ASCII characters in addition to non-ASCII characters, use /// [`str::to_uppercase`]. @@ -78,9 +80,11 @@ pub trait AsciiExt { /// /// let ascii = 'a'; /// let utf8 = '❤'; + /// let int_ascii = 97; /// /// assert_eq!('A', ascii.to_ascii_uppercase()); /// assert_eq!('❤', utf8.to_ascii_uppercase()); + /// assert_eq!(65, int_ascii.to_ascii_uppercase()); /// ``` /// /// [`make_ascii_uppercase`]: #tymethod.make_ascii_uppercase @@ -88,12 +92,12 @@ pub trait AsciiExt { #[stable(feature = "rust1", since = "1.0.0")] fn to_ascii_uppercase(&self) -> Self::Owned; - /// Makes a copy of the string in ASCII lower case. + /// Makes a copy of the value in its ASCII lower case equivalent. /// /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z', /// but non-ASCII letters are unchanged. /// - /// To lowercase the string in-place, use [`make_ascii_lowercase`]. + /// To lowercase the value in-place, use [`make_ascii_lowercase`]. /// /// To lowercase ASCII characters in addition to non-ASCII characters, use /// [`str::to_lowercase`]. @@ -105,9 +109,11 @@ pub trait AsciiExt { /// /// let ascii = 'A'; /// let utf8 = '❤'; + /// let int_ascii = 65; /// /// assert_eq!('a', ascii.to_ascii_lowercase()); /// assert_eq!('❤', utf8.to_ascii_lowercase()); + /// assert_eq!(97, int_ascii.to_ascii_lowercase()); /// ``` /// /// [`make_ascii_lowercase`]: #tymethod.make_ascii_lowercase @@ -115,10 +121,10 @@ pub trait AsciiExt { #[stable(feature = "rust1", since = "1.0.0")] fn to_ascii_lowercase(&self) -> Self::Owned; - /// Checks that two strings are an ASCII case-insensitive match. + /// Checks that two values are an ASCII case-insensitive match. /// /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`, - /// but without allocating and copying temporary strings. + /// but without allocating and copying temporaries. /// /// # Examples /// @@ -142,7 +148,7 @@ pub trait AsciiExt { /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', /// but non-ASCII letters are unchanged. /// - /// To return a new uppercased string without modifying the existing one, use + /// To return a new uppercased value without modifying the existing one, use /// [`to_ascii_uppercase`]. /// /// # Examples @@ -166,7 +172,7 @@ pub trait AsciiExt { /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z', /// but non-ASCII letters are unchanged. /// - /// To return a new lowercased string without modifying the existing one, use + /// To return a new lowercased value without modifying the existing one, use /// [`to_ascii_lowercase`]. /// /// # Examples diff --git a/src/libstd/os/raw.rs b/src/libstd/os/raw.rs index 68d4ca90019..c34491941d6 100644 --- a/src/libstd/os/raw.rs +++ b/src/libstd/os/raw.rs @@ -14,22 +14,24 @@ use fmt; -#[cfg(any(target_os = "android", - target_os = "emscripten", +#[cfg(any(target_os = "emscripten", all(target_os = "linux", any(target_arch = "aarch64", target_arch = "arm", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "s390x")), + all(target_os = "android", any(target_arch = "aarch64", + target_arch = "arm")), all(target_os = "fuchsia", target_arch = "aarch64")))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8; -#[cfg(not(any(target_os = "android", - target_os = "emscripten", +#[cfg(not(any(target_os = "emscripten", all(target_os = "linux", any(target_arch = "aarch64", target_arch = "arm", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "s390x")), + all(target_os = "android", any(target_arch = "aarch64", + target_arch = "arm")), all(target_os = "fuchsia", target_arch = "aarch64"))))] #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8; #[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8; 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, + } } } diff --git a/src/libstd/sys_common/net.rs b/src/libstd/sys_common/net.rs index 3cdeb511945..9239c18e597 100644 --- a/src/libstd/sys_common/net.rs +++ b/src/libstd/sys_common/net.rs @@ -339,7 +339,7 @@ impl TcpListener { // Bind our new socket let (addrp, len) = addr.into_inner(); - cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) })?; + cvt(unsafe { c::bind(*sock.as_inner(), addrp, len as _) })?; // Start listening cvt(unsafe { c::listen(*sock.as_inner(), 128) })?; @@ -430,7 +430,7 @@ impl UdpSocket { let sock = Socket::new(addr, c::SOCK_DGRAM)?; let (addrp, len) = addr.into_inner(); - cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) })?; + cvt(unsafe { c::bind(*sock.as_inner(), addrp, len as _) })?; Ok(UdpSocket { inner: sock }) } |
