Skip to content

Commit 686964f

Browse files
committed
Add set_passcred and passcred methods to UnixStream and UnixDatagram
1 parent 19c5fdd commit 686964f

File tree

4 files changed

+131
-11
lines changed

4 files changed

+131
-11
lines changed

library/std/src/sys/unix/ext/net/datagram.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,66 @@ impl UnixDatagram {
735735
self.0.set_nonblocking(nonblocking)
736736
}
737737

738+
/// Moves the socket to pass unix credentials as control message in [`SocketAncillary`].
739+
///
740+
/// Set the socket option `SO_PASSCRED`.
741+
///
742+
/// # Examples
743+
///
744+
/// ```no_run
745+
/// #![feature(unix_socket_ancillary_data)]
746+
/// use std::os::unix::net::UnixDatagram;
747+
///
748+
/// fn main() -> std::io::Result<()> {
749+
/// let sock = UnixDatagram::unbound()?;
750+
/// sock.set_passcred(true).expect("set_passcred function failed");
751+
/// Ok(())
752+
/// }
753+
/// ```
754+
#[cfg(any(
755+
doc,
756+
target_os = "android",
757+
target_os = "dragonfly",
758+
target_os = "emscripten",
759+
target_os = "freebsd",
760+
target_os = "fuchsia",
761+
target_os = "ios",
762+
target_os = "linux",
763+
target_os = "macos",
764+
target_os = "netbsd",
765+
target_os = "openbsd",
766+
target_env = "uclibc",
767+
))]
768+
#[unstable(feature = "unix_socket_ancillary_data", issue = "none")]
769+
pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
770+
self.0.set_passcred(passcred)
771+
}
772+
773+
/// Get the current value of the socket for passing unix credentials in [`SocketAncillary`].
774+
/// This value can be change by [`set_passcred`].
775+
///
776+
/// Get the socket option `SO_PASSCRED`.
777+
///
778+
/// [`set_passcred`]: UnixDatagram::set_passcred
779+
#[cfg(any(
780+
doc,
781+
target_os = "android",
782+
target_os = "dragonfly",
783+
target_os = "emscripten",
784+
target_os = "freebsd",
785+
target_os = "fuchsia",
786+
target_os = "ios",
787+
target_os = "linux",
788+
target_os = "macos",
789+
target_os = "netbsd",
790+
target_os = "openbsd",
791+
target_env = "uclibc",
792+
))]
793+
#[unstable(feature = "unix_socket_ancillary_data", issue = "none")]
794+
pub fn passcred(&self) -> io::Result<bool> {
795+
self.0.passcred()
796+
}
797+
738798
/// Returns the value of the `SO_ERROR` option.
739799
///
740800
/// # Examples

library/std/src/sys/unix/ext/net/stream.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,66 @@ impl UnixStream {
366366
self.0.set_nonblocking(nonblocking)
367367
}
368368

369+
/// Moves the socket to pass unix credentials as control message in [`SocketAncillary`].
370+
///
371+
/// Set the socket option `SO_PASSCRED`.
372+
///
373+
/// # Examples
374+
///
375+
/// ```no_run
376+
/// #![feature(unix_socket_ancillary_data)]
377+
/// use std::os::unix::net::UnixStream;
378+
///
379+
/// fn main() -> std::io::Result<()> {
380+
/// let socket = UnixStream::connect("/tmp/sock")?;
381+
/// socket.set_passcred(true).expect("Couldn't set passcred");
382+
/// Ok(())
383+
/// }
384+
/// ```
385+
#[cfg(any(
386+
doc,
387+
target_os = "android",
388+
target_os = "dragonfly",
389+
target_os = "emscripten",
390+
target_os = "freebsd",
391+
target_os = "fuchsia",
392+
target_os = "ios",
393+
target_os = "linux",
394+
target_os = "macos",
395+
target_os = "netbsd",
396+
target_os = "openbsd",
397+
target_env = "uclibc",
398+
))]
399+
#[unstable(feature = "unix_socket_ancillary_data", issue = "none")]
400+
pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
401+
self.0.set_passcred(passcred)
402+
}
403+
404+
/// Get the current value of the socket for passing unix credentials in [`SocketAncillary`].
405+
/// This value can be change by [`set_passcred`].
406+
///
407+
/// Get the socket option `SO_PASSCRED`.
408+
///
409+
/// [`set_passcred`]: UnixStream::set_passcred
410+
#[cfg(any(
411+
doc,
412+
target_os = "android",
413+
target_os = "dragonfly",
414+
target_os = "emscripten",
415+
target_os = "freebsd",
416+
target_os = "fuchsia",
417+
target_os = "ios",
418+
target_os = "linux",
419+
target_os = "macos",
420+
target_os = "netbsd",
421+
target_os = "openbsd",
422+
target_env = "uclibc",
423+
))]
424+
#[unstable(feature = "unix_socket_ancillary_data", issue = "none")]
425+
pub fn passcred(&self) -> io::Result<bool> {
426+
self.0.passcred()
427+
}
428+
369429
/// Returns the value of the `SO_ERROR` option.
370430
///
371431
/// # Examples

library/std/src/sys/unix/ext/net/tests.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use super::*;
22
use crate::io::prelude::*;
33
use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
44
use crate::iter::FromIterator;
5-
use crate::mem;
65
use crate::sys::unix::ext::io::AsRawFd;
76
use crate::sys_common::io::test::tmpdir;
87
use crate::thread;
@@ -513,16 +512,7 @@ fn test_send_vectored_with_ancillary_to_unix_datagram() {
513512
let bsock1 = or_panic!(UnixDatagram::bind(&path1));
514513
let bsock2 = or_panic!(UnixDatagram::bind(&path2));
515514

516-
unsafe {
517-
let optval: libc::c_int = 1;
518-
libc::setsockopt(
519-
bsock2.as_raw_fd(),
520-
libc::SOL_SOCKET,
521-
libc::SO_PASSCRED,
522-
&optval as *const _ as *const _,
523-
mem::size_of::<libc::c_int>() as u32,
524-
);
525-
}
515+
or_panic!(bsock2.set_passcred(true));
526516

527517
let mut buf1 = [1; 8];
528518
let mut bufs_send = &mut [IoSliceMut::new(&mut buf1[..])][..];

library/std/src/sys/unix/net.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,16 @@ impl Socket {
323323
Ok(raw != 0)
324324
}
325325

326+
pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
327+
let boolean: libc::c_int = if passcred { 1 } else { 0 };
328+
setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, boolean)
329+
}
330+
331+
pub fn passcred(&self) -> io::Result<bool> {
332+
let passcred: libc::c_int = getsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED)?;
333+
Ok(passcred != 0)
334+
}
335+
326336
#[cfg(not(any(target_os = "solaris", target_os = "illumos")))]
327337
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
328338
let mut nonblocking = nonblocking as libc::c_int;

0 commit comments

Comments
 (0)