summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2015-03-14 04:34:24 +0800
committerCarl Lerche <me@carllerche.com>2015-03-13 16:40:28 -0700
commitc5bc33200c8eb3563784c0e18dc37060049247cd (patch)
tree8715258b03eef8fcc6a62c82582b537ccb219e44
parent386dfd6f4770770b7721e7fa5195b4c993aa3e4b (diff)
downloadnix-c5bc33200c8eb3563784c0e18dc37060049247cd.zip
Amend some files to make it compile on arm-linux-androideabi.
-rw-r--r--nix-test/src/errno.c2
-rw-r--r--src/errno.rs147
-rw-r--r--src/fcntl.rs10
-rw-r--r--src/features.rs2
-rw-r--r--src/lib.rs4
-rw-r--r--src/sched.rs23
-rw-r--r--src/sys/epoll.rs16
-rw-r--r--src/sys/ioctl.rs3
-rw-r--r--src/sys/mman.rs2
-rw-r--r--src/sys/mod.rs8
-rw-r--r--src/sys/socket/consts.rs2
-rw-r--r--src/sys/socket/mod.rs4
-rw-r--r--src/sys/syscall.rs10
-rw-r--r--src/sys/termios.rs61
-rw-r--r--src/unistd.rs6
-rw-r--r--test/test_unistd.rs11
16 files changed, 214 insertions, 97 deletions
diff --git a/nix-test/src/errno.c b/nix-test/src/errno.c
index 9e4817dc..eaf882c8 100644
--- a/nix-test/src/errno.c
+++ b/nix-test/src/errno.c
@@ -142,9 +142,11 @@ assert_errno_eq(const char* err) {
ERRNO_EQ(EKEYREJECTED);
ERRNO_EQ(EOWNERDEAD);
ERRNO_EQ(ENOTRECOVERABLE);
+#ifndef __ANDROID__
ERRNO_EQ(ERFKILL);
ERRNO_EQ(EHWPOISON);
#endif
+#endif
#ifdef DARWIN
ERRNO_EQ(ENOTSUP);
diff --git a/src/errno.rs b/src/errno.rs
index cc6d750e..cb62f442 100644
--- a/src/errno.rs
+++ b/src/errno.rs
@@ -95,184 +95,184 @@ fn desc(errno: Errno) -> &'static str {
EHOSTDOWN => "Host is down",
EHOSTUNREACH => "No route to host",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ECHRNG => "Channel number out of range",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EL2NSYNC => "Level 2 not synchronized",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EL3HLT => "Level 3 halted",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EL3RST => "Level 3 reset",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ELNRNG => "Link number out of range",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EUNATCH => "Protocol driver not attached",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENOCSI => "No CSI structure available",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EL2HLT => "Level 2 halted",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EBADE => "Invalid exchange",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EBADR => "Invalid request descriptor",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EXFULL => "Exchange full",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENOANO => "No anode",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EBADRQC => "Invalid request code",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EBADSLT => "Invalid slot",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EBFONT => "Bad font file format",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENOSTR => "Device not a stream",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENODATA => "No data available",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ETIME => "Timer expired",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENOSR => "Out of streams resources",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENONET => "Machine is not on the network",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENOPKG => "Package not installed",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EREMOTE => "Object is remote",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENOLINK => "Link has been severed",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EADV => "Advertise error",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ESRMNT => "Srmount error",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ECOMM => "Communication error on send",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EPROTO => "Protocol error",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EMULTIHOP => "Multihop attempted",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EDOTDOT => "RFS specific error",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EBADMSG => "Not a data message",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EOVERFLOW => "Value too large for defined data type",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENOTUNIQ => "Name not unique on network",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EBADFD => "File descriptor in bad state",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EREMCHG => "Remote address changed",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ELIBACC => "Can not acces a needed shared library",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ELIBBAD => "Accessing a corrupted shared library",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ELIBSCN => ".lib section in a.out corrupted",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ELIBMAX => "Attempting to link in too many shared libraries",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ELIBEXEC => "Cannot exec a shared library directly",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EILSEQ => "Illegal byte sequence",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ERESTART => "Interrupted system call should be restarted",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ESTRPIPE => "Streams pipe error",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EUSERS => "Too many users",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EOPNOTSUPP => "Operation not supported on transport endpoint",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ESTALE => "Stale file handle",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EUCLEAN => "Structure needs cleaning",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENOTNAM => "Not a XENIX named type file",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENAVAIL => "No XENIX semaphores available",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EISNAM => "Is a named type file",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EREMOTEIO => "Remote I/O error",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EDQUOT => "Quota exceeded",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENOMEDIUM => "No medium found",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EMEDIUMTYPE => "Wrong medium type",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ECANCELED => "Operation canceled",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENOKEY => "Required key not available",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EKEYEXPIRED => "Key has expired",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EKEYREVOKED => "Key has been revoked",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EKEYREJECTED => "Key was rejected by service",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
EOWNERDEAD => "Owner died",
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
ENOTRECOVERABLE => "State not recoverable",
#[cfg(target_os = "linux")]
@@ -394,7 +394,7 @@ fn desc(errno: Errno) -> &'static str {
}
}
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
mod consts {
#[derive(Debug, Clone, PartialEq, FromPrimitive, Copy)]
pub enum Errno {
@@ -528,7 +528,10 @@ mod consts {
EKEYREJECTED = 129,
EOWNERDEAD = 130,
ENOTRECOVERABLE = 131,
+
+ #[cfg(not(target_os = "android"))]
ERFKILL = 132,
+ #[cfg(not(target_os = "android"))]
EHWPOISON = 133,
}
@@ -667,13 +670,8 @@ mod test {
use libc::c_int;
macro_rules! check_errno {
- ($errno:ident) => {{
- assert_errno_eq(stringify!($errno), $errno as c_int);
- }};
-
- ($errno:ident, $($rest:ident),+) => {{
- check_errno!($errno);
- check_errno!($($rest),*);
+ ($($errno:ident),+) => {{
+ $(assert_errno_eq(stringify!($errno), $errno as c_int);)+
}};
}
@@ -754,7 +752,7 @@ mod test {
}
#[test]
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
pub fn test_linux_errnos() {
check_errno!(
ECHRNG,
@@ -816,14 +814,19 @@ mod test {
EKEYREVOKED,
EKEYREJECTED,
EOWNERDEAD,
- ENOTRECOVERABLE,
+ ENOTRECOVERABLE);
+ }
+
+ #[test]
+ #[cfg(target_os = "linux")]
+ pub fn test_linux_not_android_errnos() {
+ check_errno!(
ERFKILL,
EHWPOISON);
}
-
#[test]
- #[cfg(target_os = "macos")]
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
pub fn test_darwin_errnos() {
check_errno!(
ENOTSUP,
diff --git a/src/fcntl.rs b/src/fcntl.rs
index 30a59ed6..0a8236a4 100644
--- a/src/fcntl.rs
+++ b/src/fcntl.rs
@@ -14,7 +14,7 @@ mod ffi {
pub use libc::{open, fcntl};
pub use self::os::*;
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
mod os {
use libc::{c_int, c_short, off_t, pid_t};
@@ -93,11 +93,11 @@ pub enum FcntlArg<'a> {
F_SETLK(&'a flock),
F_SETLKW(&'a flock),
F_GETLK(&'a mut flock),
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
F_OFD_SETLK(&'a flock),
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
F_OFD_SETLKW(&'a flock),
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
F_OFD_GETLK(&'a mut flock)
// TODO: Rest of flags
@@ -122,7 +122,7 @@ pub fn fcntl(fd: Fd, arg: FcntlArg) -> NixResult<()> {
Ok(())
}
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
mod consts {
use libc::c_int;
diff --git a/src/features.rs b/src/features.rs
index cb31c914..60022995 100644
--- a/src/features.rs
+++ b/src/features.rs
@@ -1,6 +1,6 @@
pub use self::os::*;
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
mod os {
use sys::utsname::uname;
diff --git a/src/lib.rs b/src/lib.rs
index 0370cae5..3826b4d7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -32,10 +32,10 @@ pub mod features;
#[cfg(unix)]
pub mod fcntl;
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
pub mod mount;
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
pub mod sched;
#[cfg(unix)]
diff --git a/src/sched.rs b/src/sched.rs
index c8d719ed..0dff3cad 100644
--- a/src/sched.rs
+++ b/src/sched.rs
@@ -29,7 +29,7 @@ pub static CLONE_NEWNET: CloneFlags = 0x40000000;
pub static CLONE_IO: CloneFlags = 0x80000000;
// Support a maximum CPU set of 1024 nodes
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_os = "linux"))]
mod cpuset_attribs {
use super::CpuMask;
pub const CPU_SETSIZE: usize = 1024;
@@ -46,7 +46,7 @@ mod cpuset_attribs {
}
}
-#[cfg(target_arch = "x86")]
+#[cfg(all(target_arch = "x86", target_os = "linux"))]
mod cpuset_attribs {
use super::CpuMask;
pub const CPU_SETSIZE: usize = 1024us;
@@ -63,6 +63,25 @@ mod cpuset_attribs {
}
}
+#[cfg(all(target_arch = "arm", target_os = "android"))]
+mod cpuset_attribs {
+ use super::CpuMask;
+ // bionic only supports up to 32 independent CPUs, instead of 1024.
+ pub const CPU_SETSIZE: usize = 32;
+ pub const CPU_MASK_BITS: usize = 32;
+
+ #[inline]
+ pub fn set_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
+ cur | (1u32 << bit)
+ }
+
+ #[inline]
+ pub fn clear_cpu_mask_flag(cur: CpuMask, bit: usize) -> CpuMask {
+ cur & !(1u32 << bit)
+ }
+}
+
+
pub type CloneCb<'a> = Box<FnMut() -> isize + 'a>;
// A single CPU mask word
diff --git a/src/sys/epoll.rs b/src/sys/epoll.rs
index b9b31c9a..138680fe 100644
--- a/src/sys/epoll.rs
+++ b/src/sys/epoll.rs
@@ -78,6 +78,22 @@ pub enum EpollOp {
EpollCtlMod = 3
}
+#[cfg(all(target_os = "android", not(target_arch = "x86_64")))]
+#[derive(Copy)]
+#[repr(C)]
+pub struct EpollEvent {
+ pub events: EpollEventKind,
+ pub data: u64
+}
+
+#[cfg(all(target_os = "android", not(target_arch = "x86_64")))]
+#[test]
+fn test_epoll_event_size() {
+ use std::mem::size_of;
+ assert_eq!(size_of::<EpollEvent>(), 16);
+}
+
+#[cfg(any(not(target_os = "android"), target_arch = "x86_64"))]
#[derive(Copy)]
#[repr(C, packed)]
pub struct EpollEvent {
diff --git a/src/sys/ioctl.rs b/src/sys/ioctl.rs
index 847733f2..516b29bc 100644
--- a/src/sys/ioctl.rs
+++ b/src/sys/ioctl.rs
@@ -22,7 +22,8 @@ mod ffi {
pub const TIOCGWINSZ: c_ulong = 0x40087468;
}
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux",
+ all(target_os = "android", not(target_arch = "mips"))))]
pub mod os {
use libc::c_int;
pub const TIOCGWINSZ: c_int = 0x5413;
diff --git a/src/sys/mman.rs b/src/sys/mman.rs
index 1b94cc4b..60171a9e 100644
--- a/src/sys/mman.rs
+++ b/src/sys/mman.rs
@@ -6,7 +6,7 @@ use sys::stat::Mode;
pub use self::consts::*;
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
mod consts {
use libc::c_int;
diff --git a/src/sys/mod.rs b/src/sys/mod.rs
index 06688204..c14b02f2 100644
--- a/src/sys/mod.rs
+++ b/src/sys/mod.rs
@@ -1,11 +1,11 @@
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
pub mod epoll;
#[cfg(any(target_os = "macos", target_os = "ios"))]
pub mod event;
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
pub mod eventfd;
#[cfg(not(target_os = "ios"))]
@@ -17,13 +17,13 @@ pub mod socket;
pub mod stat;
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
pub mod syscall;
#[cfg(not(target_os = "ios"))]
pub mod termios;
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
pub mod utsname;
pub mod wait;
diff --git a/src/sys/socket/consts.rs b/src/sys/socket/consts.rs
index 3131cfb8..481f133a 100644
--- a/src/sys/socket/consts.rs
+++ b/src/sys/socket/consts.rs
@@ -1,6 +1,6 @@
pub use self::os::*;
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
mod os {
use libc::{c_int, uint8_t};
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index 6b317dec..0480a020 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -132,7 +132,7 @@ pub fn accept(sockfd: Fd) -> NixResult<Fd> {
/// Accept a connection on a socket
///
/// [Further reading](http://man7.org/linux/man-pages/man2/accept.2.html)
-#[cfg(not(any(target_os = "macos", target_os = "ios")))]
+#[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "android")))]
pub fn accept4(sockfd: Fd, flags: SockFlag) -> NixResult<Fd> {
use libc::sockaddr;
@@ -162,7 +162,7 @@ pub fn accept4(sockfd: Fd, flags: SockFlag) -> NixResult<Fd> {
/// Accept a connection on a socket
///
/// [Further reading](http://man7.org/linux/man-pages/man2/accept.2.html)
-#[cfg(any(target_os = "macos", target_os = "ios"))]
+#[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))]
pub fn accept4(sockfd: Fd, flags: SockFlag) -> NixResult<Fd> {
accept4_polyfill(sockfd, flags)
}
diff --git a/src/sys/syscall.rs b/src/sys/syscall.rs
index cdf6c414..0f6a5e0b 100644
--- a/src/sys/syscall.rs
+++ b/src/sys/syscall.rs
@@ -22,6 +22,16 @@ mod arch {
pub static SYSPIVOTROOT: Syscall = 217;
}
+#[cfg(target_arch = "arm")]
+mod arch {
+ use libc::c_long;
+
+ pub type Syscall = c_long;
+
+ pub static SYSPIVOTROOT: Syscall = 218;
+}
+
+
extern {
pub fn syscall(num: Syscall, ...) -> c_int;
}
diff --git a/src/sys/termios.rs b/src/sys/termios.rs
index 56beca2e..7ef2ca57 100644
--- a/src/sys/termios.rs
+++ b/src/sys/termios.rs
@@ -17,6 +17,7 @@ mod ffi {
// `Termios` contains bitflags which are not considered
// `foreign-function-safe` by the compiler.
#[allow(improper_ctypes)]
+ #[cfg(any(target_os = "macos", target_os = "linux"))]
extern {
pub fn cfgetispeed(termios: *const Termios) -> speed_t;
pub fn cfgetospeed(termios: *const Termios) -> speed_t;
@@ -32,6 +33,62 @@ mod ffi {
pub fn tcsendbreak(fd: c_int, duration: c_int) -> c_int;
}
+ // On Android before 5.0, Bionic directly inline these to ioctl() calls.
+ #[inline]
+ #[cfg(all(target_os = "android", not(target_arch = "mips")))]
+ mod android {
+ use libc::funcs::bsd44::ioctl;
+ use libc::c_int;
+ use super::consts::*;
+
+ const TCGETS: c_int = 0x5401;
+ const TCSBRK: c_int = 0x5409;
+ const TCXONC: c_int = 0x540a;
+ const TCFLSH: c_int = 0x540b;
+ const TCSBRKP: c_int = 0x5425;
+
+ pub unsafe fn cfgetispeed(termios: *const Termios) -> speed_t {
+ ((*termios).c_cflag & CBAUD).bits() as speed_t
+ }
+ pub unsafe fn cfgetospeed(termios: *const Termios) -> speed_t {
+ ((*termios).c_cflag & CBAUD).bits() as speed_t
+ }
+ pub unsafe fn cfsetispeed(termios: *mut Termios, speed: speed_t) -> c_int {
+ (*termios).c_cflag.remove(CBAUD);
+ (*termios).c_cflag.insert(ControlFlags::from_bits_truncate(speed) & CBAUD);
+ 0
+ }
+ pub unsafe fn cfsetospeed(termios: *mut Termios, speed: speed_t) -> c_int {
+ (*termios).c_cflag.remove(CBAUD);
+ (*termios).c_cflag.insert(ControlFlags::from_bits_truncate(speed) & CBAUD);
+ 0
+ }
+ pub unsafe fn tcgetattr(fd: c_int, termios: *mut Termios) -> c_int {
+ ioctl(fd, TCGETS, termios)
+ }
+ pub unsafe fn tcsetattr(fd: c_int,
+ optional_actions: c_int,
+ termios: *const Termios) -> c_int {
+ ioctl(fd, optional_actions, termios)
+ }
+ pub unsafe fn tcdrain(fd: c_int) -> c_int {
+ ioctl(fd, TCSBRK, 1)
+ }
+ pub unsafe fn tcflow(fd: c_int, action: c_int) -> c_int {
+ ioctl(fd, TCXONC, action)
+ }
+ pub unsafe fn tcflush(fd: c_int, action: c_int) -> c_int {
+ ioctl(fd, TCFLSH, action)
+ }
+ pub unsafe fn tcsendbreak(fd: c_int, duration: c_int) -> c_int {
+ ioctl(fd, TCSBRKP, duration)
+ }
+ }
+
+ #[cfg(target_os = "android")]
+ pub use self::android::*;
+
+
#[cfg(target_os = "macos")]
pub mod consts {
use libc::{c_int, c_ulong, c_uchar};
@@ -198,7 +255,7 @@ mod ffi {
}
}
- #[cfg(target_os = "linux")]
+ #[cfg(any(target_os = "linux", target_os = "android"))]
pub mod consts {
use libc::{c_int, c_uint, c_uchar};
@@ -277,6 +334,8 @@ mod ffi {
const HUPCL = 0x00000400,
const CLOCAL = 0x00000800,
const CRTSCTS = 0x80000000,
+ #[cfg(target_os = "android")]
+ const CBAUD = 0o0010017,
}
}
diff --git a/src/unistd.rs b/src/unistd.rs
index a54bba3a..d07a170a 100644
--- a/src/unistd.rs
+++ b/src/unistd.rs
@@ -8,7 +8,7 @@ use libc::{c_char, c_void, c_int, size_t, pid_t, off_t};
use std::{mem, ptr};
use std::ffi::CString;
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
pub use self::linux::*;
mod ffi {
@@ -245,7 +245,7 @@ pub fn pipe() -> NixResult<(Fd, Fd)> {
}
}
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn pipe2(flags: OFlag) -> NixResult<(Fd, Fd)> {
type F = unsafe extern "C" fn(fds: *mut c_int, flags: c_int) -> c_int;
@@ -354,7 +354,7 @@ pub fn unlink<P: ?Sized + NixPath>(path: &P) -> NixResult<()> {
from_ffi(res)
}
-#[cfg(target_os = "linux")]
+#[cfg(any(target_os = "linux", target_os = "android"))]
mod linux {
use sys::syscall::{syscall, SYSPIVOTROOT};
use errno::Errno;
diff --git a/test/test_unistd.rs b/test/test_unistd.rs
index c648cdeb..d457c668 100644
--- a/test/test_unistd.rs
+++ b/test/test_unistd.rs
@@ -29,6 +29,7 @@ fn test_fork_and_waitpid() {
}
}
+
#[test]
fn test_execve() {
// The `exec`d process will write to `writer`, and we'll read that
@@ -37,15 +38,21 @@ fn test_execve() {
match fork().unwrap() {
Child => {
+ #[cfg(not(target_os = "android"))]
+ const SH_PATH: &'static [u8] = b"/bin/sh";
+
+ #[cfg(target_os = "android")]
+ const SH_PATH: &'static [u8] = b"/system/bin/sh";
+
// Close stdout.
close(1).unwrap();
// Make `writer` be the stdout of the new process.
dup(writer).unwrap();
// exec!
- execve(&CString::new(b"/bin/sh").unwrap(),
+ execve(&CString::new(SH_PATH).unwrap(),
&[CString::new(b"").unwrap(),
CString::new(b"-c").unwrap(),
- CString::new(b"echo nix!!! && env").unwrap()],
+ CString::new(b"echo nix!!! && echo foo=$foo && echo baz=$baz").unwrap()],
&[CString::new(b"foo=bar").unwrap(),
CString::new(b"baz=quux").unwrap()]).unwrap();
},