diff options
author | kennytm <kennytm@gmail.com> | 2015-03-14 04:34:24 +0800 |
---|---|---|
committer | Carl Lerche <me@carllerche.com> | 2015-03-13 16:40:28 -0700 |
commit | c5bc33200c8eb3563784c0e18dc37060049247cd (patch) | |
tree | 8715258b03eef8fcc6a62c82582b537ccb219e44 | |
parent | 386dfd6f4770770b7721e7fa5195b4c993aa3e4b (diff) | |
download | nix-c5bc33200c8eb3563784c0e18dc37060049247cd.zip |
Amend some files to make it compile on arm-linux-androideabi.
-rw-r--r-- | nix-test/src/errno.c | 2 | ||||
-rw-r--r-- | src/errno.rs | 147 | ||||
-rw-r--r-- | src/fcntl.rs | 10 | ||||
-rw-r--r-- | src/features.rs | 2 | ||||
-rw-r--r-- | src/lib.rs | 4 | ||||
-rw-r--r-- | src/sched.rs | 23 | ||||
-rw-r--r-- | src/sys/epoll.rs | 16 | ||||
-rw-r--r-- | src/sys/ioctl.rs | 3 | ||||
-rw-r--r-- | src/sys/mman.rs | 2 | ||||
-rw-r--r-- | src/sys/mod.rs | 8 | ||||
-rw-r--r-- | src/sys/socket/consts.rs | 2 | ||||
-rw-r--r-- | src/sys/socket/mod.rs | 4 | ||||
-rw-r--r-- | src/sys/syscall.rs | 10 | ||||
-rw-r--r-- | src/sys/termios.rs | 61 | ||||
-rw-r--r-- | src/unistd.rs | 6 | ||||
-rw-r--r-- | test/test_unistd.rs | 11 |
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; @@ -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(); }, |