Skip to content

Commit 3c48342

Browse files
authored
Implement unshare. (#461)
Fixes #452.
1 parent 1b06142 commit 3c48342

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

src/backend/libc/thread/syscalls.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,9 @@ pub(crate) fn gettid() -> Pid {
293293
pub(crate) fn setns(fd: BorrowedFd, nstype: c::c_int) -> io::Result<c::c_int> {
294294
unsafe { ret_c_int(c::setns(borrowed_fd(fd), nstype)) }
295295
}
296+
297+
#[cfg(any(target_os = "android", target_os = "linux"))]
298+
#[inline]
299+
pub(crate) fn unshare(flags: crate::thread::UnshareFlags) -> io::Result<()> {
300+
unsafe { ret(c::unshare(flags.bits() as i32)) }
301+
}

src/backend/linux_raw/thread/syscalls.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,3 +288,9 @@ unsafe fn futex_old(
288288
pub(crate) fn setns(fd: BorrowedFd, nstype: c::c_int) -> io::Result<c::c_int> {
289289
unsafe { ret_c_int(syscall_readonly!(__NR_setns, fd, c_int(nstype))) }
290290
}
291+
292+
#[cfg(any(target_os = "android", target_os = "linux"))]
293+
#[inline]
294+
pub(crate) fn unshare(flags: crate::thread::UnshareFlags) -> io::Result<()> {
295+
unsafe { ret(syscall_readonly!(__NR_unshare, c_uint(flags.bits()))) }
296+
}

src/thread/setns.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
use bitflags::bitflags;
44
use linux_raw_sys::general::{
5-
CLONE_NEWCGROUP, CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWPID, CLONE_NEWTIME,
6-
CLONE_NEWUSER, CLONE_NEWUTS,
5+
CLONE_FILES, CLONE_FS, CLONE_NEWCGROUP, CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWPID,
6+
CLONE_NEWTIME, CLONE_NEWUSER, CLONE_NEWUTS, CLONE_SYSVSEM,
77
};
88

99
use crate::backend::c::c_int;
@@ -55,6 +55,32 @@ pub enum LinkNameSpaceType {
5555
Network = CLONE_NEWNET,
5656
}
5757

58+
bitflags! {
59+
/// `CLONE_*` for use with [`unshare`].
60+
pub struct UnshareFlags: u32 {
61+
/// `CLONE_FILES`.
62+
const FILES = CLONE_FILES;
63+
/// `CLONE_FS`.
64+
const FS = CLONE_FS;
65+
/// `CLONE_NEWCGROUP`.
66+
const NWCGROUP = CLONE_NEWCGROUP;
67+
/// `CLONE_NEWIPC`.
68+
const NEWIPC = CLONE_NEWIPC;
69+
/// `CLONE_NEWNET`.
70+
const NEWNET = CLONE_NEWNET;
71+
/// `CLONE_NEWNS`.
72+
const NEWNS = CLONE_NEWNS;
73+
/// `CLONE_NEWPID`.
74+
const NEWPID = CLONE_NEWPID;
75+
/// `CLONE_NEWTIME`.
76+
const NEWTIME = CLONE_NEWTIME;
77+
/// `CLONE_NEWUSER`.
78+
const NEWUSER = CLONE_NEWUSER;
79+
/// `CLONE_SYSVSEM`.
80+
const SYSVSEM = CLONE_SYSVSEM;
81+
}
82+
}
83+
5884
/// Reassociate the calling thread with the namespace associated with link referred to by `fd`.
5985
///
6086
/// `fd` must refer to one of the magic links in a `/proc/[pid]/ns/` directory, or a bind mount
@@ -87,3 +113,14 @@ pub fn move_into_thread_name_spaces(
87113
) -> io::Result<()> {
88114
syscalls::setns(fd, allowed_types.bits() as c_int).map(|_r| ())
89115
}
116+
117+
/// `unshare(flags)`—Disassociate parts of the current thread's execution
118+
/// context with other threads.
119+
///
120+
/// # References
121+
/// - [`unshare`]
122+
///
123+
/// [`unshare`]: https://man7.org/linux/man-pages/man2/unshare.2.html
124+
pub fn unshare(flags: UnshareFlags) -> io::Result<()> {
125+
syscalls::unshare(flags)
126+
}

0 commit comments

Comments
 (0)