about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/os/unix/net/ancillary.rs141
-rw-r--r--library/std/src/os/unix/net/datagram.rs36
-rw-r--r--library/std/src/os/unix/net/stream.rs36
-rw-r--r--library/std/src/os/unix/net/tests.rs2
-rw-r--r--library/std/src/sys/unix/net.rs11
5 files changed, 205 insertions, 21 deletions
diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs
index 7cc901a7944..7565fbc0d09 100644
--- a/library/std/src/os/unix/net/ancillary.rs
+++ b/library/std/src/os/unix/net/ancillary.rs
@@ -86,7 +86,12 @@ fn add_to_ancillary_data<T>(
     cmsg_level: libc::c_int,
     cmsg_type: libc::c_int,
 ) -> bool {
-    let source_len = if let Some(source_len) = source.len().checked_mul(size_of::<T>()) {
+    #[cfg(not(target_os = "freebsd"))]
+    let cmsg_size = source.len().checked_mul(size_of::<T>());
+    #[cfg(target_os = "freebsd")]
+    let cmsg_size = Some(unsafe { libc::SOCKCRED2SIZE(1) });
+
+    let source_len = if let Some(source_len) = cmsg_size {
         if let Ok(source_len) = u32::try_from(source_len) {
             source_len
         } else {
@@ -178,7 +183,13 @@ impl<'a, T> Iterator for AncillaryDataIter<'a, T> {
     }
 }
 
-#[cfg(all(doc, not(target_os = "android"), not(target_os = "linux"), not(target_os = "netbsd")))]
+#[cfg(all(
+    doc,
+    not(target_os = "android"),
+    not(target_os = "linux"),
+    not(target_os = "netbsd"),
+    not(target_os = "freebsd")
+))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 #[derive(Clone)]
 pub struct SocketCred(());
@@ -194,6 +205,11 @@ pub struct SocketCred(libc::ucred);
 #[derive(Clone)]
 pub struct SocketCred(libc::sockcred);
 
+#[cfg(target_os = "freebsd")]
+#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+#[derive(Clone)]
+pub struct SocketCred(libc::sockcred2);
+
 #[doc(cfg(any(target_os = "android", target_os = "linux")))]
 #[cfg(any(target_os = "android", target_os = "linux"))]
 impl SocketCred {
@@ -246,6 +262,66 @@ impl SocketCred {
     }
 }
 
+#[cfg(target_os = "freebsd")]
+impl SocketCred {
+    /// Create a Unix credential struct.
+    ///
+    /// PID, UID and GID is set to 0.
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    #[must_use]
+    pub fn new() -> SocketCred {
+        SocketCred(libc::sockcred2 {
+            sc_version: 0,
+            sc_pid: 0,
+            sc_uid: 0,
+            sc_euid: 0,
+            sc_gid: 0,
+            sc_egid: 0,
+            sc_ngroups: 0,
+            sc_groups: [0; 1],
+        })
+    }
+
+    /// Set the PID.
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    pub fn set_pid(&mut self, pid: libc::pid_t) {
+        self.0.sc_pid = pid;
+    }
+
+    /// Get the current PID.
+    #[must_use]
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    pub fn get_pid(&self) -> libc::pid_t {
+        self.0.sc_pid
+    }
+
+    /// Set the UID.
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    pub fn set_uid(&mut self, uid: libc::uid_t) {
+        self.0.sc_euid = uid;
+    }
+
+    /// Get the current UID.
+    #[must_use]
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    pub fn get_uid(&self) -> libc::uid_t {
+        self.0.sc_euid
+    }
+
+    /// Set the GID.
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    pub fn set_gid(&mut self, gid: libc::gid_t) {
+        self.0.sc_egid = gid;
+    }
+
+    /// Get the current GID.
+    #[must_use]
+    #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+    pub fn get_gid(&self) -> libc::gid_t {
+        self.0.sc_egid
+    }
+}
+
 #[cfg(target_os = "netbsd")]
 impl SocketCred {
     /// Create a Unix credential struct.
@@ -271,6 +347,7 @@ impl SocketCred {
     }
 
     /// Get the current PID.
+    #[must_use]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn get_pid(&self) -> libc::pid_t {
         self.0.sc_pid
@@ -283,6 +360,7 @@ impl SocketCred {
     }
 
     /// Get the current UID.
+    #[must_use]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn get_uid(&self) -> libc::uid_t {
         self.0.sc_uid
@@ -295,6 +373,7 @@ impl SocketCred {
     }
 
     /// Get the current GID.
+    #[must_use]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn get_gid(&self) -> libc::gid_t {
         self.0.sc_gid
@@ -316,7 +395,13 @@ impl<'a> Iterator for ScmRights<'a> {
     }
 }
 
