interprocess/os/unix/fifo_file.rs
1//! Creation of FIFO files.
2//!
3//! On Windows, named pipes can be compared to Unix domain sockets: they can have multiple duplex
4//! connections on a single path, and the data can be chosen to either preserve or erase the message
5//! boundaries, resulting in a reliable performant alternative to TCP and UDP working in the bounds
6//! of a single machine. Those Unix domain sockets are employed by `interprocess` for local sockets
7//! via [an implementation provided by the standard library](std::os::unix::net).
8//!
9//! On Unix, named pipes, referred to as "FIFO files" in this crate, are just files which can have
10//! a sender and a receiver communicating with each other in one direction without message
11//! boundaries. If further receivers try to open the file, they will simply receive nothing at all;
12//! if further senders are connected, the data mixes in an unpredictable way, making it unusable.
13//! Therefore, FIFOs are to be used specifically to conveniently connect two applications through a
14//! known path which works like a pipe and nothing else.
15//!
16//! ## Usage
17//! The [`create_fifo()`] function serves for a FIFO file creation. Opening FIFO files works via the
18//! standard [`File`](std::fs::File)s, opened either only for sending or only for receiving.
19//! Deletion works the same way as with any regular file, via
20//! [`remove_file()`](std::fs::remove_file).
21
22use {
23 super::unixprelude::*,
24 crate::OrErrno,
25 std::{ffi::CString, io, path::Path},
26};
27
28/// Creates a FIFO file at the specified path with the specified permissions.
29///
30/// Since the `mode` parameter is masked with the [`umask`], it's best to leave it at `0o777` unless
31/// a different value is desired.
32///
33/// ## System calls
34/// - [`mkfifo`]
35///
36/// [`mkfifo`]: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/mkfifo.html
37/// [`umask`]: https://en.wikipedia.org/wiki/Umask
38pub fn create_fifo<P: AsRef<Path>>(path: P, mode: mode_t) -> io::Result<()> {
39 _create_fifo(path.as_ref(), mode)
40}
41fn _create_fifo(path: &Path, mode: mode_t) -> io::Result<()> {
42 let path = CString::new(path.as_os_str().as_bytes())?;
43 unsafe { libc::mkfifo(path.as_bytes_with_nul().as_ptr().cast(), mode) != -1 }
44 .true_val_or_errno(())
45}