1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
use dlog::{BufferId, Priority};
use dlog_redirect_stdout_sys::*;
use std::ffi::CStr;
use std::io::{Error, ErrorKind, Result};
/// Open an unstructured connection to a DLog logging sink.
///
/// Opens a connection with stdout to which you can stream data.
/// DLog will automatically convert it to individual logs appropriately.
///
/// # Arguments
///
/// * `buffer` - Target DLog buffer.
/// * `tag` - DLog tag for the resulting logs.
/// * `prio` - Priority for the resulting logs.
///
/// # Errors
///
/// * [`std::io::ErrorKind::InvalidInput`] - Buffer does not allow connections.
/// * [`std::io::ErrorKind::PermissionDenied`] - Buffer disabled via dlog config.
/// * [`std::io::ErrorKind::Uncategorized`] - Buffer not configured via dlog config.
/// * [`std::io::ErrorKind::Uncategorized`] - Unsupported DLog backend.
/// * [`std::io::ErrorKind::InvalidInput`] - Tag empty.
///
/// # Examples
///
/// ```
/// use dlog::{BufferId, Priority};
/// use dlog_redirect_stdout::redirect_stdout;
///
/// fn main() -> Result<(), std::io::Error> {
/// redirect_stdout(BufferId::LogIdMain, "foo", Priority::Info)?;
/// // The following sends an info log with tag "foo" and message "my_message".
/// println!("my_message");
/// Ok(())
/// }
/// ```
pub fn redirect_stdout(buffer: BufferId, tag: &str, prio: Priority) -> Result<()> {
let tag = format!("{}\0", tag);
let tag_c = CStr::from_bytes_with_nul(tag.as_bytes()).map_err(|_| ErrorKind::InvalidInput)?;
// SAFETY: the string is defined in a verified way above. All other parameters
// are checked for correctness on the C side.
match unsafe { dlog_connect_fd(buffer as i32, 1, tag_c.as_ptr(), prio as i32) } {
0 => Ok(()),
e => Err(Error::from_raw_os_error(-e)),
}
}
/// Open an unstructured connection to a DLog logging sink.
///
/// Opens a connection with stderr to which you can stream data.
/// DLog will automatically convert it to individual logs appropriately.
///
/// # Arguments
///
/// * `buffer` - Target DLog buffer.
/// * `tag` - DLog tag for the resulting logs.
/// * `prio` - Priority for the resulting logs.
///
/// # Errors
///
/// * [`std::io::ErrorKind::InvalidInput`] - Buffer does not allow connections.
/// * [`std::io::ErrorKind::PermissionDenied`] - Buffer disabled via dlog config.
/// * [`std::io::ErrorKind::Uncategorized`] - Buffer not configured via dlog config.
/// * [`std::io::ErrorKind::Uncategorized`] - Unsupported DLog backend.
/// * [`std::io::ErrorKind::InvalidInput`] - Tag empty.
///
/// # Examples
///
/// ```
/// use dlog::{BufferId, Priority};
/// use dlog_redirect_stdout::redirect_stderr;
///
/// fn main() -> Result<(), std::io::Error> {
/// redirect_stderr(BufferId::LogIdMain, "foo", Priority::Info)?;
/// // The following sends an info log with tag "foo" and message "my_message".
/// eprintln!("my_message");
/// Ok(())
/// }
/// ```
pub fn redirect_stderr(buffer: BufferId, tag: &str, prio: Priority) -> Result<()> {
let tag = format!("{}\0", tag);
let tag_c = CStr::from_bytes_with_nul(tag.as_bytes()).map_err(|_| ErrorKind::InvalidInput)?;
// SAFETY: the string is defined in a verified way above. All other parameters
// are checked for correctness on the C side.
match unsafe { dlog_connect_fd(buffer as i32, 2, tag_c.as_ptr(), prio as i32) } {
0 => Ok(()),
e => Err(Error::from_raw_os_error(-e)),
}
}
/// Check whether a file descriptor has been opened via DLog.
///
/// Use for low-level code that does bulk operations on FDs (for example, close
/// them all) but still wants to be able to use DLog interfaces afterwards.
///
/// # Returns
///
/// * `bool` - Whether the descriptor refers to a DLog file.
pub fn is_log_fd(fd: i32) -> bool {
// SAFETY: the C function is safe by itself.
unsafe { dlog_is_log_fd(fd) }
}