Skip to main content

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
16#[cfg(target_family = "unix")]
17use std::{io::IoSlice};
18use std::{time::Duration};
19
20#[cfg(target_family = "unix")]
21use tokio::{fs::File, io::{AsyncWrite, AsyncWriteExt}};
22
23#[cfg(target_family = "unix")]
24use crate::{PATH_CONSOLE, error::SyRes, map_error_os};
25
26use tokio::{time::sleep};
27
28use crate::{a_sync::syslog_async_internal::AsyncSyslogInternalIO, LogStat};
29
30pub type DefaultIOs = TokioIOs;
31
32#[derive(Debug, Clone)]
33pub struct TokioIOs;
34
35#[cfg(target_family = "unix")]
36impl TokioIOs
37{
38    /// Sends to the FD i.e file of stderr, stdout or any which 
39    /// implements [Write] `write_vectored` in async manner
40    ///
41    /// # Arguments
42    /// 
43    /// * `file_fd` - mutable consume of the container FD.
44    ///
45    /// * `msg` - a reference on array of data
46    ///
47    /// * `newline` - a new line string ref i.e "\n" or "\r\n"
48    pub(crate) async 
49    fn async_send_to_fd<W>(mut file_fd: W, msg: &str, newline: &str) -> SyRes<usize>
50    where W: AsyncWrite + Unpin
51    {
52        return 
53            file_fd
54                .write_vectored(
55                    &[IoSlice::new(msg.as_bytes()), IoSlice::new(newline.as_bytes())]
56                )
57                .await
58                .map_err(|e|
59                    map_error_os!(e, "async_send_to_fd() writev() failed")
60                );
61    }
62}
63
64#[cfg(target_family = "unix")]
65impl AsyncSyslogInternalIO for TokioIOs
66{
67    #[inline]
68    async 
69    fn send_to_stderr(logstat: LogStat, msg: &str)
70    {
71        if logstat.intersects(LogStat::LOG_PERROR) == true
72        {
73            let stderr_lock = tokio::io::stderr();
74
75            let newline = "\n";
76            let _ = Self::async_send_to_fd(stderr_lock, msg, newline).await;
77        }
78    }
79
80    #[inline]
81    async 
82    fn send_to_syscons(logstat: LogStat, msg_payload: &str)
83    {
84        use nix::libc;
85
86        if logstat.intersects(LogStat::LOG_CONS)
87        {
88            let syscons = 
89                File
90                    ::options()
91                        .create(false)
92                        .read(false)
93                        .write(true)
94                        .custom_flags(libc::O_NONBLOCK | libc::O_CLOEXEC)
95                        .open(*PATH_CONSOLE)
96                        .await;
97
98            if let Ok(file) = syscons
99            {
100                let newline = "\n";
101                let _ = Self::async_send_to_fd(file, msg_payload, newline);
102            }
103        }
104    }
105    
106    #[inline]
107    async 
108    fn sleep_micro(us: u64) 
109    {
110        sleep(Duration::from_micros(us)).await;
111    }
112}
113
114#[cfg(target_family = "windows")]
115impl AsyncSyslogInternalIO for TokioIOs
116{
117    #[inline]
118    async 
119    fn send_to_stderr(logstat: LogStat, msg: &str)
120    {
121        if logstat.intersects(LogStat::LOG_PERROR) == true
122        {
123           eprintln!("{}", msg);
124        }
125    }
126
127    #[inline]
128    async 
129    fn send_to_syscons(logstat: LogStat, msg_payload: &str)
130    {
131        if logstat.intersects(LogStat::LOG_CONS)
132        {
133            eprintln!("{}", msg_payload);
134        }
135    }
136    
137    #[inline]
138    async 
139    fn sleep_micro(us: u64) 
140    {
141        sleep(Duration::from_micros(us)).await;
142    }
143}