Files
RedBear-OS/src/header/sys_syslog/linux.rs
T
Josh Megnauth 64d9847e37 Linux support for syslog.h
Linux's syslog is a local socket, so this uses the recent UDS work.

* Most of redox.rs is refactored into mod.rs now which has all of the C
  facing functions and consts.
* I wrapped the global logger in a Mutex instead of a RwLock. The logger
  is almost always locked for writing so a Mutex is simpler as RwLock
  provides no benefits.
* I implemented LOG_PERROR which also prints errors to stderr as well as
  the log.
* Syslog should be sys/syslog.h with syslog.h as an alias (the
  original code only had syslog.h).
2025-07-24 21:46:49 -04:00

75 lines
1.8 KiB
Rust

use crate::{
error::{Errno, Result},
fs::File,
header::{
sys_socket::{
connect,
constants::{AF_UNIX, SOCK_CLOEXEC, SOCK_DGRAM},
sockaddr, socket,
},
sys_un::sockaddr_un,
unistd::close,
},
io::BufWriter,
platform::ERRNO,
};
use super::logger::LogSink;
/// Unix Domain Socket connected to /dev/log.
pub struct LogFile(BufWriter<File>);
impl LogSink for LogFile {
type Sink = BufWriter<File>;
fn open() -> Result<Self>
where
Self: Sized,
{
let log_addr = {
let path = c"/dev/log";
let mut sockaddr: sockaddr_un = unsafe { core::mem::zeroed() };
sockaddr.sun_family = AF_UNIX as _;
unsafe {
core::ptr::copy_nonoverlapping(
path.as_ptr(),
sockaddr.sun_path.as_mut_ptr(),
path.count_bytes(),
)
};
path
};
let log_fd = {
let result = unsafe { socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0) };
if result > 0 {
Ok(result)
} else {
Err(Errno(ERRNO.get()))
}
}?;
// SAFETY:
// * connect handles invalid descriptors.
// * log_addr is a sockaddr_un so the size is correct.
if unsafe {
connect(
log_fd,
&raw const log_addr as *const sockaddr,
size_of::<sockaddr_un>(),
) < 0
} {
// In case close sets ERRNO.
let e = ERRNO.get();
close(log_fd);
return Err(Errno(e));
}
Ok(Self(BufWriter::new(File::new(log_fd))))
}
#[inline(always)]
fn writer(&mut self) -> &mut Self::Sink {
&mut self.0
}
}