Skip to content

Commit 15fe7ed

Browse files
committed
Android support
AOSP has vsock support via the cuttlefish hypervisor Signed-off-by: Dustin Thomson <[email protected]>
1 parent 5d1d5dc commit 15fe7ed

File tree

4 files changed

+31
-25
lines changed

4 files changed

+31
-25
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ async-trait = { version = "0.1.31", optional = true }
2222
tokio = { version = "1", features = ["rt", "sync", "io-util", "macros", "time"], optional = true }
2323
futures = { version = "0.3", optional = true }
2424

25-
[target.'cfg(target_os = "linux")'.dependencies]
25+
[target.'cfg(any(target_os = "linux", target_os = "android"))'.dependencies]
2626
tokio-vsock = { version = "0.3.1", optional = true }
2727

2828
[build-dependencies]

src/asynchronous/server.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use tokio::{
2727
task,
2828
time::timeout,
2929
};
30-
#[cfg(target_os = "linux")]
30+
#[cfg(any(target_os = "linux", target_os = "android"))]
3131
use tokio_vsock::VsockListener;
3232

3333
use crate::asynchronous::unix_incoming::UnixIncoming;
@@ -111,7 +111,7 @@ impl Server {
111111
self
112112
}
113113

114-
#[cfg(target_os = "linux")]
114+
#[cfg(any(target_os = "linux", target_os = "android"))]
115115
pub fn set_domain_vsock(mut self) -> Self {
116116
self.domain = Some(Domain::Vsock);
117117
self
@@ -157,7 +157,7 @@ impl Server {
157157

158158
self.do_start(incoming).await
159159
}
160-
#[cfg(target_os = "linux")]
160+
#[cfg(any(target_os = "linux", target_os = "android"))]
161161
Some(Domain::Vsock) => {
162162
let incoming = unsafe { VsockListener::from_raw_fd(listenfd).incoming() };
163163
self.do_start(incoming).await

src/common.rs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
//! Common functions and macros.
77
88
use crate::error::{Error, Result};
9-
#[cfg(any(feature = "async", not(target_os = "linux")))]
9+
#[cfg(any(
10+
feature = "async",
11+
not(any(target_os = "linux", target_os = "android"))
12+
))]
1013
use nix::fcntl::FdFlag;
1114
use nix::fcntl::{fcntl, FcntlArg, OFlag};
1215
use nix::sys::socket::*;
@@ -15,7 +18,7 @@ use std::os::unix::io::RawFd;
1518
#[derive(Debug, Clone, Copy, PartialEq)]
1619
pub(crate) enum Domain {
1720
Unix,
18-
#[cfg(target_os = "linux")]
21+
#[cfg(any(target_os = "linux", target_os = "android"))]
1922
Vsock,
2023
}
2124

@@ -30,7 +33,7 @@ pub(crate) fn do_listen(listener: RawFd) -> Result<()> {
3033
listen(listener, 10).map_err(|e| Error::Socket(e.to_string()))
3134
}
3235

