Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add syslog supports #2537

Merged
merged 26 commits into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 20 additions & 19 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
[package]
name = "nix"
name = "nix"
description = "Rust friendly bindings to *nix APIs"
edition = "2021"
version = "0.29.0"
edition = "2021"
version = "0.29.0"
rust-version = "1.69"
authors = ["The nix-rust Project Developers"]
repository = "https://github.com/nix-rust/nix"
license = "MIT"
categories = ["os::unix-apis"]
authors = ["The nix-rust Project Developers"]
repository = "https://github.com/nix-rust/nix"
license = "MIT"
categories = ["os::unix-apis"]
include = ["build.rs", "src/**/*", "test/**/*", "LICENSE", "README.md", "CHANGELOG.md"]

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
targets = [
"x86_64-unknown-linux-gnu",
"aarch64-linux-android",
"x86_64-apple-darwin",
"aarch64-apple-ios",
"x86_64-unknown-freebsd",
"x86_64-unknown-openbsd",
"x86_64-unknown-netbsd",
"x86_64-unknown-dragonfly",
"x86_64-fuchsia",
"x86_64-unknown-redox",
"x86_64-unknown-illumos"
tisonkun marked this conversation as resolved.
Show resolved Hide resolved
"x86_64-unknown-linux-gnu",
"aarch64-linux-android",
"x86_64-apple-darwin",
"aarch64-apple-ios",
"x86_64-unknown-freebsd",
"x86_64-unknown-openbsd",
"x86_64-unknown-netbsd",
"x86_64-unknown-dragonfly",
"x86_64-fuchsia",
"x86_64-unknown-redox",
"x86_64-unknown-illumos"
]

[dependencies]
Expand Down Expand Up @@ -64,6 +64,7 @@ resource = []
sched = ["process"]
signal = ["process"]
socket = ["memoffset"]
syslog = []
tisonkun marked this conversation as resolved.
Show resolved Hide resolved
term = []
time = []
ucontext = ["signal"]
Expand All @@ -80,7 +81,7 @@ semver = "1.0.7"
nix = { path = ".", features = ["acct", "aio", "dir", "env", "event", "fanotify",
"feature", "fs", "hostname", "inotify", "ioctl", "kmod", "mman", "mount", "mqueue",
"net", "personality", "poll", "pthread", "ptrace", "quota", "process", "reboot",
"resource", "sched", "signal", "socket", "term", "time", "ucontext", "uio",
"resource", "sched", "signal", "socket", "syslog", "term", "time", "ucontext", "uio",
"user", "zerocopy"] }

[target.'cfg(any(target_os = "android", target_os = "linux"))'.dev-dependencies]
Expand Down
1 change: 1 addition & 0 deletions changelog/2537.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for `syslog`, `openlog`, `closelog` on `macos`.
tisonkun marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 6 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,12 @@ feature! {
pub mod spawn;
}

#[cfg(target_os = "macos")]
feature! {
#![feature = "syslog"]
pub mod syslog;
}

use std::ffi::{CStr, CString, OsStr};
use std::mem::MaybeUninit;
use std::os::unix::ffi::OsStrExt;
Expand Down
146 changes: 146 additions & 0 deletions src/syslog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
//! Interfaces for controlling system log.

use crate::NixPath;
use crate::Result;
use std::ffi::OsStr;

/// Logging options of subsequent [`syslog`] calls can be set by calling [`openlog`].
///
/// The parameter `ident` is a string that will be prepended to every message. The `logopt`
/// argument specifies logging options. The `facility` parameter encodes a default facility to be
/// assigned to all messages that do not have an explicit facility encoded.
pub fn openlog<P: NixPath + ?Sized>(
ident: &P,
tisonkun marked this conversation as resolved.
Show resolved Hide resolved
logopt: LogFlags,
facility: Facility,
) -> Result<()> {
ident.with_nix_path(|ident| unsafe {
libc::openlog(ident.as_ptr(), logopt.bits(), facility as libc::c_int);
})
}

