summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorIgor Matuszewski <igor@sequoia-pgp.org>2020-03-17 17:16:29 +0100
committerIgor Matuszewski <igor@sequoia-pgp.org>2020-03-19 14:40:01 +0100
commit131e963ac8847a7b50143e732bbb824b44b24c46 (patch)
treebc5bcc4f7e6545d238de17bf28752afa5c07afbe /ipc
parent8a18b0fe7c9479114510deffac81f0a72e6f37e2 (diff)
ipc: Simplify IPC policy implementation
Diffstat (limited to 'ipc')
-rw-r--r--ipc/src/lib.rs55
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<()> {