Add 'logd/' from commit 'db36d01782a6b9cc7ec995f884f8c1259d79903e'
git-subtree-dir: logd git-subtree-mainline:38c917a56bgit-subtree-split:db36d01782
This commit is contained in:
@@ -0,0 +1 @@
|
||||
target
|
||||
Generated
+65
@@ -0,0 +1,65 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.159"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logd"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libredox",
|
||||
"redox-daemon",
|
||||
"redox-scheme",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox-daemon"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fbdeffdb03cf2961b211a2023e683d71f2c225ea93404da5dc34b0dc94f0341"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libredox",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox-scheme"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98d040cfa6370d9c6b1a5987247272f19ea4722f1064e66ad2e077c152b82ea3"
|
||||
dependencies = [
|
||||
"libredox",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "logd"
|
||||
version = "0.1.0"
|
||||
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
redox_syscall = "0.5"
|
||||
redox-daemon = "0.1.2"
|
||||
libredox = "0.1.3"
|
||||
redox-scheme = "0.2.1"
|
||||
@@ -0,0 +1,19 @@
|
||||
# logd
|
||||
|
||||
Log daemon for collecting all log output.
|
||||
|
||||
## How To Contribute
|
||||
|
||||
To learn how to contribute to this system component you need to read the following document:
|
||||
|
||||
- [CONTRIBUTING.md](https://gitlab.redox-os.org/redox-os/redox/-/blob/master/CONTRIBUTING.md)
|
||||
|
||||
## Development
|
||||
|
||||
To learn how to do development with this system component inside the Redox build system you need to read the [Build System](https://doc.redox-os.org/book/build-system-reference.html) and [Coding and Building](https://doc.redox-os.org/book/coding-and-building.html) pages.
|
||||
|
||||
### How To Build
|
||||
|
||||
To build this system component you need to download the Redox build system, you can learn how to do it on the [Building Redox](https://doc.redox-os.org/book/podman-build.html) page.
|
||||
|
||||
This is necessary because they only work with cross-compilation to a Redox virtual machine, but you can do some testing from Linux.
|
||||
@@ -0,0 +1,50 @@
|
||||
use redox_scheme::{RequestKind, SignalBehavior, Socket, V2};
|
||||
use std::env;
|
||||
use std::fs::OpenOptions;
|
||||
use std::process;
|
||||
|
||||
use crate::scheme::LogScheme;
|
||||
|
||||
mod scheme;
|
||||
|
||||
fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
let mut files = Vec::new();
|
||||
for arg in env::args().skip(1) {
|
||||
eprintln!("logd: opening {:?}", arg);
|
||||
match OpenOptions::new().write(true).open(&arg) {
|
||||
Ok(file) => files.push(file),
|
||||
Err(err) => eprintln!("logd: failed to open {:?}: {:?}", arg, err),
|
||||
}
|
||||
}
|
||||
|
||||
let socket = Socket::<V2>::create("log").expect("logd: failed to create log scheme");
|
||||
|
||||
libredox::call::setrens(0, 0).expect("logd: failed to enter null namespace");
|
||||
|
||||
eprintln!("logd: ready for logging on log:");
|
||||
|
||||
daemon.ready().expect("logd: failed to notify parent");
|
||||
|
||||
let mut scheme = LogScheme::new(files);
|
||||
|
||||
while let Some(request) = socket
|
||||
.next_request(SignalBehavior::Restart)
|
||||
.expect("logd: failed to read events from log scheme")
|
||||
{
|
||||
scheme.current_pid = request.context_id();
|
||||
|
||||
let RequestKind::Call(request) = request.kind() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let response = request.handle_scheme_mut(&mut scheme);
|
||||
socket
|
||||
.write_responses(&[response], SignalBehavior::Restart)
|
||||
.expect("logd: failed to write responses to log scheme");
|
||||
}
|
||||
process::exit(0);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
redox_daemon::Daemon::new(daemon).expect("logd: failed to daemonize");
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
|
||||
use redox_scheme::SchemeMut;
|
||||
use syscall::error::*;
|
||||
|
||||
pub struct LogHandle {
|
||||
context: Box<str>,
|
||||
bufs: BTreeMap<usize, Vec<u8>>,
|
||||
}
|
||||
|
||||
pub struct LogScheme {
|
||||
next_id: usize,
|
||||
files: Vec<File>,
|
||||
handles: BTreeMap<usize, LogHandle>,
|
||||
pub current_pid: usize,
|
||||
}
|
||||
|
||||
impl LogScheme {
|
||||
pub fn new(files: Vec<File>) -> Self {
|
||||
LogScheme {
|
||||
next_id: 0,
|
||||
files,
|
||||
handles: BTreeMap::new(),
|
||||
current_pid: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SchemeMut for LogScheme {
|
||||
fn open(&mut self, path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
|
||||
self.handles.insert(
|
||||
id,
|
||||
LogHandle {
|
||||
context: path.to_string().into_boxed_str(),
|
||||
bufs: BTreeMap::new(),
|
||||
},
|
||||
);
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
fn dup(&mut self, old_id: usize, buf: &[u8]) -> Result<usize> {
|
||||
if !buf.is_empty() {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
|
||||
let context = {
|
||||
let handle = self.handles.get(&old_id).ok_or(Error::new(EBADF))?;
|
||||
handle.context.clone()
|
||||
};
|
||||
|
||||
let id = self.next_id;
|
||||
self.next_id += 1;
|
||||
|
||||
self.handles.insert(
|
||||
id,
|
||||
LogHandle {
|
||||
context,
|
||||
bufs: BTreeMap::new(),
|
||||
},
|
||||
);
|
||||
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
fn read(&mut self, id: usize, _buf: &mut [u8], _offset: u64, _flags: u32) -> Result<usize> {
|
||||
let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
// TODO
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn write(&mut self, id: usize, buf: &[u8], _offset: u64, _flags: u32) -> Result<usize> {
|
||||
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
let handle_buf = handle
|
||||
.bufs
|
||||
.entry(self.current_pid)
|
||||
.or_insert_with(|| Vec::new());
|
||||
|
||||
let mut i = 0;
|
||||
while i < buf.len() {
|
||||
let b = buf[i];
|
||||
|
||||
if handle_buf.is_empty() && !handle.context.is_empty() {
|
||||
handle_buf.extend_from_slice(handle.context.as_bytes());
|
||||
handle_buf.extend_from_slice(b": ");
|
||||
}
|
||||
|
||||
handle_buf.push(b);
|
||||
|
||||
if b == b'\n' {
|
||||
for file in self.files.iter_mut() {
|
||||
let _ = file.write(&handle_buf);
|
||||
let _ = file.flush();
|
||||
}
|
||||
|
||||
handle_buf.clear();
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
|
||||
Ok(i)
|
||||
}
|
||||
|
||||
fn fcntl(&mut self, id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
|
||||
let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
let scheme_path = b"log:";
|
||||
|
||||
let mut i = 0;
|
||||
while i < buf.len() && i < scheme_path.len() {
|
||||
buf[i] = scheme_path[i];
|
||||
i += 1;
|
||||
}
|
||||
|
||||
let mut j = 0;
|
||||
let context_bytes = handle.context.as_bytes();
|
||||
while i < buf.len() && j < context_bytes.len() {
|
||||
buf[i] = context_bytes[j];
|
||||
i += 1;
|
||||
j += 1;
|
||||
}
|
||||
|
||||
Ok(i)
|
||||
}
|
||||
|
||||
fn fsync(&mut self, id: usize) -> Result<usize> {
|
||||
let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
//TODO: flush remaining data?
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn close(&mut self, id: usize) -> Result<usize> {
|
||||
self.handles.remove(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
//TODO: flush remaining data?
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user