pub unsafe fn tee(
fd_in: i32,
fd_out: i32,
len: size_t,
flags: u32,
) -> Result<ssize_t, Errno>
Expand description
Duplicate pipe content.
§Examples
let mut fds_left = [0, 0];
let ret = unsafe { nc::pipe2(&mut fds_left, 0) };
assert!(ret.is_ok());
let mut fds_right = [0, 0];
let ret = unsafe { nc::pipe2(&mut fds_right, 0) };
assert!(ret.is_ok());
let msg = "Hello, Rust";
let ret = unsafe { nc::write(fds_left[1], msg.as_bytes()) };
assert!(ret.is_ok());
let n_write = ret.unwrap() as nc::size_t;
assert_eq!(n_write, msg.len());
let ret = unsafe { nc::tee(fds_left[0], fds_right[1], n_write, nc::SPLICE_F_NONBLOCK) };
assert!(ret.is_ok());
let mut buf = [0u8; 64];
let buf_len = buf.len();
let ret = unsafe { nc::read(fds_right[0], &mut buf) };
assert!(ret.is_ok());
let n_read = ret.unwrap() as nc::size_t;
assert_eq!(n_read, n_write);
let read_msg = std::str::from_utf8(&buf[..n_read]);
assert!(read_msg.is_ok());
assert_eq!(Ok(msg), read_msg);
unsafe {
assert!(nc::close(fds_left[0]).is_ok());
assert!(nc::close(fds_left[1]).is_ok());
assert!(nc::close(fds_right[0]).is_ok());
assert!(nc::close(fds_right[1]).is_ok());
}
Examples found in repository?
examples/tee.rs (lines 79-84)
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
fn main() {
let output_file = "/tmp/nc-splice";
let ret = unsafe {
nc::openat(
nc::AT_FDCWD,
output_file,
nc::O_WRONLY | nc::O_CREAT | nc::O_TRUNC,
0o644,
)
};
assert!(ret.is_ok());
let fd = ret.unwrap();
// Tee stdin to stdout
loop {
let stdin_fileno = 0;
let stdout_fileno = 1;
let ret = unsafe {
nc::tee(
stdin_fileno,
stdout_fileno,
usize::MAX,
nc::SPLICE_F_NONBLOCK,
)
};
let mut tee_len = match ret {
Ok(0) => break,
Err(nc::EAGAIN) => continue,
Err(errno) => {
eprintln!("tee error: {}", nc::strerror(errno));
unsafe { nc::exit(1) };
}
Ok(len) => len,
};
// Consume stdin by splicing it to a file.
while tee_len > 0 {
let ret = unsafe {
nc::splice(
stdin_fileno,
None,
fd,
None,
tee_len as usize,
nc::SPLICE_F_MOVE,
)
};
match ret {
Err(errno) => {
eprintln!("splice error: {}", nc::strerror(errno));
break;
}
Ok(len) => tee_len -= len,
}
}
}
let ret = unsafe { nc::close(fd) };
assert!(ret.is_ok());
}