Skip to content

Commit e7427e1

Browse files
ids1024Ian Douglas Scott
authored andcommitted
Add socket_peerpidfd
Supported on Linux since 6.5.
1 parent 5245b81 commit e7427e1

File tree

5 files changed

+55
-3
lines changed

5 files changed

+55
-3
lines changed

src/backend/libc/net/sockopt.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use super::ext::{in6_addr_new, in_addr_new};
44
use crate::backend::c;
55
use crate::backend::conv::{borrowed_fd, ret};
6-
use crate::fd::BorrowedFd;
6+
use crate::fd::{BorrowedFd, FromRawFd, OwnedFd, RawFd};
77
#[cfg(feature = "alloc")]
88
#[cfg(any(
99
linux_like,
@@ -1094,6 +1094,13 @@ pub(crate) fn socket_peercred(fd: BorrowedFd<'_>) -> io::Result<UCred> {
10941094
getsockopt(fd, c::SOL_SOCKET, c::SO_PEERCRED)
10951095
}
10961096

1097+
#[cfg(all(linux_kernel, not(target_os = "android")))]
1098+
#[inline]
1099+
pub(crate) fn socket_peerpidfd(fd: BorrowedFd<'_>) -> io::Result<OwnedFd> {
1100+
let raw = getsockopt::<RawFd>(fd, c::SOL_SOCKET, c::SO_PEERPIDFD)?;
1101+
Ok(unsafe { OwnedFd::from_raw_fd(raw) })
1102+
}
1103+
10971104
#[cfg(all(target_os = "linux", feature = "time"))]
10981105
#[inline]
10991106
pub(crate) fn set_txtime(

src/backend/linux_raw/net/sockopt.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::backend::c;
99
use crate::backend::conv::{by_mut, c_uint, ret, socklen_t};
1010
#[cfg(all(target_os = "linux", feature = "time"))]
1111
use crate::clockid::ClockId;
12-
use crate::fd::BorrowedFd;
12+
use crate::fd::{BorrowedFd, FromRawFd, OwnedFd, RawFd};
1313
#[cfg(feature = "alloc")]
1414
use crate::ffi::CStr;
1515
use crate::io;
@@ -880,6 +880,12 @@ pub(crate) fn socket_peercred(fd: BorrowedFd<'_>) -> io::Result<UCred> {
880880
getsockopt(fd, c::SOL_SOCKET, linux_raw_sys::net::SO_PEERCRED)
881881
}
882882

883+
#[inline]
884+
pub(crate) fn socket_peerpidfd(fd: BorrowedFd<'_>) -> io::Result<OwnedFd> {
885+
let raw = getsockopt::<RawFd>(fd, c::SOL_SOCKET, linux_raw_sys::net::SO_PEERPIDFD)?;
886+
Ok(unsafe { OwnedFd::from_raw_fd(raw) })
887+
}
888+
883889
#[cfg(all(target_os = "linux", feature = "time"))]
884890
#[inline]
885891
pub(crate) fn set_txtime(

src/net/sockopt.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ use crate::{backend, io};
187187
))]
188188
use alloc::string::String;
189189
use backend::c;
190-
use backend::fd::AsFd;
190+
use backend::fd::{AsFd, OwnedFd};
191191
use core::time::Duration;
192192

193193
/// Timeout identifier for use with [`set_socket_timeout`] and
@@ -1692,6 +1692,15 @@ pub fn socket_peercred<Fd: AsFd>(fd: Fd) -> io::Result<super::UCred> {
16921692
backend::net::sockopt::socket_peercred(fd.as_fd())
16931693
}
16941694

1695+
///`getsockopt(fd, SOL_SOCKET, SO_PEERPIDFD)`—Get pidfd of Unix domain peer
1696+
///
1697+
/// Added in Linux 6.5.
1698+
#[cfg(all(linux_kernel, not(target_os = "android")))]
1699+
#[doc(alias = "SO_PEERPIDFD")]
1700+
pub fn socket_peerpidfd<Fd: AsFd>(fd: Fd) -> io::Result<OwnedFd> {
1701+
backend::net::sockopt::socket_peerpidfd(fd.as_fd())
1702+
}
1703+
16951704
/// `getsockopt(fd, SOL_SOCKET, SO_TXTIME)` — Get transmission timing configuration.
16961705
#[cfg(all(target_os = "linux", feature = "time"))]
16971706
#[doc(alias = "SO_TXTIME")]

tests/event/select.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ fn test_select_with_pipes() {
8989
#[serial] // for `setrlimit` usage
9090
fn test_select_with_great_fds() {
9191
use core::cmp::max;
92+
use rustix::fd::{FromRawFd as _, OwnedFd};
9293
use rustix::io::{read, write};
9394
use rustix::pipe::pipe;
9495
use rustix::process::{getrlimit, setrlimit, Resource};
@@ -278,6 +279,7 @@ fn test_select_with_sockets() {
278279
#[test]
279280
#[serial] // for `setrlimit` usage, and `crate::init`
280281
fn test_select_with_maxfd_sockets() {
282+
use rustix::fd::{FromRawFd as _, OwnedFd};
281283
use rustix::net::{recv, send, AddressFamily, RecvFlags, SendFlags, SocketType};
282284
use rustix::process::{getrlimit, setrlimit, Resource};
283285
use std::net::{IpAddr, Ipv4Addr, SocketAddr};

tests/net/unix_alloc.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,34 @@ fn test_unix_peercred() {
684684
};
685685
}
686686

687+
#[cfg(all(
688+
feature = "process",
689+
feature = "net",
690+
linux_kernel,
691+
not(target_os = "android")
692+
))]
693+
#[test]
694+
fn test_unix_peerpidfd() {
695+
use rustix::net::{sockopt, AddressFamily, SocketFlags, SocketType};
696+
use rustix::process::PidfdFlags;
697+
698+
let (send_sock, _recv_sock) = rustix::net::socketpair(
699+
AddressFamily::UNIX,
700+
SocketType::STREAM,
701+
SocketFlags::CLOEXEC,
702+
None,
703+
)
704+
.unwrap();
705+
let pidfd = sockopt::socket_peerpidfd(&send_sock).unwrap();
706+
let own_pidfd =
707+
rustix::process::pidfd_open(rustix::process::getpid(), PidfdFlags::empty()).unwrap();
708+
// Two pidfds refer to the same process iff their `st_ino` values are the same.
709+
assert_eq!(
710+
rustix::fs::fstat(pidfd).unwrap().st_ino,
711+
rustix::fs::fstat(own_pidfd).unwrap().st_ino
712+
)
713+
}
714+
687715
/// Like `test_unix_msg_with_scm_rights`, but with multiple file descriptors
688716
/// over multiple control messages.
689717
#[cfg(not(any(target_os = "redox", target_os = "wasi")))]

0 commit comments

Comments
 (0)