/// Writes message to the system message logger.
///
/// The message is then written to the system console, log files, logged-in users, or forwarded
/// to other machines as appropriate.
pub fn syslog<S: AsRef<OsStr> + ?Sized>(
tisonkun marked this conversation as resolved.
Show resolved Hide resolved
priority: Priority,
message: &S,
) -> Result<()> {
let formatter = OsStr::new("%s");
tisonkun marked this conversation as resolved.
Show resolved Hide resolved
let message = OsStr::new(message);
formatter.with_nix_path(|formatter| {
message.with_nix_path(|message| unsafe {
libc::syslog(priority.0, formatter.as_ptr(), message.as_ptr())
})
})??;
Ok(())
}

/// The priority for a log message.
#[derive(Debug, Clone, Copy)]
pub struct Priority(libc::c_int);

impl Priority {
/// Create a new priority from a severity level.
pub fn from_severity(severity: Severity) -> Self {
let priority = severity as libc::c_int;
Priority(priority)
}

/// Create a new priority from a facility and severity level.
pub fn from(severity: Severity, facility: Facility) -> Self {
let priority = (facility as libc::c_int) | (severity as libc::c_int);
Priority(priority)
}
}

libc_bitflags! {
/// Options for system logging.
pub struct LogFlags: libc::c_int {
tisonkun marked this conversation as resolved.
Show resolved Hide resolved
/// Log the process id with each message: useful for identifying instantiations of
/// daemons.
LOG_PID;
/// If syslog() cannot pass the message to syslogd(8) it will attempt to write the
/// message to the console ("/dev/console").
LOG_CONS;
/// Open the connection to syslogd(8) immediately. Normally the open is delayed until
/// the first message is logged. Useful for programs that need to manage the order in
/// which file descriptors are allocated.
LOG_NDELAY;
/// Write the message to standard error output as well to the system log.
LOG_PERROR;
}
}

libc_enum! {
/// Severity levels for log messages.
#[repr(i32)]
#[non_exhaustive]
pub enum Severity {
tisonkun marked this conversation as resolved.
Show resolved Hide resolved
/// A panic condition.
///
/// This is normally broadcast to all users.
LOG_EMERG,
/// A condition that should be corrected immediately, such as a corrupted system database.
LOG_ALERT,
/// Critical conditions, e.g., hard device errors.
LOG_CRIT,
/// Errors.
LOG_ERR,
/// Warning messages.
LOG_WARNING,
/// Conditions that are not error conditions, but should possibly be handled specially.
LOG_NOTICE,
/// Informational messages.
LOG_INFO,
/// Messages that contain information normally of use only when debugging a program.
LOG_DEBUG,
}
}

libc_enum! {
/// Facilities for log messages.
#[repr(i32)]
#[non_exhaustive]
pub enum Facility {
/// Messages generated by the kernel.
///
/// These cannot be generated by any user processes.
LOG_KERN,
/// Messages generated by random user processes.
///
/// This is the default facility identifier if none is specified.
LOG_USER,
/// The mail system.
LOG_MAIL,
/// System daemons, such as routed(8), that are not provided for explicitly by other facilities.
LOG_DAEMON,
/// The authorization system: login(1), su(1), getty(8), etc.
LOG_AUTH,
/// Messages generated internally by syslogd(8).
LOG_SYSLOG,
/// The line printer spooling system: cups-lpd(8), cupsd(8), etc.
LOG_LPR,
/// The network news system.
LOG_NEWS,
/// The uucp system.
LOG_UUCP,
/// Reserved for local use.
LOG_LOCAL0,
/// Reserved for local use.
LOG_LOCAL1,
/// Reserved for local use.
LOG_LOCAL2,
/// Reserved for local use.
LOG_LOCAL3,
/// Reserved for local use.
LOG_LOCAL4,
/// Reserved for local use.
LOG_LOCAL5,
/// Reserved for local use.
LOG_LOCAL6,
/// Reserved for local use.
LOG_LOCAL7,
}
}
3 changes: 3 additions & 0 deletions test/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ mod test_sendfile;
))]
mod test_spawn;

#[cfg(target_os = "macos")]
mod test_syslog;

mod test_time;
mod test_unistd;

Expand Down
9 changes: 9 additions & 0 deletions test/test_syslog.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use nix::syslog::{openlog, syslog, Facility, LogFlags, Priority, Severity};

#[test]
fn test_syslog_hello_world() {
let name = "test_syslog_hello_world";
let priority = Priority::from_severity(Severity::LOG_EMERG);
openlog(name, LogFlags::LOG_PID, Facility::LOG_USER).unwrap();
syslog(priority, "Hello, nix!").unwrap();
}