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