rectangle_device_sandbox/
socket.rs1use async_std::os::unix::net::UnixListener;
2use std::error::Error;
3use std::fs::Permissions;
4use std::path::PathBuf;
5use std::os::unix::fs::PermissionsExt;
6use tempfile::TempDir;
7
8const TEMP_DIR_PREFIX: &'static str = "rect-socket.";
9const TEMP_DIR_MODE: u32 = 0o700;
10
11pub struct SocketPool {
12 pub mount_args: Vec<String>,
13 dir: TempDir,
14}
15
16pub struct Socket {
17 pub socket_path: PathBuf,
18 pub listener: UnixListener,
19}
20
21impl SocketPool {
22 pub fn new() -> Result<SocketPool, Box<dyn Error>> {
23 let dir = tempfile::Builder::new().prefix(TEMP_DIR_PREFIX).tempdir()?;
24 std::fs::set_permissions(&dir, Permissions::from_mode(TEMP_DIR_MODE))?;
25 Ok(SocketPool {
26 mount_args: vec![],
27 dir
28 })
29 }
30
31 pub async fn bind(&mut self, path_in_container: &str) -> Result<Socket, Box<dyn Error>> {
32 let arbitrary_id = self.mount_args.len().to_string();
33 let socket_path = self.dir.path().join(arbitrary_id);
34 let socket_path_str = socket_path.to_str().unwrap();
35 self.mount_args.push(format!("-v={}:{}", socket_path_str, path_in_container));
36 let listener = UnixListener::bind(&socket_path).await?;
37 Ok(Socket{ listener, socket_path })
38 }
39}