-#[cfg(all(doc, not(target_os = "android"), not(target_os = "linux"), not(target_os = "netbsd")))]
+#[cfg(all(
+    doc,
+    not(target_os = "android"),
+    not(target_os = "linux"),
+    not(target_os = "netbsd"),
+    not(target_os = "freebsd")
+))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub struct ScmCredentials<'a>(AncillaryDataIter<'a, ()>);
 
@@ -327,11 +412,21 @@ pub struct ScmCredentials<'a>(AncillaryDataIter<'a, ()>);
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::ucred>);
 
+#[cfg(target_os = "freebsd")]
+#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
+pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::sockcred2>);
+
 #[cfg(target_os = "netbsd")]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::sockcred>);
 
-#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
+#[cfg(any(
+    doc,
+    target_os = "android",
+    target_os = "linux",
+    target_os = "netbsd",
+    target_os = "freebsd"
+))]
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 impl<'a> Iterator for ScmCredentials<'a> {
     type Item = SocketCred;
@@ -353,7 +448,13 @@ pub enum AncillaryError {
 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
 pub enum AncillaryData<'a> {
     ScmRights(ScmRights<'a>),
-    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
+    #[cfg(any(
+        doc,
+        target_os = "android",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_os = "freebsd"
+    ))]
     ScmCredentials(ScmCredentials<'a>),
 }
 
@@ -376,7 +477,13 @@ impl<'a> AncillaryData<'a> {
     ///
     /// `data` must contain a valid control message and the control message must be type of
     /// `SOL_SOCKET` and level of `SCM_CREDENTIALS` or `SCM_CREDS`.
-    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
+    #[cfg(any(
+        doc,
+        target_os = "android",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_os = "freebsd"
+    ))]
     unsafe fn as_credentials(data: &'a [u8]) -> Self {
         let ancillary_data_iter = AncillaryDataIter::new(data);
         let scm_credentials = ScmCredentials(ancillary_data_iter);
@@ -395,6 +502,8 @@ impl<'a> AncillaryData<'a> {
                     libc::SCM_RIGHTS => Ok(AncillaryData::as_rights(data)),
                     #[cfg(any(target_os = "android", target_os = "linux",))]
                     libc::SCM_CREDENTIALS => Ok(AncillaryData::as_credentials(data)),
+                    #[cfg(target_os = "freebsd")]
+                    libc::SCM_CREDS2 => Ok(AncillaryData::as_credentials(data)),
                     #[cfg(target_os = "netbsd")]
                     libc::SCM_CREDS => Ok(AncillaryData::as_credentials(data)),
                     cmsg_type => {
@@ -603,12 +712,18 @@ impl<'a> SocketAncillary<'a> {
 
     /// Add credentials to the ancillary data.
     ///
-    /// The function returns `true` if there was enough space in the buffer.
-    /// If there was not enough space then no credentials was appended.
+    /// The function returns `true` if there is enough space in the buffer.
+    /// If there is not enough space then no credentials will be appended.
     /// Technically, that means this operation adds a control message with the level `SOL_SOCKET`
-    /// and type `SCM_CREDENTIALS` or `SCM_CREDS`.
-    ///
-    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
+    /// and type `SCM_CREDENTIALS`, `SCM_CREDS`, or `SCM_CREDS2`.
+    ///
+    #[cfg(any(
+        doc,
+        target_os = "android",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_os = "freebsd"
+    ))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn add_creds(&mut self, creds: &[SocketCred]) -> bool {
         self.truncated = false;
@@ -617,8 +732,10 @@ impl<'a> SocketAncillary<'a> {
             &mut self.length,
             creds,
             libc::SOL_SOCKET,
-            #[cfg(not(target_os = "netbsd"))]
+            #[cfg(not(any(target_os = "netbsd", target_os = "freebsd")))]
             libc::SCM_CREDENTIALS,
+            #[cfg(target_os = "freebsd")]
+            libc::SCM_CREDS2,
             #[cfg(target_os = "netbsd")]
             libc::SCM_CREDS,
         )
diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs
index e64569758a0..41cdcda4613 100644
--- a/library/std/src/os/unix/net/datagram.rs
+++ b/library/std/src/os/unix/net/datagram.rs
@@ -808,8 +808,24 @@ impl UnixDatagram {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(
+            target_os = "android",
+            target_os = "linux",
+            target_os = "netbsd",
+            target_os = "freebsd",
+        ),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(
+            target_os = "android",
+            target_os = "linux",
+            target_os = "netbsd",
+            target_os = "freebsd"
+        )),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::UnixDatagram;
     ///
@@ -819,7 +835,13 @@ impl UnixDatagram {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
+    #[cfg(any(
+        doc,
+        target_os = "android",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_os = "freebsd"
+    ))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
         self.0.set_passcred(passcred)
@@ -831,7 +853,13 @@ impl UnixDatagram {
     /// Get the socket option `SO_PASSCRED`.
     ///
     /// [`set_passcred`]: UnixDatagram::set_passcred
-    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
+    #[cfg(any(
+        doc,
+        target_os = "android",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_os = "freebsd"
+    ))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn passcred(&self) -> io::Result<bool> {
         self.0.passcred()
diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs
index 65cb4ae07a5..5aa3fb92576 100644
--- a/library/std/src/os/unix/net/stream.rs
+++ b/library/std/src/os/unix/net/stream.rs
@@ -397,8 +397,24 @@ impl UnixStream {
     ///
     /// # Examples
     ///
-    #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
-    #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
+    #[cfg_attr(
+        any(
+            target_os = "android",
+            target_os = "linux",
+            target_os = "netbsd",
+            target_os = "freebsd"
+        ),
+        doc = "```no_run"
+    )]
+    #[cfg_attr(
+        not(any(
+            target_os = "android",
+            target_os = "linux",
+            target_os = "netbsd",
+            target_os = "freebsd"
+        )),
+        doc = "```ignore"
+    )]
     /// #![feature(unix_socket_ancillary_data)]
     /// use std::os::unix::net::UnixStream;
     ///
