//! Listening on a Unix socket: the directory at 0700, a stale socket removed, the socket at 0600 //! (M5a spec, section 7). The same steps as `brokerd`'s; no crate depends on another role's. use std::fs::{DirBuilder, Permissions}; use std::io; use std::os::unix::fs::{DirBuilderExt, PermissionsExt}; use std::os::unix::net::UnixListener; use std::path::Path; /// Bind one socket: prepare its directory at 0700, make it private, remove any stale socket, /// bind, then make the socket itself private at 0600. The error names the path. pub fn listen(socket: &Path) -> Result { // The same five steps as `listen` in brokerd/src/serve.rs. Every error is a String naming its // path: format!("{}: {e}", path.display()). // 1. The directory is `socket.parent()`; when that is None, empty, or `/` itself (its own // parent() is None): Err(format!("{}: a socket needs a directory of its own, not / or none", // socket.display())). // 2. `DirBuilder::new().recursive(true).mode(0o700).create(dir)`. // 3. `std::fs::symlink_metadata(dir)`; when its file_type() is not a directory: // Err(format!("{}: is a symbolic link or not a directory; memoryd will not change its mode", // dir.display())). Then `set_permissions(dir, Permissions::from_mode(0o700))`. // 4. Remove a stale socket: `remove_file(socket)`; NotFound is fine, any other error is // returned. // 5. `UnixListener::bind(socket)`, then `set_permissions(socket, // Permissions::from_mode(0o600))`. Ok(listener). todo!() }