Skip to main content

line_editor/
io.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::io::Write;
6
7/// An unbuffered writer to standard output using the `write(2)` system call directly on
8/// `libc::STDOUT_FILENO`.
9///
10/// Bypasses any userspace buffering (such as `std::io::stdout`'s internal `LineWriter`),
11/// matching the unbuffered I/O behavior of `linenoise`.
12#[derive(Debug, Default, Clone, Copy)]
13pub struct UnbufferedStdout;
14
15impl Write for UnbufferedStdout {
16    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
17        if buf.is_empty() {
18            return Ok(0);
19        }
20        let ret = unsafe {
21            libc::write(libc::STDOUT_FILENO, buf.as_ptr() as *const libc::c_void, buf.len())
22        };
23        if ret < 0 { Err(std::io::Error::last_os_error()) } else { Ok(ret as usize) }
24    }
25
26    fn flush(&mut self) -> std::io::Result<()> {
27        Ok(())
28    }
29}
30
31impl Write for &UnbufferedStdout {
32    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
33        if buf.is_empty() {
34            return Ok(0);
35        }
36        let ret = unsafe {
37            libc::write(libc::STDOUT_FILENO, buf.as_ptr() as *const libc::c_void, buf.len())
38        };
39        if ret < 0 { Err(std::io::Error::last_os_error()) } else { Ok(ret as usize) }
40    }
41
42    fn flush(&mut self) -> std::io::Result<()> {
43        Ok(())
44    }
45}