@@ -408,7 +424,13 @@ impl UnixStream {
     ///     Ok(())
     /// }
     /// ```
-    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
+    #[cfg(any(
+        doc,
+        target_os = "android",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_os = "freebsd"
+    ))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
         self.0.set_passcred(passcred)
@@ -420,7 +442,13 @@ impl UnixStream {
     /// Get the socket option `SO_PASSCRED`.
     ///
     /// [`set_passcred`]: UnixStream::set_passcred
-    #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
+    #[cfg(any(
+        doc,
+        target_os = "android",
+        target_os = "linux",
+        target_os = "netbsd",
+        target_os = "freebsd"
+    ))]
     #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
     pub fn passcred(&self) -> io::Result<bool> {
         self.0.passcred()
diff --git a/library/std/src/os/unix/net/tests.rs b/library/std/src/os/unix/net/tests.rs
index f8c29a6d3a1..39f10c50dc4 100644
--- a/library/std/src/os/unix/net/tests.rs
+++ b/library/std/src/os/unix/net/tests.rs
@@ -646,7 +646,7 @@ fn test_send_vectored_fds_unix_stream() {
     }
 }
 
-#[cfg(any(target_os = "android", target_os = "linux",))]
+#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
 #[test]
 fn test_send_vectored_with_ancillary_to_unix_datagram() {
     fn getpid() -> libc::pid_t {
diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs
index f84240d268f..573bfa6587e 100644
--- a/library/std/src/sys/unix/net.rs
+++ b/library/std/src/sys/unix/net.rs
@@ -443,6 +443,17 @@ impl Socket {
         Ok(passcred != 0)
     }
 
+    #[cfg(target_os = "freebsd")]
+    pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
+        setsockopt(self, libc::AF_LOCAL, libc::LOCAL_CREDS_PERSISTENT, passcred as libc::c_int)
+    }
+
+    #[cfg(target_os = "freebsd")]
+    pub fn passcred(&self) -> io::Result<bool> {
+        let passcred: libc::c_int = getsockopt(self, libc::AF_LOCAL, libc::LOCAL_CREDS_PERSISTENT)?;
+        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;