33-
#[cfg(target_os = "linux")]
36+
#[cfg(any(target_os = "linux", target_os = "android"))]
3437
fn parse_sockaddr(addr: &str) -> Result<(Domain, &str)> {
3538
if let Some(addr) = addr.strip_prefix("unix://") {
3639
return Ok((Domain::Unix, addr));
@@ -43,7 +46,7 @@ fn parse_sockaddr(addr: &str) -> Result<(Domain, &str)> {
4346
Err(Error::Others(format!("Scheme {:?} is not supported", addr)))
4447
}
4548

46-
#[cfg(not(target_os = "linux"))]
49+
#[cfg(not(any(target_os = "linux", target_os = "android")))]
4750
fn parse_sockaddr(addr: &str) -> Result<(Domain, &str)> {
4851
if let Some(addr) = addr.strip_prefix("unix://") {
4952
if addr.starts_with('@') {
@@ -57,7 +60,10 @@ fn parse_sockaddr(addr: &str) -> Result<(Domain, &str)> {
5760
Err(Error::Others(format!("Scheme {:?} is not supported", addr)))
5861
}
5962

60-
#[cfg(any(feature = "async", not(target_os = "linux")))]
63+
#[cfg(any(
64+
feature = "async",
65+
not(any(target_os = "linux", target_os = "android"))
66+
))]
6167
pub(crate) fn set_fd_close_exec(fd: RawFd) -> Result<RawFd> {
6268
if let Err(e) = fcntl(fd, FcntlArg::F_SETFD(FdFlag::FD_CLOEXEC)) {
6369
return Err(Error::Others(format!(
@@ -69,12 +75,12 @@ pub(crate) fn set_fd_close_exec(fd: RawFd) -> Result<RawFd> {
6975
}
7076

7177
// SOCK_CLOEXEC flag is Linux specific
72-
#[cfg(target_os = "linux")]
78+
#[cfg(any(target_os = "linux", target_os = "android"))]
7379
pub(crate) const SOCK_CLOEXEC: SockFlag = SockFlag::SOCK_CLOEXEC;
74-
#[cfg(not(target_os = "linux"))]
80+
#[cfg(not(any(target_os = "linux", target_os = "android")))]
7581
pub(crate) const SOCK_CLOEXEC: SockFlag = SockFlag::empty();
7682

77-
#[cfg(target_os = "linux")]
83+
#[cfg(any(target_os = "linux", target_os = "android"))]
7884
fn make_addr(domain: Domain, sockaddr: &str) -> Result<UnixAddr> {
7985
match domain {
8086
Domain::Unix => {
@@ -90,7 +96,7 @@ fn make_addr(domain: Domain, sockaddr: &str) -> Result<UnixAddr> {
9096
}
9197
}
9298

93-
#[cfg(not(target_os = "linux"))]
99+
#[cfg(not(any(target_os = "linux", target_os = "android")))]
94100
fn make_addr(_domain: Domain, sockaddr: &str) -> Result<UnixAddr> {
95101
UnixAddr::new(sockaddr).map_err(err_to_others_err!(e, ""))
96102
}
@@ -114,7 +120,7 @@ fn make_socket(addr: (&str, u32)) -> Result<(RawFd, Domain, SockAddr)> {
114120

115121
let (fd, sockaddr) = match domain {
116122
Domain::Unix => get_sock_addr(domain, sockaddrv)?,
117-
#[cfg(target_os = "linux")]
123+
#[cfg(any(target_os = "linux", target_os = "android"))]
118124
Domain::Vsock => {
119125
let sockaddr_port_v: Vec<&str> = sockaddrv.split(':').collect();
120126
if sockaddr_port_v.len() != 2 {
@@ -143,13 +149,13 @@ fn make_socket(addr: (&str, u32)) -> Result<(RawFd, Domain, SockAddr)> {
143149
}
144150

145151
// Vsock is not supported on non Linux.
146-
#[cfg(target_os = "linux")]
152+
#[cfg(any(target_os = "linux", target_os = "android"))]
147153
use libc::VMADDR_CID_ANY;
148-
#[cfg(not(target_os = "linux"))]
154+
#[cfg(not(any(target_os = "linux", target_os = "android")))]
149155
const VMADDR_CID_ANY: u32 = 0;
150-
#[cfg(target_os = "linux")]
156+
#[cfg(any(target_os = "linux", target_os = "android"))]
151157
use libc::VMADDR_CID_HOST;
152-
#[cfg(not(target_os = "linux"))]
158+
#[cfg(not(any(target_os = "linux", target_os = "android")))]
153159
const VMADDR_CID_HOST: u32 = 0;
154160

155161
pub(crate) fn do_bind(sockaddr: &str) -> Result<(RawFd, Domain)> {
@@ -194,7 +200,7 @@ macro_rules! cfg_async {
194200
mod tests {
195201
use super::*;
196202

197-
#[cfg(target_os = "linux")]
203+
#[cfg(any(target_os = "linux", target_os = "android"))]
198204
#[test]
199205
fn test_parse_sockaddr() {
200206
for i in &[
@@ -226,7 +232,7 @@ mod tests {
226232
}
227233
}
228234

229-
#[cfg(not(target_os = "linux"))]
235+
#[cfg(not(any(target_os = "linux", target_os = "android")))]
230236
#[test]
231237
fn test_parse_sockaddr() {
232238
for i in &[

src/sync/server.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use std::{io, thread};
2727

2828
use super::utils::response_to_channel;
2929
use crate::common;
30-
#[cfg(not(target_os = "linux"))]
30+
#[cfg(not(any(target_os = "linux", target_os = "android")))]
3131
use crate::common::set_fd_close_exec;
3232
use crate::context;
3333
use crate::error::{get_status, Error, Result};
@@ -329,10 +329,10 @@ impl Server {
329329

330330
self.listener_quit_flag.store(false, Ordering::SeqCst);
331331

332-
#[cfg(target_os = "linux")]
332+
#[cfg(any(target_os = "linux", target_os = "android"))]
333333
let fds = pipe2(nix::fcntl::OFlag::O_CLOEXEC)?;
334334

335-
#[cfg(not(target_os = "linux"))]
335+
#[cfg(not(any(target_os = "linux", target_os = "android")))]
336336
let fds = {
337337
let (rfd, wfd) = pipe()?;
338338
set_fd_close_exec(rfd)?;
@@ -435,7 +435,7 @@ impl Server {
435435
break;
436436
}
437437

438-
#[cfg(target_os = "linux")]
438+
#[cfg(any(target_os = "linux", target_os = "android"))]
439439
let fd = match accept4(listener, SockFlag::SOCK_CLOEXEC) {
440440
Ok(fd) => fd,
441441
Err(e) => {
@@ -447,7 +447,7 @@ impl Server {
447447
// Non Linux platforms do not support accept4 with SOCK_CLOEXEC flag, so instead
448448
// use accept and call fcntl separately to set SOCK_CLOEXEC.
449449
// Because of this there is chance of the descriptor leak if fork + exec happens in between.
450-
#[cfg(not(target_os = "linux"))]
450+
#[cfg(not(any(target_os = "linux", target_os = "android")))]
451451
let fd = match accept(listener) {
452452
Ok(fd) => {
453453
if let Err(err) = set_fd_close_exec(fd) {

0 commit comments

Comments
 (0)