the log wrapper in C/C++ accepts formats
This commit is contained in:
@@ -23,3 +23,15 @@ target_link_libraries(pam_usercontainer PRIVATE ${RUST_STATICLIB})
|
||||
|
||||
# Install target
|
||||
install(TARGETS pam_usercontainer DESTINATION lib/security)
|
||||
|
||||
# Examples: small programs demonstrating logging wrappers
|
||||
set_source_files_properties(examples/logging_example.c PROPERTIES LANGUAGE CXX)
|
||||
add_executable(logging_example_c examples/logging_example.c)
|
||||
target_include_directories(logging_example_c PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
add_dependencies(logging_example_c rust_backend_build)
|
||||
target_link_libraries(logging_example_c PRIVATE ${RUST_STATICLIB})
|
||||
|
||||
add_executable(logging_example_cpp examples/logging_example.cpp)
|
||||
target_include_directories(logging_example_cpp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
add_dependencies(logging_example_cpp rust_backend_build)
|
||||
target_link_libraries(logging_example_cpp PRIVATE ${RUST_STATICLIB})
|
||||
|
||||
18
pam-module/examples/logging_example.c
Normal file
18
pam-module/examples/logging_example.c
Normal file
@@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// C example demonstrating printf-style Rust logging wrapper
|
||||
|
||||
#include "../include/rust_backend_ffi.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
(void)argc; (void)argv;
|
||||
// Ensure logger is initialized (nullptr -> default path)
|
||||
rust_init_logging(NULL);
|
||||
|
||||
const char* user = "alice";
|
||||
int result = 0; // pretend success
|
||||
|
||||
RUST_LOGF_INFO("C example: user=%s authenticated=%d", user, result);
|
||||
RUST_LOGF_DEBUG("C example: debug details: x=%d y=%d", 10, 20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
17
pam-module/examples/logging_example.cpp
Normal file
17
pam-module/examples/logging_example.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// C++ example demonstrating stream-style Rust logging wrapper
|
||||
|
||||
#include "../include/rust_backend_ffi.h"
|
||||
#include <string>
|
||||
|
||||
int main() {
|
||||
rust_init_logging(nullptr);
|
||||
|
||||
std::string user = "bob";
|
||||
bool ok = true;
|
||||
|
||||
RUST_COUT() << "C++ example: user=" << user << " authenticated=" << (ok?"yes":"no") << std::flush;
|
||||
RUST_CERR() << "C++ example: an error message for user=" << user << std::flush;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -44,3 +44,9 @@ void rust_log_event_with_level(const char* event, RustLogLevel level);
|
||||
#define RUST_LOG_DEBUG(msg) rust_log_event_with_level((msg), RUST_LOG_LEVEL_DEBUG)
|
||||
#define RUST_LOG_TRACE(msg) rust_log_event_with_level((msg), RUST_LOG_LEVEL_TRACE)
|
||||
|
||||
// C wrapper: printf-style helpers (header-only)
|
||||
#include "rust_backend_logging_c.h"
|
||||
#ifdef __cplusplus
|
||||
#include "rust_backend_logging_cpp.h"
|
||||
#endif
|
||||
|
||||
|
||||
74
pam-module/include/rust_backend_logging_c.h
Normal file
74
pam-module/include/rust_backend_logging_c.h
Normal file
@@ -0,0 +1,74 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// C printf-style wrappers for Rust logging FFI
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "rust_backend_ffi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Buffer size for formatted messages. Documented truncation behavior.
|
||||
#define RUST_LOG_FMT_BUFSZ 2048
|
||||
|
||||
static inline void rust_log_vprintf_level(RustLogLevel level, const char* fmt, va_list ap) {
|
||||
if (fmt == NULL) {
|
||||
rust_log_event_with_level("(null format)", level);
|
||||
return;
|
||||
}
|
||||
char buf[RUST_LOG_FMT_BUFSZ];
|
||||
int ret = vsnprintf(buf, RUST_LOG_FMT_BUFSZ, fmt, ap);
|
||||
if (ret < 0) {
|
||||
rust_log_event_with_level("(format error)", level);
|
||||
return;
|
||||
}
|
||||
// vsnprintf guarantees NUL-termination as long as size>0
|
||||
buf[RUST_LOG_FMT_BUFSZ - 1] = '\0';
|
||||
rust_log_event_with_level(buf, level);
|
||||
}
|
||||
|
||||
static inline void rust_log_printf_level(RustLogLevel level, const char* fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
rust_log_vprintf_level(level, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
// Convenience per-level functions
|
||||
static inline void rust_logf_fatal(const char* fmt, ...) {
|
||||
va_list ap; va_start(ap, fmt); rust_log_vprintf_level(RUST_LOG_LEVEL_FATAL, fmt, ap); va_end(ap);
|
||||
}
|
||||
static inline void rust_logf_error(const char* fmt, ...) {
|
||||
va_list ap; va_start(ap, fmt); rust_log_vprintf_level(RUST_LOG_LEVEL_ERROR, fmt, ap); va_end(ap);
|
||||
}
|
||||
static inline void rust_logf_warn(const char* fmt, ...) {
|
||||
va_list ap; va_start(ap, fmt); rust_log_vprintf_level(RUST_LOG_LEVEL_WARN, fmt, ap); va_end(ap);
|
||||
}
|
||||
static inline void rust_logf_info(const char* fmt, ...) {
|
||||
va_list ap; va_start(ap, fmt); rust_log_vprintf_level(RUST_LOG_LEVEL_INFO, fmt, ap); va_end(ap);
|
||||
}
|
||||
static inline void rust_logf_debug(const char* fmt, ...) {
|
||||
va_list ap; va_start(ap, fmt); rust_log_vprintf_level(RUST_LOG_LEVEL_DEBUG, fmt, ap); va_end(ap);
|
||||
}
|
||||
static inline void rust_logf_trace(const char* fmt, ...) {
|
||||
va_list ap; va_start(ap, fmt); rust_log_vprintf_level(RUST_LOG_LEVEL_TRACE, fmt, ap); va_end(ap);
|
||||
}
|
||||
|
||||
// Convenience macros for C/C++ callers (variadic macro)
|
||||
// Support both C99 and C++ compilers that support variadic macros
|
||||
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus)
|
||||
#define RUST_LOGF_FATAL(fmt, ...) rust_log_printf_level(RUST_LOG_LEVEL_FATAL, (fmt), ##__VA_ARGS__)
|
||||
#define RUST_LOGF_ERROR(fmt, ...) rust_log_printf_level(RUST_LOG_LEVEL_ERROR, (fmt), ##__VA_ARGS__)
|
||||
#define RUST_LOGF_WARN(fmt, ...) rust_log_printf_level(RUST_LOG_LEVEL_WARN, (fmt), ##__VA_ARGS__)
|
||||
#define RUST_LOGF_INFO(fmt, ...) rust_log_printf_level(RUST_LOG_LEVEL_INFO, (fmt), ##__VA_ARGS__)
|
||||
#define RUST_LOGF_DEBUG(fmt, ...) rust_log_printf_level(RUST_LOG_LEVEL_DEBUG, (fmt), ##__VA_ARGS__)
|
||||
#define RUST_LOGF_TRACE(fmt, ...) rust_log_printf_level(RUST_LOG_LEVEL_TRACE, (fmt), ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
75
pam-module/include/rust_backend_logging_cpp.h
Normal file
75
pam-module/include/rust_backend_logging_cpp.h
Normal file
@@ -0,0 +1,75 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// C++ stream-style wrappers for Rust logging FFI
|
||||
|
||||
#pragma once
|
||||
|
||||
// This header expects `rust_backend_ffi.h` to have been included first
|
||||
// so that `RustLogLevel` and `rust_log_event_with_level` are available.
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
|
||||
class RustLogStream {
|
||||
public:
|
||||
explicit RustLogStream(RustLogLevel level) noexcept : level_(level) {}
|
||||
|
||||
// Generic stream insertion
|
||||
template<typename T>
|
||||
RustLogStream& operator<<(const T& v) {
|
||||
try {
|
||||
oss_ << v;
|
||||
} catch (...) {
|
||||
// swallow; avoid exceptions crossing FFI
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Support manipulators like std::endl
|
||||
RustLogStream& operator<<(std::ostream& (*manip)(std::ostream&)) {
|
||||
try {
|
||||
manip(oss_);
|
||||
} catch (...) {
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Destructor emits buffered message
|
||||
~RustLogStream() noexcept {
|
||||
try {
|
||||
const std::string s = oss_.str();
|
||||
if (!s.empty()) {
|
||||
rust_log_event_with_level(s.c_str(), level_);
|
||||
}
|
||||
} catch (...) {
|
||||
// never throw
|
||||
}
|
||||
}
|
||||
|
||||
// Non-copyable
|
||||
RustLogStream(const RustLogStream&) = delete;
|
||||
RustLogStream& operator=(const RustLogStream&) = delete;
|
||||
|
||||
// Movable
|
||||
RustLogStream(RustLogStream&&) = default;
|
||||
RustLogStream& operator=(RustLogStream&&) = default;
|
||||
|
||||
private:
|
||||
RustLogLevel level_;
|
||||
std::ostringstream oss_;
|
||||
};
|
||||
|
||||
// Factories and macros
|
||||
inline RustLogStream rust_log_info_stream() { return RustLogStream(RUST_LOG_LEVEL_INFO); }
|
||||
inline RustLogStream rust_log_warn_stream() { return RustLogStream(RUST_LOG_LEVEL_WARN); }
|
||||
inline RustLogStream rust_log_error_stream() { return RustLogStream(RUST_LOG_LEVEL_ERROR); }
|
||||
inline RustLogStream rust_log_debug_stream() { return RustLogStream(RUST_LOG_LEVEL_DEBUG); }
|
||||
inline RustLogStream rust_log_trace_stream() { return RustLogStream(RUST_LOG_LEVEL_TRACE); }
|
||||
inline RustLogStream rust_log_fatal_stream() { return RustLogStream(RUST_LOG_LEVEL_FATAL); }
|
||||
|
||||
#define RUST_COUT() rust_log_info_stream()
|
||||
#define RUST_CERR() rust_log_error_stream()
|
||||
#define RUST_CDEBUG() rust_log_debug_stream()
|
||||
|
||||
// Usage example:
|
||||
// RUST_COUT() << "User=" << user << " logged in" << std::endl;
|
||||
@@ -15,7 +15,7 @@ extern "C" {
|
||||
int pam_sm_authenticate(pam_handle_t* pamh, int flags, int argc, const char** argv) {
|
||||
try {
|
||||
rust_init_logging(nullptr); // Ensure logger is initialized
|
||||
RUST_LOG_INFO("PAM authentication attempt");
|
||||
RUST_CDEBUG() << "PAM authentication attempt" << std::flush;
|
||||
|
||||
|
||||
const char* user = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user