37 releases

0.11.7 Apr 27, 2022
0.11.5 Mar 27, 2022
0.9.0 Nov 27, 2021
0.8.2 Apr 8, 2021
0.8.0 Mar 31, 2021

#182 in Windows APIs

Download history 58/week @ 2023-10-19 107/week @ 2023-10-26 66/week @ 2023-11-02 54/week @ 2023-11-09 88/week @ 2023-11-16 139/week @ 2023-11-23 190/week @ 2023-11-30 46/week @ 2023-12-07 81/week @ 2023-12-14 139/week @ 2023-12-21 76/week @ 2023-12-28 190/week @ 2024-01-04 51/week @ 2024-01-11 139/week @ 2024-01-18 67/week @ 2024-01-25 64/week @ 2024-02-01

328 downloads per month
Used in 4 crates


974 lines


This library is currently unstable and does not achieve reliable cross-platofrm functionality. While it works in some specific cases, there are simply too many exceptions to call this anywhere close to production-ready.

This project is in peril!

The right solution is to create (or find) unique and complete crates that wrap the Windows and the Unix functionality separately, and then to turn this into (one or more) crates that leverage those into specific opinionated, cross-platform implementations. I just don't have the time to prioritize working on this at the moment, so I'm looking for someone interested in adopting this project. I have a reasonably good idea of what needs to happen at both a high and a low-level, and would at least be willing to spend the time to transfer the knowledge I have. Otherwise, unless something changes for me and I find myself with a chunk more free time, this is at risk of becoming a failed project. Contact me through github, reddit /u/eolu, or discord Eolu#3431 if interested.

ipipe - A cross-platform named-pipe library for Rust

This library allows the creation of platform-independant named pipes. Standard Read/Write traits are implemented. APIs and performance will be improved in future versions. Issues and PRs welcome.


use ipipe::Pipe;
use std::thread;
use std::io::{BufRead, BufWriter};

const CANCEL: u8 = 24;

fn main()
    let mut pipe = Pipe::create().unwrap();
    println!("Name: {}", pipe.path().display());

    let writer = pipe.clone();
    thread::spawn(move || print_nums(writer));
    for line in BufReader::new(pipe).lines()
        println!("{}", line.unwrap());

fn print_nums(mut pipe: Pipe)
    for i in 1..=10
        writeln!(&mut pipe, "{}", i).unwrap();
    write!(&mut pipe, "{}", CANCEL as char).unwrap();

Running the above example program will output:


Pipe::create generates a random pipe name in a temporary location. Example path (Windows): \\.\pipe\pipe_23676_xMvclVhNKcg6iGf Example path (Unix): /tmp/pipe_1230_mFP8dx8uVl

Pipe::with_name allows a pipe name to be specified.

A note on reading/writing

To read or write to the same pipe in multiple places, Pipe::clone should be used to share the pipe. Pipe instances contain an internal Arc which will maintain the raw handle to the pipe until the last instance is dropped. Creating 2 separate handles to the same pipe is currently undefined behavior. This is an issue currently under investigation.


  • static_pipe

The static_pipe default feature allows the creation of mutex-protected static pipes that can be written to from anywhere in a way that mimics stdout. Here's an example:

use ipipe::*;
use std::io::{BufRead, BufWriter};

let mut reader = ipipe::init("my_out").unwrap();

// You can get a handle to an already-initialized pipe like this:
// let mut reader = ipipe::get("my_pipe");
let s = BufReader::new(pipe).lines().next().unwrap();
println!("String received: {}", s);

// Drops the static pipe. Can also call `ipipe::close_all()` to drop all static pipes.

Then anywhere your program (or another program with enough permission to access the pipe) can write code like this:

pprintln!("my_pipe", "This text will be sent over the pipe!");

Lower level as well as more complete/intuitive APIs to the static pipes are also planned for a future release.

  • rand

The rand default feature will allow calling Pipe::create() to open a pipe with a randomly-generated name. The generated name will have the following format: pipe_[process pid]_[15 random alphnumeric characters]. Equivalent to Pipe::with_name(&str) in every other way.

  • channels

The channels feature will allow calling pipe.receiver() and pipe.sender() to generate a channel. One end of the channel will be sent to a thread to watch either input or output from the pipe, and the other end of the channel will be returned.

  • tokio_channels

Equivalent to the channels feature, but uses tokio::task in place of std::thread.


~727K SLoC