use std::time::Duration;
use std::io::{IoSlice, Write};
use smol::io::AsyncWrite;
use smol::Timer;
use crate::smol::io::AsyncWriteExt;
use crate::error::SyRes;
use crate::{map_error_os};
use crate::{a_sync::syslog_async_internal::AsyncSyslogInternalIO, LogStat};
pub type DefaultIOs = SmolIOs;
#[derive(Debug, Clone)]
pub struct SmolIOs;
impl SmolIOs
{
pub(crate)
fn send_to_fd<W>(mut file_fd: W, msg: &str, newline: &str) -> SyRes<usize>
where W: Write
{
return
file_fd
.write_vectored(
&[IoSlice::new(msg.as_bytes()), IoSlice::new(newline.as_bytes())]
)
.map_err(|e|
map_error_os!(e, "async_send_to_fd() writev() failed")
);
}
pub(crate) async
fn async_send_to_fd<W>(mut file_fd: W, msg: &str, newline: &str) -> SyRes<usize>
where W: AsyncWrite + Unpin
{
return
file_fd
.write_vectored(
&[IoSlice::new(msg.as_bytes()), IoSlice::new(newline.as_bytes())]
)
.await
.map_err(|e|
map_error_os!(e, "async_send_to_fd() writev() failed")
);
}
}
#[cfg(target_family = "unix")]
impl AsyncSyslogInternalIO for SmolIOs
{
#[inline]
async
fn send_to_stderr(logstat: LogStat, msg: &str)
{
if logstat.intersects(LogStat::LOG_PERROR) == true
{
let stderr_lock = std::io::stderr();
let newline = "\n";
let _ = Self::send_to_fd(stderr_lock, msg, newline);
}
}
#[inline]
async
fn send_to_syscons(logstat: LogStat, msg_payload: &str)
{
use nix::libc;
use smol::fs::OpenOptions;
use smol::fs::unix::OpenOptionsExt;
use crate::{PATH_CONSOLE};
if logstat.intersects(LogStat::LOG_CONS)
{
let syscons =
OpenOptions
::new()
.create(false)
.read(false)
.write(true)
.custom_flags(libc::O_NONBLOCK | libc::O_CLOEXEC)
.open(*PATH_CONSOLE)
.await;
if let Ok(file) = syscons
{
let newline = "\n";
let _ = Self::async_send_to_fd(file, msg_payload, newline);
}
}
}
#[inline]
async
fn sleep_micro(us: u64)
{
Timer::after(Duration::from_micros(us));
}
}
#[cfg(target_family = "windows")]
impl AsyncSyslogInternalIO for SmolIOs
{
#[inline]
async
fn send_to_stderr(logstat: LogStat, msg: &str)
{
if logstat.intersects(LogStat::LOG_PERROR) == true
{
eprintln!("{}", msg);
}
}
#[inline]
async
fn send_to_syscons(logstat: LogStat, msg_payload: &str)
{
if logstat.intersects(LogStat::LOG_CONS)
{
eprintln!("{}", msg_payload);
}
}
#[inline]
async
fn sleep_micro(us: u64)
{
Timer::after(Duration::from_micros(us));
}
}