Skip to content

Commit

Permalink
FreeBSD's rfork wrapper proposal
Browse files Browse the repository at this point in the history
  • Loading branch information
devnexen committed Nov 29, 2023
1 parent 39ad47b commit a55c665
Showing 1 changed file with 90 additions and 41 deletions.
131 changes: 90 additions & 41 deletions src/unistd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2911,6 +2911,55 @@ mod getres {
}
}

feature! {
#![feature = "process"]
#[cfg(target_os = "freebsd")]
pub mod rfork_freebsd {
use crate::errno::Errno;
use crate::Result;
use super::ForkResult;
use super::Pid;

libc_bitflags! {
/// Flags for [`rfork`]
/// subset of flags supported by FreeBSD 12.x and onwards
/// with a safe outcome, thus as `RFMEM` can possibly lead to undefined behavior,
/// it is not in the list. And `rfork_thread` is deprecated.
pub struct RforkFlags: libc::c_int {
/// creates a new process.
RFPROC;
/// the child process will detach from the parent.
/// however, no status will be emitted at child's exit.
RFNOWAIT;
/// the file descriptor's table will be copied
RFFDG;
/// a new file descriptor's table will be created
RFCFDG;
/// enables kernel thread support.
RFTHREAD;
/// sets a status to emit at child's exit.
RFTSIGZMB;
/// linux's behavior compatibility setting.
/// emits SIGUSR1 as opposed to SIGCHLD upon child's exit.
RFLINUXTHPN;
}
}

/// rfork can be used to have a tigher control about which resources child
/// and parent process will be sharing, file descriptors, address spaces
/// and child exit's behavior.
pub unsafe fn rfork(flags: RforkFlags) -> Result<ForkResult> {
let res = libc::rfork(flags.bits());
use ForkResult::*;

Errno::result(res).map(|res| match res {
0 => Child,
res => Parent { child: Pid(res) },
})
}
}
}

#[cfg(feature = "fs")]
libc_bitflags! {
/// Options for access()
Expand All @@ -2930,50 +2979,50 @@ libc_bitflags! {
feature! {
#![feature = "fs"]

/// Checks the file named by `path` for accessibility according to the flags given by `amode`
/// See [access(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html)
pub fn access<P: ?Sized + NixPath>(path: &P, amode: AccessFlags) -> Result<()> {
let res = path.with_nix_path(|cstr| unsafe {
libc::access(cstr.as_ptr(), amode.bits())
})?;
Errno::result(res).map(drop)
}
/// Checks the file named by `path` for accessibility according to the flags given by `amode`
/// See [access(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/access.html)
pub fn access<P: ?Sized + NixPath>(path: &P, amode: AccessFlags) -> Result<()> {
let res = path.with_nix_path(|cstr| unsafe {
libc::access(cstr.as_ptr(), amode.bits())
})?;
Errno::result(res).map(drop)
}

/// Checks the file named by `path` for accessibility according to the flags given by `mode`
///
/// If `dirfd` has a value, then `path` is relative to directory associated with the file descriptor.
///
/// If `dirfd` is `None`, then `path` is relative to the current working directory.
///
/// # References
///
/// [faccessat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/faccessat.html)
// redox: does not appear to support the *at family of syscalls.
/// Checks the file named by `path` for accessibility according to the flags given by `mode`
///
/// If `dirfd` has a value, then `path` is relative to directory associated with the file descriptor.
///
/// If `dirfd` is `None`, then `path` is relative to the current working directory.
///
/// # References
///
/// [faccessat(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/faccessat.html)
// redox: does not appear to support the *at family of syscalls.
#[cfg(not(target_os = "redox"))]
pub fn faccessat<P: ?Sized + NixPath>(
dirfd: Option<RawFd>,
path: &P,
mode: AccessFlags,
flags: AtFlags,
) -> Result<()> {
let res = path.with_nix_path(|cstr| unsafe {
libc::faccessat(
at_rawfd(dirfd),
cstr.as_ptr(),
mode.bits(),
flags.bits(),
)
})?;
Errno::result(res).map(drop)
}
pub fn faccessat<P: ?Sized + NixPath>(
dirfd: Option<RawFd>,
path: &P,
mode: AccessFlags,
flags: AtFlags,
) -> Result<()> {
let res = path.with_nix_path(|cstr| unsafe {
libc::faccessat(
at_rawfd(dirfd),
cstr.as_ptr(),
mode.bits(),
flags.bits(),
)
})?;
Errno::result(res).map(drop)
}

/// Checks the file named by `path` for accessibility according to the flags given
/// by `mode` using effective UID, effective GID and supplementary group lists.
///
/// # References
///
/// * [FreeBSD man page](https://www.freebsd.org/cgi/man.cgi?query=eaccess&sektion=2&n=1)
/// * [Linux man page](https://man7.org/linux/man-pages/man3/euidaccess.3.html)
/// Checks the file named by `path` for accessibility according to the flags given
/// by `mode` using effective UID, effective GID and supplementary group lists.
///
/// # References
///
/// * [FreeBSD man page](https://www.freebsd.org/cgi/man.cgi?query=eaccess&sektion=2&n=1)
/// * [Linux man page](https://man7.org/linux/man-pages/man3/euidaccess.3.html)
#[cfg(any(
freebsdlike,
all(target_os = "linux", not(target_env = "uclibc")),
Expand Down

0 comments on commit a55c665

Please sign in to comment.