Skip to content

Commit 857b631

Browse files
authored
Rollup merge of #91793 - devnexen:anc_data_fbsd, r=ChrisDenton
socket ancillary data implementation for FreeBSD (from 13 and above). introducing new build config as well.
2 parents f418859 + ed5c0f6 commit 857b631

File tree

7 files changed

+209
-21
lines changed

7 files changed

+209
-21
lines changed

library/std/build.rs

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ fn main() {
66
if target.contains("freebsd") {
77
if env::var("RUST_STD_FREEBSD_12_ABI").is_ok() {
88
println!("cargo:rustc-cfg=freebsd12");
9+
} else if env::var("RUST_STD_FREEBSD_13_ABI").is_ok() {
10+
println!("cargo:rustc-cfg=freebsd12");
11+
println!("cargo:rustc-cfg=freebsd13");
912
}
1013
} else if target.contains("linux")
1114
|| target.contains("netbsd")

library/std/src/os/unix/net/ancillary.rs

+129-12
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,12 @@ fn add_to_ancillary_data<T>(
8686
cmsg_level: libc::c_int,
8787
cmsg_type: libc::c_int,
8888
) -> bool {
89-
let source_len = if let Some(source_len) = source.len().checked_mul(size_of::<T>()) {
89+
#[cfg(not(target_os = "freebsd"))]
90+
let cmsg_size = source.len().checked_mul(size_of::<T>());
91+
#[cfg(target_os = "freebsd")]
92+
let cmsg_size = Some(unsafe { libc::SOCKCRED2SIZE(1) });
93+
94+
let source_len = if let Some(source_len) = cmsg_size {
9095
if let Ok(source_len) = u32::try_from(source_len) {
9196
source_len
9297
} else {
@@ -178,7 +183,13 @@ impl<'a, T> Iterator for AncillaryDataIter<'a, T> {
178183
}
179184
}
180185

181-
#[cfg(all(doc, not(target_os = "android"), not(target_os = "linux"), not(target_os = "netbsd")))]
186+
#[cfg(all(
187+
doc,
188+
not(target_os = "android"),
189+
not(target_os = "linux"),
190+
not(target_os = "netbsd"),
191+
not(target_os = "freebsd")
192+
))]
182193
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
183194
#[derive(Clone)]
184195
pub struct SocketCred(());
@@ -194,6 +205,11 @@ pub struct SocketCred(libc::ucred);
194205
#[derive(Clone)]
195206
pub struct SocketCred(libc::sockcred);
196207

208+
#[cfg(target_os = "freebsd")]
209+
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
210+
#[derive(Clone)]
211+
pub struct SocketCred(libc::sockcred2);
212+
197213
#[doc(cfg(any(target_os = "android", target_os = "linux")))]
198214
#[cfg(any(target_os = "android", target_os = "linux"))]
199215
impl SocketCred {
@@ -246,6 +262,66 @@ impl SocketCred {
246262
}
247263
}
248264

265+
#[cfg(target_os = "freebsd")]
266+
impl SocketCred {
267+
/// Create a Unix credential struct.
268+
///
269+
/// PID, UID and GID is set to 0.
270+
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
271+
#[must_use]
272+
pub fn new() -> SocketCred {
273+
SocketCred(libc::sockcred2 {
274+
sc_version: 0,
275+
sc_pid: 0,
276+
sc_uid: 0,
277+
sc_euid: 0,
278+
sc_gid: 0,
279+
sc_egid: 0,
280+
sc_ngroups: 0,
281+
sc_groups: [0; 1],
282+
})
283+
}
284+
285+
/// Set the PID.
286+
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
287+
pub fn set_pid(&mut self, pid: libc::pid_t) {
288+
self.0.sc_pid = pid;
289+
}
290+
291+
/// Get the current PID.
292+
#[must_use]
293+
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
294+
pub fn get_pid(&self) -> libc::pid_t {
295+
self.0.sc_pid
296+
}
297+
298+
/// Set the UID.
299+
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
300+
pub fn set_uid(&mut self, uid: libc::uid_t) {
301+
self.0.sc_euid = uid;
302+
}
303+
304+
/// Get the current UID.
305+
#[must_use]
306+
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
307+
pub fn get_uid(&self) -> libc::uid_t {
308+
self.0.sc_euid
309+
}
310+
311+
/// Set the GID.
312+
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
313+
pub fn set_gid(&mut self, gid: libc::gid_t) {
314+
self.0.sc_egid = gid;
315+
}
316+
317+
/// Get the current GID.
318+
#[must_use]
319+
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
320+
pub fn get_gid(&self) -> libc::gid_t {
321+
self.0.sc_egid
322+
}
323+
}
324+
249325
#[cfg(target_os = "netbsd")]
250326
impl SocketCred {
251327
/// Create a Unix credential struct.
@@ -271,6 +347,7 @@ impl SocketCred {
271347
}
272348

273349
/// Get the current PID.
350+
#[must_use]
274351
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
275352
pub fn get_pid(&self) -> libc::pid_t {
276353
self.0.sc_pid
@@ -283,6 +360,7 @@ impl SocketCred {
283360
}
284361

285362
/// Get the current UID.
363+
#[must_use]
286364
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
287365
pub fn get_uid(&self) -> libc::uid_t {
288366
self.0.sc_uid
@@ -295,6 +373,7 @@ impl SocketCred {
295373
}
296374

297375
/// Get the current GID.
376+
#[must_use]
298377
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
299378
pub fn get_gid(&self) -> libc::gid_t {
300379
self.0.sc_gid
@@ -316,7 +395,13 @@ impl<'a> Iterator for ScmRights<'a> {
316395
}
317396
}
318397

319-
#[cfg(all(doc, not(target_os = "android"), not(target_os = "linux"), not(target_os = "netbsd")))]
398+
#[cfg(all(
399+
doc,
400+
not(target_os = "android"),
401+
not(target_os = "linux"),
402+
not(target_os = "netbsd"),
403+
not(target_os = "freebsd")
404+
))]
320405
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
321406
pub struct ScmCredentials<'a>(AncillaryDataIter<'a, ()>);
322407

