From dedfb57285958aa90a00ccf83131cde788e4f14d Mon Sep 17 00:00:00 2001 From: Lucy Date: Thu, 30 Jun 2022 12:07:45 -0400 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Socket=20passing=20works!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 1 + src/comp.rs | 28 ++++++++++++++++++++++++++-- src/main.rs | 8 +++++--- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index eb78aef..d1bf85a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ async-signals = "0.4" color-eyre = "0.6" futures-util = "0.3" libc = "0.2" +nix = { version = "0.24.1", features = ["fs"], default-features = false } sendfd = { version = "0.4.1", features = ["tokio"] } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/src/comp.rs b/src/comp.rs index d746f79..775d23c 100644 --- a/src/comp.rs +++ b/src/comp.rs @@ -1,9 +1,13 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::process::{ProcessEvent, ProcessHandler}; use color_eyre::eyre::{ContextCompat, Result, WrapErr}; +use nix::fcntl; use sendfd::SendWithFd; use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, os::unix::prelude::IntoRawFd}; +use std::{ + collections::HashMap, + os::unix::prelude::{AsRawFd, IntoRawFd}, +}; use tokio::{ io::{AsyncBufReadExt, AsyncWriteExt, BufReader, Lines}, net::{ @@ -24,6 +28,21 @@ pub enum Message { NewPrivilegedClient { count: usize }, } +fn mark_as_cloexec(stream: &UnixStream) -> Result<()> { + let raw_fd = stream.as_raw_fd(); + let fd_flags = fcntl::FdFlag::from_bits( + fcntl::fcntl(raw_fd, fcntl::FcntlArg::F_GETFD) + .wrap_err("failed to get GETFD value of stream")?, + ) + .wrap_err("failed to get fd flags from file")?; + fcntl::fcntl( + raw_fd, + fcntl::FcntlArg::F_SETFD(fd_flags.difference(fcntl::FdFlag::FD_CLOEXEC)), + ) + .wrap_err("failed to set CLOEXEC on file")?; + Ok(()) +} + pub fn create_privileged_socket( sockets: &mut Vec, env_vars: &[(String, String)], @@ -32,6 +51,7 @@ pub fn create_privileged_socket( UnixStream::pair().wrap_err("failed to create socket pair")?; sockets.push(comp_socket); let client_fd = { + mark_as_cloexec(&client_socket).wrap_err("failed to mark client stream as CLOEXEC")?; let std_stream = client_socket .into_std() .wrap_err("failed to convert client socket to std socket")?; @@ -98,6 +118,7 @@ async fn send_fd(session_tx: &mut WriteHalf<'_>, stream: Vec) -> Res let fds = stream .into_iter() .map(|stream| { + mark_as_cloexec(&stream).wrap_err("failed to mark stream as CLOEXEC")?; let std_stream = stream .into_std() .wrap_err("failed to convert stream to std stream")?; @@ -118,8 +139,10 @@ async fn send_fd(session_tx: &mut WriteHalf<'_>, stream: Vec) -> Res .write_all(b"\n") .await .wrap_err("failed to write newline")?; + tokio::time::sleep(std::time::Duration::from_micros(100)).await; let tx: &UnixStream = session_tx.as_ref(); - tx.send_with_fd(&[], &fds).wrap_err("failed to send fd")?; + tx.send_with_fd(&[0], &fds).wrap_err("failed to send fd")?; + info!("sent {} fds", fds.len()); Ok(()) } @@ -135,6 +158,7 @@ pub async fn run_compositor( let (session_rx, mut session_tx) = session.split(); let mut session = BufReader::new(session_rx).lines(); let comp = { + mark_as_cloexec(&comp).wrap_err("failed to mark compositor stream as CLOEXEC")?; let std_stream = comp .into_std() .wrap_err("failed to convert compositor unix stream to a standard unix stream")?; diff --git a/src/main.rs b/src/main.rs index 24539f9..90e3ad1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,9 +41,11 @@ async fn main() -> Result<()> { } } }); - let env_vars = env_rx - .await - .expect("failed to receive environmental variables"); + // let env_vars = env_rx + // .await + // .expect("failed to receive environmental variables"); + tokio::time::sleep(std::time::Duration::from_millis(100)).await; + let env_vars = Vec::new(); info!("got environmental variables: {:?}", env_vars); let mut sockets = Vec::with_capacity(2);