lrzsz2 0.3.2

ZMODEM file transfer utilities
Documentation
// SPDX-License-Identifier: GPL-3-0-or-later
// Copyright (c) 2017-2020 Alexey Arbuzov
// Copyright (c) 2023-2025 Jarkko Sakkinen

use std::fs::File;
use std::os::unix::io::{AsFd, AsRawFd};

/// Configure a file/device for raw serial communication suitable for ZMODEM
///
/// This sets the terminal to raw mode, which is necessary for binary protocols
/// like ZMODEM to work correctly over serial ports or PTYs.
#[cfg(unix)]
pub fn configure_raw_mode(file: &File) -> std::io::Result<()> {
    use nix::sys::termios::{self, SetArg};

    let mut termios = termios::tcgetattr(file.as_fd()).map_err(std::io::Error::other)?;

    termios::cfmakeraw(&mut termios);

    termios::tcsetattr(file.as_fd(), SetArg::TCSANOW, &termios).map_err(std::io::Error::other)?;

    Ok(())
}

#[cfg(not(unix))]
pub fn configure_raw_mode(_file: &File) -> std::io::Result<()> {
    Ok(())
}

/// Configure a file/device for non-blocking I/O
#[cfg(unix)]
pub fn configure_nonblocking(file: &File) -> std::io::Result<()> {
    use nix::fcntl::{self, FcntlArg, OFlag};

    let flags = fcntl::fcntl(file.as_raw_fd(), FcntlArg::F_GETFL).map_err(std::io::Error::other)?;
    let mut new_flags = OFlag::from_bits_truncate(flags);
    new_flags.insert(OFlag::O_NONBLOCK);
    fcntl::fcntl(file.as_raw_fd(), FcntlArg::F_SETFL(new_flags)).map_err(std::io::Error::other)?;
    Ok(())
}

#[cfg(not(unix))]
pub fn configure_nonblocking(_file: &File) -> std::io::Result<()> {
    Ok(())
}