rectangle_device_sandbox/
socket.rs

1use 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}