Add set_passcred and passcred methods to UnixStream and UnixDatagram

This commit is contained in:
LinkTed 2020-09-07 18:00:01 +02:00
parent 19c5fdda7c
commit 686964f0f5
4 changed files with 131 additions and 11 deletions

View file

@ -735,6 +735,66 @@ impl UnixDatagram {
self.0.set_nonblocking(nonblocking)
}
/// Moves the socket to pass unix credentials as control message in [`SocketAncillary`].
///
/// Set the socket option `SO_PASSCRED`.
///
/// # Examples
///
/// ```no_run
/// #![feature(unix_socket_ancillary_data)]
/// use std::os::unix::net::UnixDatagram;
///
/// fn main() -> std::io::Result<()> {
/// let sock = UnixDatagram::unbound()?;
/// sock.set_passcred(true).expect("set_passcred function failed");
/// Ok(())
/// }
/// ```
#[cfg(any(
doc,
target_os = "android",
target_os = "dragonfly",
target_os = "emscripten",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
target_env = "uclibc",
))]
#[unstable(feature = "unix_socket_ancillary_data", issue = "none")]
pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
self.0.set_passcred(passcred)
}
/// Get the current value of the socket for passing unix credentials in [`SocketAncillary`].
/// This value can be change by [`set_passcred`].
///
/// Get the socket option `SO_PASSCRED`.
///
/// [`set_passcred`]: UnixDatagram::set_passcred
#[cfg(any(
doc,
target_os = "android",
target_os = "dragonfly",
target_os = "emscripten",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
target_env = "uclibc",
))]
#[unstable(feature = "unix_socket_ancillary_data", issue = "none")]
pub fn passcred(&self) -> io::Result<bool> {
self.0.passcred()
}
/// Returns the value of the `SO_ERROR` option.
///
/// # Examples

View file

@ -366,6 +366,66 @@ impl UnixStream {
self.0.set_nonblocking(nonblocking)
}
/// Moves the socket to pass unix credentials as control message in [`SocketAncillary`].
///
/// Set the socket option `SO_PASSCRED`.
///
/// # Examples
///
/// ```no_run
/// #![feature(unix_socket_ancillary_data)]
/// use std::os::unix::net::UnixStream;
///
/// fn main() -> std::io::Result<()> {
/// let socket = UnixStream::connect("/tmp/sock")?;
/// socket.set_passcred(true).expect("Couldn't set passcred");
/// Ok(())
/// }
/// ```
#[cfg(any(
doc,
target_os = "android",
target_os = "dragonfly",
target_os = "emscripten",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
target_env = "uclibc",
))]
#[unstable(feature = "unix_socket_ancillary_data", issue = "none")]
pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
self.0.set_passcred(passcred)
}
/// Get the current value of the socket for passing unix credentials in [`SocketAncillary`].
/// This value can be change by [`set_passcred`].
///
/// Get the socket option `SO_PASSCRED`.
///
/// [`set_passcred`]: UnixStream::set_passcred
#[cfg(any(
doc,
target_os = "android",
target_os = "dragonfly",
target_os = "emscripten",
target_os = "freebsd",
target_os = "fuchsia",
target_os = "ios",
target_os = "linux",
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
target_env = "uclibc",
))]
#[unstable(feature = "unix_socket_ancillary_data", issue = "none")]
pub fn passcred(&self) -> io::Result<bool> {
self.0.passcred()
}
/// Returns the value of the `SO_ERROR` option.
///
/// # Examples

View file

@ -2,7 +2,6 @@ use super::*;
use crate::io::prelude::*;
use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
use crate::iter::FromIterator;
use crate::mem;
use crate::sys::unix::ext::io::AsRawFd;
use crate::sys_common::io::test::tmpdir;
use crate::thread;
@ -513,16 +512,7 @@ fn test_send_vectored_with_ancillary_to_unix_datagram() {
let bsock1 = or_panic!(UnixDatagram::bind(&path1));
let bsock2 = or_panic!(UnixDatagram::bind(&path2));
unsafe {
let optval: libc::c_int = 1;
libc::setsockopt(
bsock2.as_raw_fd(),
libc::SOL_SOCKET,
libc::SO_PASSCRED,
&optval as *const _ as *const _,
mem::size_of::<libc::c_int>() as u32,
);
}
or_panic!(bsock2.set_passcred(true));
let mut buf1 = [1; 8];
let mut bufs_send = &mut [IoSliceMut::new(&mut buf1[..])][..];

View file

@ -323,6 +323,16 @@ impl Socket {
Ok(raw != 0)
}
pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
let boolean: libc::c_int = if passcred { 1 } else { 0 };
setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, boolean)
}
pub fn passcred(&self) -> io::Result<bool> {
let passcred: libc::c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED)?;
Ok(passcred != 0)
}
#[cfg(not(any(target_os = "solaris", target_os = "illumos")))]
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
let mut nonblocking = nonblocking as libc::c_int;