diff --git a/CHANGELOG.md b/CHANGELOG.md index 061d1b9fda..8e5354a9ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). (#[1284](https://github.com/nix-rust/nix/pull/1284)) - Changed unistd::{execv,execve,execvp,execvpe,fexecve,execveat} to take both `&[&CStr]` and `&[CString]` as its list argument(s). (#[1278](https://github.com/nix-rust/nix/pull/1278)) +- Made `unistd::fork` an unsafe funtion, bringing it in line with [libstd's decision](https://github.com/rust-lang/rust/pull/58059). + (#[1293](https://github.com/nix-rust/nix/pull/1293)) ### Fixed ### Removed diff --git a/src/unistd.rs b/src/unistd.rs index 4a7903a304..04031e3729 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -200,7 +200,7 @@ impl ForkResult { /// ```no_run /// use nix::unistd::{fork, ForkResult}; /// -/// match fork() { +/// match unsafe{fork()} { /// Ok(ForkResult::Parent { child, .. }) => { /// println!("Continuing execution in parent process, new child has pid: {}", child); /// } @@ -230,9 +230,9 @@ impl ForkResult { /// /// [async-signal-safe]: http://man7.org/linux/man-pages/man7/signal-safety.7.html #[inline] -pub fn fork() -> Result { +pub unsafe fn fork() -> Result { use self::ForkResult::*; - let res = unsafe { libc::fork() }; + let res = libc::fork(); Errno::result(res).map(|res| match res { 0 => Child, diff --git a/test/sys/test_ptrace.rs b/test/sys/test_ptrace.rs index 46ea3d6a14..3b60dd7056 100644 --- a/test/sys/test_ptrace.rs +++ b/test/sys/test_ptrace.rs @@ -81,7 +81,7 @@ fn test_ptrace_cont() { return; } - match fork().expect("Error: Fork Failed") { + match unsafe{fork()}.expect("Error: Fork Failed") { Child => { ptrace::traceme().unwrap(); // As recommended by ptrace(2), raise SIGTRAP to pause the child @@ -132,7 +132,7 @@ fn test_ptrace_syscall() { let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); - match fork().expect("Error: Fork Failed") { + match unsafe{fork()}.expect("Error: Fork Failed") { Child => { ptrace::traceme().unwrap(); // first sigstop until parent is ready to continue diff --git a/test/sys/test_uio.rs b/test/sys/test_uio.rs index 236560f43a..4fa838c994 100644 --- a/test/sys/test_uio.rs +++ b/test/sys/test_uio.rs @@ -212,7 +212,7 @@ fn test_process_vm_readv() { let mut vector = vec![1u8, 2, 3, 4, 5]; let (r, w) = pipe().unwrap(); - match fork().expect("Error: Fork Failed") { + match unsafe{fork()}.expect("Error: Fork Failed") { Parent { child } => { close(w).unwrap(); // wait for child diff --git a/test/sys/test_wait.rs b/test/sys/test_wait.rs index 53b7c84ac8..d105625012 100644 --- a/test/sys/test_wait.rs +++ b/test/sys/test_wait.rs @@ -11,7 +11,7 @@ fn test_wait_signal() { let _ = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe. - match fork().expect("Error: Fork Failed") { + match unsafe{fork()}.expect("Error: Fork Failed") { Child => { pause(); unsafe { _exit(123) } @@ -28,7 +28,7 @@ fn test_wait_exit() { let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); // Safe: Child only calls `_exit`, which is async-signal-safe. - match fork().expect("Error: Fork Failed") { + match unsafe{fork()}.expect("Error: Fork Failed") { Child => unsafe { _exit(12); }, Parent { child } => { assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 12))); @@ -48,7 +48,7 @@ fn test_waitstatus_from_raw() { fn test_waitstatus_pid() { let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); - match fork().unwrap() { + match unsafe{fork()}.unwrap() { Child => unsafe { _exit(0) }, Parent { child } => { let status = waitpid(child, None).unwrap(); @@ -98,7 +98,7 @@ mod ptrace { require_capability!(CAP_SYS_PTRACE); let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); - match fork().expect("Error: Fork Failed") { + match unsafe{fork()}.expect("Error: Fork Failed") { Child => ptrace_child(), Parent { child } => ptrace_parent(child), } diff --git a/test/test_unistd.rs b/test/test_unistd.rs index 0b2a810a48..c7a75fbe63 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -32,7 +32,7 @@ fn test_fork_and_waitpid() { let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); // Safe: Child only calls `_exit`, which is signal-safe - match fork().expect("Error: Fork Failed") { + match unsafe{fork()}.expect("Error: Fork Failed") { Child => unsafe { _exit(0) }, Parent { child } => { // assert that child was created and pid > 0 @@ -60,7 +60,7 @@ fn test_wait() { let _m = crate::FORK_MTX.lock().expect("Mutex got poisoned by another test"); // Safe: Child only calls `_exit`, which is signal-safe - match fork().expect("Error: Fork Failed") { + match unsafe{fork()}.expect("Error: Fork Failed") { Child => unsafe { _exit(0) }, Parent { child } => { let wait_status = wait(); @@ -302,7 +302,7 @@ macro_rules! execve_test_factory( // Safe: Child calls `exit`, `dup`, `close` and the provided `exec*` family function. // NOTE: Technically, this makes the macro unsafe to use because you could pass anything. // The tests make sure not to do that, though. - match fork().unwrap() { + match unsafe{fork()}.unwrap() { Child => { // Make `writer` be the stdout of the new process. dup2(writer, 1).unwrap();