Creating a FIFO

I'm trying to develop my first rust application and can't find a way to create an unix FIFO file. I didn't find anything related to FIFOs in the standard libraries so I moved to libc, where I found mkfifo.

extern crate libc;

use std::ffi::CString;

fn main() {
    let filename = CString::new("/tmp/noted").unwrap().as_ptr();

    unsafe {
        libc::mkfifo(filename, 0o644);
    }   
} 

This is how I tried to create a fifo named noted in /tmp. It didn't work...It compiles and runs and yet, no fifo is created. Help is appreciated :wink:

The CString::new("/tmp/noted").unwrap().as_ptr() line creates a temporary CString, gets the pointer to it, and then deallocates it. Because this is a common issue, the behaviour on drop was changed to zero the first byte of all CStrings when they are dropped, so at the end of the first line, filename points to memory which is technically freed, but which probably contains \0. Unfortunately, raw pointers do not contain lifetimes so there is no error. For example, if you change as_ptr() to to_bytes() you'll get an error.

To fix it, you need to change it so that the CString outlives the call to mkfifo.

let filename = CString::new("/tmp/noted").unwrap(); // No as ptr
unsafe {
    libc::mkfifo(filename.as_ptr(), 0o644); // as_ptr moved here
}
5 Likes