• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

varlink / rust / 12485070824

24 Dec 2024 06:28PM UTC coverage: 57.26% (+0.003%) from 57.257%
12485070824

Pull #117

github

web-flow
Merge 5e6ce3f47 into b08941906
Pull Request #117: Remove unix_socket dependency

14 of 14 new or added lines in 2 files covered. (100.0%)

3 existing lines in 1 file now uncovered.

2784 of 4862 relevant lines covered (57.26%)

33.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

28.79
/varlink/src/client.rs
1
//! Handle network connections for a varlink service
2

3
#![allow(dead_code)]
4

5
use std::net::TcpStream;
6
#[cfg(unix)]
7
use std::os::unix::io::{AsRawFd, IntoRawFd};
8
#[cfg(unix)]
9
use std::os::unix::net::{UnixListener, UnixStream};
10
use std::process::Child;
11

12
#[cfg(unix)]
13
use libc::{close, dup2, getpid};
14
use tempfile::TempDir;
15
#[cfg(windows)]
16
use uds_windows::UnixStream;
17

18
use crate::error::*;
19
use crate::stream::Stream;
20

21
#[allow(clippy::try_err)]
22
pub fn varlink_connect<S: ?Sized + AsRef<str>>(address: &S) -> Result<(Box<dyn Stream>, String)> {
13✔
23
    let address = address.as_ref();
13✔
24
    let new_address: String = address.into();
13✔
25

26
    if let Some(addr) = new_address.strip_prefix("tcp:") {
13✔
27
        Ok((
28
            Box::new(TcpStream::connect(addr).map_err(map_context!())?),
4✔
29
            new_address,
4✔
30
        ))
31
    } else if let Some(addr) = new_address.strip_prefix("unix:@") {
9✔
32
        let addr = addr.split(';').next().unwrap_or(addr);
1✔
33
        get_abstract_unixstream(addr).map(|v| (Box::new(v) as Box<dyn Stream>, new_address))
1✔
34
    } else if let Some(addr) = new_address.strip_prefix("unix:") {
8✔
35
        let addr = addr.split(';').next().unwrap_or(addr);
8✔
36
        Ok((
8✔
37
            Box::new(UnixStream::connect(addr).map_err(map_context!())?),
8✔
38
            new_address,
8✔
39
        ))
40
    } else {
41
        Err(context!(ErrorKind::InvalidAddress))?
×
42
    }
43
}
13✔
44

45
#[cfg(any(target_os = "linux", target_os = "android"))]
46
fn get_abstract_unixstream(addr: &str) -> Result<UnixStream> {
1✔
47
    use std::os::linux::net::SocketAddrExt;
48
    use std::os::unix::net::SocketAddr;
49

50
    let addr = SocketAddr::from_abstract_name(addr).map_err(map_context!())?;
1✔
51
    UnixStream::connect_addr(&addr).map_err(map_context!())
1✔
52
}
1✔
53

54
#[cfg(not(any(target_os = "linux", target_os = "android")))]
55
fn get_abstract_unixstream(_addr: &str) -> Result<UnixStream> {
56
    Err(context!(ErrorKind::InvalidAddress))
57
}
58

59
#[cfg(windows)]
60
pub fn varlink_exec<S: ?Sized + AsRef<str>>(
61
    _address: &S,
62
) -> Result<(Child, String, Option<TempDir>)> {
63
    Err(context!(ErrorKind::MethodNotImplemented(
64
        "varlink_exec".into()
65
    )))
66
}
67

68
#[cfg(unix)]
69
pub fn varlink_exec<S: ?Sized + AsRef<str>>(
×
70
    address: &S,
×
71
) -> Result<(Child, String, Option<TempDir>)> {
×
72
    use std::env;
73
    use std::os::unix::process::CommandExt;
74
    use std::process::Command;
75
    use tempfile::tempdir;
76

77
    let executable = String::from("exec ") + address.as_ref();
×
78

UNCOV
79
    let dir = tempdir().map_err(map_context!())?;
×
UNCOV
80
    let file_path = dir.path().join("varlink-socket");
×
81

82
    let listener = UnixListener::bind(file_path.clone()).map_err(map_context!())?;
×
83
    let fd = listener.as_raw_fd();
×
84

85
    let child = unsafe {
×
86
        Command::new("sh")
×
87
            .arg("-c")
×
88
            .arg(executable)
×
89
            .pre_exec({
×
90
                let file_path = file_path.clone();
×
91
                move || {
×
92
                    dup2(2, 1);
×
93
                    if fd != 3 {
×
94
                        dup2(fd, 3);
×
95
                        close(fd);
×
96
                    }
×
97
                    env::set_var("VARLINK_ADDRESS", format!("unix:{}", file_path.display()));
×
98
                    env::set_var("LISTEN_FDS", "1");
×
99
                    env::set_var("LISTEN_FDNAMES", "varlink");
×
100
                    env::set_var("LISTEN_PID", format!("{}", getpid()));
×
101
                    Ok(())
×
102
                }
×
103
            })
×
104
            .spawn()
×
105
            .map_err(map_context!())?
×
106
    };
107

108
    Ok((child, format!("unix:{}", file_path.display()), Some(dir)))
×
109
}
×
110

111
#[cfg(windows)]
112
pub fn varlink_bridge<S: ?Sized + AsRef<str>>(address: &S) -> Result<(Child, Box<dyn Stream>)> {
113
    use std::io::copy;
114
    use std::process::{Command, Stdio};
115
    use std::thread;
116

117
    let (stream0, stream1) = UnixStream::pair().map_err(map_context!())?;
118
    let executable = address.as_ref();
119

120
    let mut child = Command::new("cmd")
121
        .arg("/C")
122
        .arg(executable)
123
        .stdin(Stdio::piped())
124
        .stdout(Stdio::piped())
125
        .spawn()
126
        .map_err(map_context!())?;
127

128
    let mut client_writer = child.stdin.take().unwrap();
129
    let mut client_reader = child.stdout.take().unwrap();
130
    let mut service_writer = stream1.try_clone().map_err(map_context!())?;
131
    let mut service_reader = stream1;
132

133
    thread::spawn(move || copy(&mut client_reader, &mut service_writer));
134
    thread::spawn(move || copy(&mut service_reader, &mut client_writer));
135

136
    Ok((child, Box::new(stream0)))
137
}
138

139
#[cfg(unix)]
140
pub fn varlink_bridge<S: ?Sized + AsRef<str>>(address: &S) -> Result<(Child, Box<dyn Stream>)> {
×
141
    use std::os::unix::io::FromRawFd;
142
    use std::process::Command;
143

144
    let executable = address.as_ref();
×
UNCOV
145
    let (stream0, stream1) = UnixStream::pair().map_err(map_context!())?;
×
146
    let fd = stream1.into_raw_fd();
×
147
    let childin = unsafe { ::std::fs::File::from_raw_fd(fd) };
×
148
    let childout = unsafe { ::std::fs::File::from_raw_fd(fd) };
×
149

150
    let child = Command::new("sh")
×
151
        .arg("-c")
×
152
        .arg(executable)
×
153
        .stdin(childin)
×
154
        .stdout(childout)
×
155
        .spawn()
×
156
        .map_err(map_context!())?;
×
157
    Ok((child, Box::new(stream0)))
×
158
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc