diff options
author | Igor Matuszewski <igor@sequoia-pgp.org> | 2020-03-17 17:16:29 +0100 |
---|---|---|
committer | Igor Matuszewski <igor@sequoia-pgp.org> | 2020-03-19 14:40:01 +0100 |
commit | 131e963ac8847a7b50143e732bbb824b44b24c46 (patch) | |
tree | bc5bcc4f7e6545d238de17bf28752afa5c07afbe /ipc/src | |
parent | 8a18b0fe7c9479114510deffac81f0a72e6f37e2 (diff) |
ipc: Simplify IPC policy implementation
Diffstat (limited to 'ipc/src')
-rw-r--r-- | ipc/src/lib.rs | 55 |
1 files changed, 19 insertions, 36 deletions
diff --git a/ipc/src/lib.rs b/ipc/src/lib.rs index d5ad629c..fa44e722 100644 --- a/ipc/src/lib.rs +++ b/ipc/src/lib.rs @@ -172,49 +172,32 @@ impl Descriptor { } } else { let cookie = Cookie::new(); - for external in &[true, false] { - // Implement the IPC policy. - if policy == core::IPCPolicy::Internal && *external { - // Do not try to fork. - continue; - } - let addr = match self.start(*external) { - Ok(a) => a, - Err(e) => if *external { - if policy == core::IPCPolicy::External { - // Fail! - return Err(e); - } - - // Try to spawn a thread next. - continue; - } else { - // Failed to spawn a thread. - return Err(e); - } - }; - - /* XXX: It'd be nice not to waste this connection. */ - cookie.send(&mut TcpStream::connect(addr)?)?; - - if *external { - /* Write connection information to file. */ - file.set_len(0)?; - cookie.send(&mut file)?; - write!(file, "{}", addr)?; - } - drop(file); + let (addr, external) = match policy { + core::IPCPolicy::Internal => self.start(false)?, + core::IPCPolicy::External => self.start(true)?, + core::IPCPolicy::Robust => self.start(true) + .or_else(|_| self.start(false))? + }; + + /* XXX: It'd be nice not to waste this connection. */ + cookie.send(&mut TcpStream::connect(addr)?)?; - return do_connect(cookie, TcpStream::connect(addr)?); + if external { + /* Write connection information to file. */ + file.set_len(0)?; + file.write_all(&cookie.0)?; + write!(file, "{}", addr)?; } - unreachable!(); + drop(file); + + do_connect(cookie, TcpStream::connect(addr)?) } } /// Start the service, either as an external process or as a /// thread. - fn start(&self, external: bool) -> Result<SocketAddr> { + fn start(&self, external: bool) -> Result<(SocketAddr, bool)> { let listener = TcpListener::bind((Ipv4Addr::LOCALHOST, 0)).unwrap(); let addr = listener.local_addr()?; @@ -225,7 +208,7 @@ impl Descriptor { self.spawn(listener)?; } - Ok(addr) + Ok((addr, external)) } fn fork(&self, listener: TcpListener) -> Result<()> { |