diff --git a/CHANGELOG.md b/CHANGELOG.md index c52fd5271c..61dd81e16e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). ([#1020](https://github.com/nix-rust/nix/pull/1020)) - Replaced `CmsgSpace` with the `cmsg_space` macro. ([#1020](https://github.com/nix-rust/nix/pull/1020)) - +- Marked `fork` as unsafe function + ([#1020](https://github.com/nix-rust/nix/pull/1020)) ### Fixed - Fixed multiple bugs when using `sendmsg` and `recvmsg` with ancillary control messages ([#1020](https://github.com/nix-rust/nix/pull/1020)) diff --git a/src/unistd.rs b/src/unistd.rs index 96d8ace78c..d3e33070ac 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -192,7 +192,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); /// } @@ -222,9 +222,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 24d9b522ee..5311202f17 100644 --- a/test/sys/test_ptrace.rs +++ b/test/sys/test_ptrace.rs @@ -74,7 +74,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 diff --git a/test/sys/test_uio.rs b/test/sys/test_uio.rs index 3e4fc28ceb..58da573bcc 100644 --- a/test/sys/test_uio.rs +++ b/test/sys/test_uio.rs @@ -207,7 +207,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 d07d82f0d9..e92c48b6f1 100644 --- a/test/sys/test_wait.rs +++ b/test/sys/test_wait.rs @@ -10,7 +10,7 @@ fn test_wait_signal() { let _ = ::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) } @@ -27,7 +27,7 @@ fn test_wait_exit() { let _m = ::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))); @@ -47,7 +47,7 @@ fn test_waitstatus_from_raw() { fn test_waitstatus_pid() { let _m = ::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(); @@ -96,7 +96,7 @@ mod ptrace { fn test_wait_ptrace() { let _m = ::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 3f13883c7e..2f9990a12a 100644 --- a/test/test_unistd.rs +++ b/test/test_unistd.rs @@ -19,7 +19,7 @@ fn test_fork_and_waitpid() { let _m = ::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 @@ -47,7 +47,7 @@ fn test_wait() { let _m = ::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(); @@ -191,7 +191,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 => { // Close stdout. close(1).unwrap();