diff options
author | Jonas Schievink <jonasschievink@gmail.com> | 2017-07-20 19:55:13 +0200 |
---|---|---|
committer | Jonas Schievink <jonasschievink@gmail.com> | 2017-07-22 18:02:05 +0200 |
commit | 7128f155df302edef0173d68c4eaa139fedcc020 (patch) | |
tree | b6f27640da5536838e4c3bd196ee5d5d82f86c28 /src | |
parent | 59d6b3cbe7c97646722feafaa944bbf6b1b9d32a (diff) | |
download | nix-7128f155df302edef0173d68c4eaa139fedcc020.zip |
Document invariants of fork and fix tests
Some tests were invoking non-async-signal-safe functions from the child
process after a `fork`. Since they might be invoked in parallel, this
could lead to problems.
Diffstat (limited to 'src')
-rw-r--r-- | src/unistd.rs | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/unistd.rs b/src/unistd.rs index 25237a07..19f82ef6 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -191,6 +191,18 @@ impl ForkResult { /// Continuing execution in parent process, new child has pid: 1234 /// I'm a new child process /// ``` +/// +/// # Safety +/// +/// In a multithreaded program, only [async-signal-safe] functions like `pause` +/// and `_exit` may be called by the child (the parent isn't restricted). Note +/// that memory allocation may **not** be async-signal-safe and thus must be +/// prevented. +/// +/// Those functions are only a small subset of your operating system's API, so +/// special care must be taken to only invoke code you can control and audit. +/// +/// [async-signal-safe]: http://man7.org/linux/man-pages/man7/signal-safety.7.html #[inline] pub fn fork() -> Result<ForkResult> { use self::ForkResult::*; @@ -687,7 +699,7 @@ pub fn gethostname<'a>(buffer: &'a mut [u8]) -> Result<&'a CStr> { /// use nix::unistd::close; /// /// fn main() { -/// let mut f = tempfile::tempfile().unwrap(); +/// let f = tempfile::tempfile().unwrap(); /// close(f.as_raw_fd()).unwrap(); // Bad! f will also close on drop! /// } /// ``` @@ -700,7 +712,7 @@ pub fn gethostname<'a>(buffer: &'a mut [u8]) -> Result<&'a CStr> { /// use nix::unistd::close; /// /// fn main() { -/// let mut f = tempfile::tempfile().unwrap(); +/// let f = tempfile::tempfile().unwrap(); /// close(f.into_raw_fd()).unwrap(); // Good. into_raw_fd consumes f /// } /// ``` |