syslog_rs/a_sync/async_tokio/
async_internal.rs

1/*-
2 * syslog-rs - a syslog client translated from libc to rust
3 * 
4 * Copyright 2025 Aleksandr Morozov
5 * 
6 * The syslog-rs crate can be redistributed and/or modified
7 * under the terms of either of the following licenses:
8 *
9 *   1. the Mozilla Public License Version 2.0 (the “MPL”) OR
10 *                     
11 *   2. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
12 */
13
14use std::{io::IoSlice, time::Duration};
15
16use nix::libc;
17use tokio::{fs::File, io::{AsyncWrite, AsyncWriteExt}, time::sleep};
18
19use crate::{a_sync::syslog_async_internal::AsyncSyslogInternalIO, error::SyRes, map_error_os, LogStat, PATH_CONSOLE};
20
21pub type DefaultIOs = TokioIOs;
22
23#[derive(Debug, Clone)]
24pub struct TokioIOs;
25
26impl TokioIOs
27{
28    /// Sends to the FD i.e file of stderr, stdout or any which 
29    /// implements [Write] `write_vectored` in async manner
30    ///
31    /// # Arguments
32    /// 
33    /// * `file_fd` - mutable consume of the container FD.
34    ///
35    /// * `msg` - a reference on array of data
36    ///
37    /// * `newline` - a new line string ref i.e "\n" or "\r\n"
38    pub(crate) async 
39    fn async_send_to_fd<W>(mut file_fd: W, msg: &str, newline: &str) -> SyRes<usize>
40    where W: AsyncWrite + Unpin
41    {
42        return 
43            file_fd
44                .write_vectored(
45                    &[IoSlice::new(msg.as_bytes()), IoSlice::new(newline.as_bytes())]
46                )
47                .await
48                .map_err(|e|
49                    map_error_os!(e, "async_send_to_fd() writev() failed")
50                );
51    }
52}
53impl AsyncSyslogInternalIO for TokioIOs
54{
55    #[inline]
56    async 
57    fn send_to_stderr(logstat: LogStat, msg: &str)
58    {
59        if logstat.intersects(LogStat::LOG_PERROR) == true
60        {
61            let stderr_lock = tokio::io::stderr();
62
63            let newline = "\n";
64            let _ = Self::async_send_to_fd(stderr_lock, msg, newline).await;
65        }
66    }
67
68    #[inline]
69    async 
70    fn send_to_syscons(logstat: LogStat, msg_payload: &str)
71    {
72        if logstat.intersects(LogStat::LOG_CONS)
73        {
74            let syscons = 
75                File
76                    ::options()
77                        .create(false)
78                        .read(false)
79                        .write(true)
80                        .custom_flags(libc::O_NONBLOCK | libc::O_CLOEXEC)
81                        .open(*PATH_CONSOLE)
82                        .await;
83
84            if let Ok(file) = syscons
85            {
86                let newline = "\n";
87                let _ = Self::async_send_to_fd(file, msg_payload, newline);
88            }
89        }
90    }
91    
92    #[inline]
93    async 
94    fn sleep_micro(us: u64) 
95    {
96        sleep(Duration::from_micros(us)).await;
97    }
98}