@@ -327,11 +412,21 @@ pub struct ScmCredentials<'a>(AncillaryDataIter<'a, ()>);
327412
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
328413
pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::ucred>);
329414

415+
#[cfg(target_os = "freebsd")]
416+
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
417+
pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::sockcred2>);
418+
330419
#[cfg(target_os = "netbsd")]
331420
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
332421
pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::sockcred>);
333422

334-
#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
423+
#[cfg(any(
424+
doc,
425+
target_os = "android",
426+
target_os = "linux",
427+
target_os = "netbsd",
428+
target_os = "freebsd"
429+
))]
335430
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
336431
impl<'a> Iterator for ScmCredentials<'a> {
337432
type Item = SocketCred;
@@ -353,7 +448,13 @@ pub enum AncillaryError {
353448
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
354449
pub enum AncillaryData<'a> {
355450
ScmRights(ScmRights<'a>),
356-
#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
451+
#[cfg(any(
452+
doc,
453+
target_os = "android",
454+
target_os = "linux",
455+
target_os = "netbsd",
456+
target_os = "freebsd"
457+
))]
357458
ScmCredentials(ScmCredentials<'a>),
358459
}
359460

@@ -376,7 +477,13 @@ impl<'a> AncillaryData<'a> {
376477
///
377478
/// `data` must contain a valid control message and the control message must be type of
378479
/// `SOL_SOCKET` and level of `SCM_CREDENTIALS` or `SCM_CREDS`.
379-
#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
480+
#[cfg(any(
481+
doc,
482+
target_os = "android",
483+
target_os = "linux",
484+
target_os = "netbsd",
485+
target_os = "freebsd"
486+
))]
380487
unsafe fn as_credentials(data: &'a [u8]) -> Self {
381488
let ancillary_data_iter = AncillaryDataIter::new(data);
382489
let scm_credentials = ScmCredentials(ancillary_data_iter);
@@ -395,6 +502,8 @@ impl<'a> AncillaryData<'a> {
395502
libc::SCM_RIGHTS => Ok(AncillaryData::as_rights(data)),
396503
#[cfg(any(target_os = "android", target_os = "linux",))]
397504
libc::SCM_CREDENTIALS => Ok(AncillaryData::as_credentials(data)),
505+
#[cfg(target_os = "freebsd")]
506+
libc::SCM_CREDS2 => Ok(AncillaryData::as_credentials(data)),
398507
#[cfg(target_os = "netbsd")]
399508
libc::SCM_CREDS => Ok(AncillaryData::as_credentials(data)),
400509
cmsg_type => {
@@ -603,12 +712,18 @@ impl<'a> SocketAncillary<'a> {
603712

604713
/// Add credentials to the ancillary data.
605714
///
606-
/// The function returns `true` if there was enough space in the buffer.
607-
/// If there was not enough space then no credentials was appended.
715+
/// The function returns `true` if there is enough space in the buffer.
716+
/// If there is not enough space then no credentials will be appended.
608717
/// Technically, that means this operation adds a control message with the level `SOL_SOCKET`
609-
/// and type `SCM_CREDENTIALS` or `SCM_CREDS`.
610-
///
611-
#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
718+
/// and type `SCM_CREDENTIALS`, `SCM_CREDS`, or `SCM_CREDS2`.
719+
///
720+
#[cfg(any(
721+
doc,
722+
target_os = "android",
723+
target_os = "linux",
724+
target_os = "netbsd",
725+
target_os = "freebsd"
726+
))]
612727
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
613728
pub fn add_creds(&mut self, creds: &[SocketCred]) -> bool {
614729
self.truncated = false;
@@ -617,8 +732,10 @@ impl<'a> SocketAncillary<'a> {
617732
&mut self.length,
618733
creds,
619734
libc::SOL_SOCKET,
620-
#[cfg(not(target_os = "netbsd"))]
735+
#[cfg(not(any(target_os = "netbsd", target_os = "freebsd")))]
621736
libc::SCM_CREDENTIALS,
737+
#[cfg(target_os = "freebsd")]
738+
libc::SCM_CREDS2,
622739
#[cfg(target_os = "netbsd")]
623740
libc::SCM_CREDS,
624741
)

library/std/src/os/unix/net/datagram.rs

+32-4
Original file line numberDiff line numberDiff line change
@@ -808,8 +808,24 @@ impl UnixDatagram {
808808
///
809809
/// # Examples
810810
///
811-
#[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
812-
#[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
811+
#[cfg_attr(
812+
any(
813+
target_os = "android",
814+
target_os = "linux",
815+
target_os = "netbsd",
816+
target_os = "freebsd",
817+
),
818+
doc = "```no_run"
819+
)]
820+
#[cfg_attr(
821+
not(any(
822+
target_os = "android",
823+
target_os = "linux",
824+
target_os = "netbsd",
825+
target_os = "freebsd"
826+
)),
827+
doc = "```ignore"
828+
)]
813829
/// #![feature(unix_socket_ancillary_data)]
814830
/// use std::os::unix::net::UnixDatagram;
815831
///
@@ -819,7 +835,13 @@ impl UnixDatagram {
819835
/// Ok(())
820836
/// }
821837
/// ```
822-
#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
838+
#[cfg(any(
839+
doc,
840+
target_os = "android",
841+
target_os = "linux",
842+
target_os = "netbsd",
843+
target_os = "freebsd"
844+
))]
823845
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
824846
pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
825847
self.0.set_passcred(passcred)
@@ -831,7 +853,13 @@ impl UnixDatagram {
831853
/// Get the socket option `SO_PASSCRED`.
832854
///
833855
/// [`set_passcred`]: UnixDatagram::set_passcred
834-
#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
856+
#[cfg(any(
857+
doc,
858+
target_os = "android",
859+
target_os = "linux",
860+
target_os = "netbsd",
861+
target_os = "freebsd"
862+
))]
835863
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
836864
pub fn passcred(&self) -> io::Result<bool> {
837865
self.0.passcred()

library/std/src/os/unix/net/stream.rs

+32-4
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,24 @@ impl UnixStream {
397397
///
398398
/// # Examples
399399
///
400-
#[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
401-
#[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
400+
#[cfg_attr(
401+
any(
402+
target_os = "android",
403+
target_os = "linux",
404+
target_os = "netbsd",
405+
target_os = "freebsd"
406+
),
407+
doc = "```no_run"
408+
)]
409+
#[cfg_attr(
410+
not(any(
411+
target_os = "android",
412+
target_os = "linux",
413+
target_os = "netbsd",
414+
target_os = "freebsd"
415+
)),
416+
doc = "```ignore"
417+
)]
402418
/// #![feature(unix_socket_ancillary_data)]
403419
/// use std::os::unix::net::UnixStream;
404420
///
@@ -408,7 +424,13 @@ impl UnixStream {
408424
/// Ok(())
409425
/// }
410426
/// ```
411-
#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
427+
#[cfg(any(
428+
doc,
429+
target_os = "android",
430+
target_os = "linux",
431+
target_os = "netbsd",
432+
target_os = "freebsd"
433+
))]
412434
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
413435
pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
414436
self.0.set_passcred(passcred)
@@ -420,7 +442,13 @@ impl UnixStream {
420442
/// Get the socket option `SO_PASSCRED`.
421443
///
422444
/// [`set_passcred`]: UnixStream::set_passcred
423-
#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))]
445+
#[cfg(any(
446+
doc,
447+
target_os = "android",
448+
target_os = "linux",
449+
target_os = "netbsd",
450+
target_os = "freebsd"
451+
))]
424452
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
425453
pub fn passcred(&self) -> io::Result<bool> {
426454
self.0.passcred()

library/std/src/os/unix/net/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ fn test_send_vectored_fds_unix_stream() {
646646
}
647647
}
648648

649-
#[cfg(any(target_os = "android", target_os = "linux",))]
649+
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
650650
#[test]
651651
fn test_send_vectored_with_ancillary_to_unix_datagram() {
652652
fn getpid() -> libc::pid_t {

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

+11
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,17 @@ impl Socket {
443443
Ok(passcred != 0)
444444
}
445445

446+
#[cfg(target_os = "freebsd")]
447+
pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
448+
setsockopt(self, libc::AF_LOCAL, libc::LOCAL_CREDS_PERSISTENT, passcred as libc::c_int)
449+
}
450+
451+
#[cfg(target_os = "freebsd")]
452+
pub fn passcred(&self) -> io::Result<bool> {
453+
let passcred: libc::c_int = getsockopt(self, libc::AF_LOCAL, libc::LOCAL_CREDS_PERSISTENT)?;
454+
Ok(passcred != 0)
455+
}
456+
446457
#[cfg(not(any(target_os = "solaris", target_os = "illumos")))]
447458
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
448459
let mut nonblocking = nonblocking as libc::c_int;

0 commit comments

Comments
 (0)