File: local_socket_mode.rs

package info (click to toggle)
rust-interprocess 2.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,016 kB
  • sloc: makefile: 2
file content (66 lines) | stat: -rw-r--r-- 2,074 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use {
    crate::{
        local_socket::{traits::Stream as _, Listener, ListenerOptions, Name, NameInner, Stream},
        os::unix::local_socket::ListenerOptionsExt,
        tests::util::*,
        OrErrno,
    },
    libc::mode_t,
    std::{
        ffi::{CString, OsStr},
        mem::zeroed,
        os::unix::prelude::*,
        sync::Arc,
    },
};

fn get_file_mode(fname: &OsStr) -> TestResult<mode_t> {
    let mut cfname = fname.as_bytes().to_owned();
    cfname.push(0);
    let fname = CString::from_vec_with_nul(cfname)?;
    let mut stat = unsafe { zeroed::<libc::stat>() };
    unsafe { libc::stat(fname.as_ptr(), &mut stat) != -1 }
        .true_val_or_errno(())
        .opname("stat")?;
    Ok(stat.st_mode & 0o777)
}

fn get_fd_mode(fd: BorrowedFd<'_>) -> TestResult<mode_t> {
    let mut stat = unsafe { zeroed::<libc::stat>() };
    unsafe { libc::fstat(fd.as_raw_fd(), &mut stat) != -1 }
        .true_val_or_errno(())
        .opname("stat")?;
    Ok(stat.st_mode & 0o777)
}

fn test_inner(path: bool) -> TestResult {
    const MODE: libc::mode_t = 0o600;
    let (name, listener) =
        listen_and_pick_name(&mut namegen_local_socket(make_id!(), path), |nm| {
            ListenerOptions::new().name(nm.borrow()).mode(MODE).create_sync()
        })?;
    let name = Arc::try_unwrap(name).unwrap();
    let _ = Stream::connect(name.borrow()).opname("client connect")?;
    let actual_mode = if let Name(NameInner::UdSocketPath(path)) = name {
        get_file_mode(&path)
    } else {
        let fd = match &listener {
            Listener::UdSocket(l) => l.as_fd(),
        };
        get_fd_mode(fd)
    }
    .opname("get mode")?;
    if actual_mode != 0 {
        // FreeBSD refuses to fstat sockets for reasons I cannot even begin to fathom
        ensure_eq!(actual_mode, MODE);
    }

    Ok(())
}

#[test]
fn local_socket_file_mode() -> TestResult { test_wrapper(|| test_inner(true)) }

#[cfg(any(target_os = "linux", target_os = "android"))]
#[test]
fn local_socket_namespaced_mode() -> TestResult { test_wrapper(|| test_inner(false)) }