Skip to content

Commit 382ee6b

Browse files
authored
net: add pid to tokio::net::unix::UCred (#2633)
1 parent 24ed874 commit 382ee6b

File tree

1 file changed

+68
-7
lines changed

1 file changed

+68
-7
lines changed

tokio/src/net/unix/ucred.rs

+68-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
use libc::{gid_t, uid_t};
1+
use libc::{gid_t, pid_t, uid_t};
22

33
/// Credentials of a process
44
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
55
pub struct UCred {
6+
/// PID (process ID) of the process
7+
pid: Option<pid_t>,
68
/// UID (user ID) of the process
79
uid: uid_t,
810
/// GID (group ID) of the process
@@ -19,19 +21,27 @@ impl UCred {
1921
pub fn gid(&self) -> gid_t {
2022
self.gid
2123
}
24+
25+
/// Gets PID (process ID) of the process.
26+
///
27+
/// This is only implemented under linux, android, IOS and MacOS
28+
pub fn pid(&self) -> Option<pid_t> {
29+
self.pid
30+
}
2231
}
2332

2433
#[cfg(any(target_os = "linux", target_os = "android"))]
2534
pub(crate) use self::impl_linux::get_peer_cred;
2635

2736
#[cfg(any(
2837
target_os = "dragonfly",
29-
target_os = "macos",
30-
target_os = "ios",
3138
target_os = "freebsd",
3239
target_os = "netbsd",
3340
target_os = "openbsd"
3441
))]
42+
pub(crate) use self::impl_bsd::get_peer_cred;
43+
44+
#[cfg(any(target_os = "macos", target_os = "ios"))]
3545
pub(crate) use self::impl_macos::get_peer_cred;
3646

3747
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
@@ -77,6 +87,7 @@ pub(crate) mod impl_linux {
7787
Ok(super::UCred {
7888
uid: ucred.uid,
7989
gid: ucred.gid,
90+
pid: Some(ucred.pid),
8091
})
8192
} else {
8293
Err(io::Error::last_os_error())
@@ -87,13 +98,11 @@ pub(crate) mod impl_linux {
8798

8899
#[cfg(any(
89100
target_os = "dragonfly",
90-
target_os = "macos",
91-
target_os = "ios",
92101
target_os = "freebsd",
93102
target_os = "netbsd",
94103
target_os = "openbsd"
95104
))]
96-
pub(crate) mod impl_macos {
105+
pub(crate) mod impl_bsd {
97106
use crate::net::unix::UnixStream;
98107

99108
use libc::getpeereid;
@@ -114,6 +123,54 @@ pub(crate) mod impl_macos {
114123
Ok(super::UCred {
115124
uid: uid.assume_init(),
116125
gid: gid.assume_init(),
126+
pid: None,
127+
})
128+
} else {
129+
Err(io::Error::last_os_error())
130+
}
131+
}
132+
}
133+
}
134+
135+
#[cfg(any(target_os = "macos", target_os = "ios"))]
136+
pub(crate) mod impl_macos {
137+
use crate::net::unix::UnixStream;
138+
139+
use libc::{c_void, getpeereid, getsockopt, pid_t, LOCAL_PEEREPID, SOL_LOCAL};
140+
use std::io;
141+
use std::mem::size_of;
142+
use std::mem::MaybeUninit;
143+
use std::os::unix::io::AsRawFd;
144+
145+
pub(crate) fn get_peer_cred(sock: &UnixStream) -> io::Result<super::UCred> {
146+
unsafe {
147+
let raw_fd = sock.as_raw_fd();
148+
149+
let mut uid = MaybeUninit::uninit();
150+
let mut gid = MaybeUninit::uninit();
151+
let mut pid: MaybeUninit<pid_t> = MaybeUninit::uninit();
152+
let mut pid_size: MaybeUninit<u32> = MaybeUninit::new(size_of::<pid_t>() as u32);
153+
154+
if getsockopt(
155+
raw_fd,
156+
SOL_LOCAL,
157+
LOCAL_PEEREPID,
158+
pid.as_mut_ptr() as *mut c_void,
159+
pid_size.as_mut_ptr(),
160+
) != 0
161+
{
162+
return Err(io::Error::last_os_error());
163+
}
164+
165+
assert!(pid_size.assume_init() == (size_of::<pid_t>() as u32));
166+
167+
let ret = getpeereid(raw_fd, uid.as_mut_ptr(), gid.as_mut_ptr());
168+
169+
if ret == 0 {
170+
Ok(super::UCred {
171+
uid: uid.assume_init(),
172+
gid: gid.assume_init(),
173+
pid: Some(pid.assume_init()),
117174
})
118175
} else {
119176
Err(io::Error::last_os_error())
@@ -154,7 +211,11 @@ pub(crate) mod impl_solaris {
154211

155212
ucred_free(cred);
156213

157-
Ok(super::UCred { uid, gid })
214+
Ok(super::UCred {
215+
uid,
216+
gid,
217+
pid: None,
218+
})
158219
} else {
159220
Err(io::Error::last_os_error())
160221
}

0 commit comments

Comments
 (0)