Implemented the POSIX syslog API including the BeOS extensions. In BeOS,
this API is found in libbe.so, in OpenBeOS, it's directly in libroot.so. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5326 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
7aaeb3f35a
commit
3b737adbda
@ -1,5 +1,7 @@
|
||||
SubDir OBOS_TOP src kernel libroot posix ;
|
||||
|
||||
UsePrivateHeaders [ FDirName syslog_daemon ] ;
|
||||
|
||||
KernelMergeObject posix_main.o :
|
||||
<$(SOURCE_GRIST)>dlfcn.c
|
||||
<$(SOURCE_GRIST)>errno.c
|
||||
@ -8,6 +10,7 @@ KernelMergeObject posix_main.o :
|
||||
<$(SOURCE_GRIST)>poll.c
|
||||
<$(SOURCE_GRIST)>pwd.c
|
||||
<$(SOURCE_GRIST)>rlimit.c
|
||||
<$(SOURCE_GRIST)>syslog.cpp
|
||||
<$(SOURCE_GRIST)>utime.c
|
||||
:
|
||||
-fPIC -DPIC
|
||||
@ -34,4 +37,6 @@ SubInclude OBOS_TOP src kernel libroot posix string ;
|
||||
SubInclude OBOS_TOP src kernel libroot posix sys ;
|
||||
SubInclude OBOS_TOP src kernel libroot posix termios ;
|
||||
SubInclude OBOS_TOP src kernel libroot posix time ;
|
||||
SubInclude OBOS_TOP src kernel libroot posix unistd ;
|
||||
SubInclude OBOS_TOP src kernel libroot posix unistd ;
|
||||
|
||||
#SubInclude OBOS_TOP src kernel libroot posix glibc ;
|
||||
|
246
src/kernel/libroot/posix/syslog.cpp
Normal file
246
src/kernel/libroot/posix/syslog.cpp
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
|
||||
|
||||
#include <syslog_daemon.h>
|
||||
#include <TLS.h>
|
||||
|
||||
#include <syslog.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
struct syslog_context {
|
||||
char ident[B_OS_NAME_LENGTH];
|
||||
int32 mask;
|
||||
int32 options;
|
||||
};
|
||||
|
||||
static syslog_context sTeamContext;
|
||||
static int32 sThreadContextSlot = -1;
|
||||
|
||||
|
||||
static syslog_context *
|
||||
allocate_context()
|
||||
{
|
||||
syslog_context *context = (syslog_context *)malloc(sizeof(syslog_context));
|
||||
if (context == NULL)
|
||||
return NULL;
|
||||
|
||||
// inherit the attributes of the team context
|
||||
memcpy(context, &sTeamContext, sizeof(syslog_context));
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
/** This function returns the current syslog context structure.
|
||||
* If there is none for the current thread, it will create one
|
||||
* that inherits the context attributes from the team and put it
|
||||
* into TLS.
|
||||
* If it could not allocate a thread context, it will return the
|
||||
* team context; this function is guaranteed to return a valid
|
||||
* syslog context.
|
||||
*/
|
||||
|
||||
static syslog_context *
|
||||
get_context()
|
||||
{
|
||||
if (sThreadContextSlot == B_NO_MEMORY)
|
||||
return &sTeamContext;
|
||||
|
||||
if (sThreadContextSlot < 0) {
|
||||
static int32 lock = 0;
|
||||
if (atomic_add(&lock, 1) == 0) {
|
||||
int32 slot = tls_allocate();
|
||||
|
||||
if (slot < 0) {
|
||||
sThreadContextSlot = B_NO_MEMORY;
|
||||
return &sTeamContext;
|
||||
}
|
||||
|
||||
*tls_address(slot) = allocate_context();
|
||||
sThreadContextSlot = slot;
|
||||
return (syslog_context *)tls_get(slot);
|
||||
} else {
|
||||
while (sThreadContextSlot == -1)
|
||||
snooze(10000);
|
||||
}
|
||||
}
|
||||
|
||||
syslog_context *context = (syslog_context *)tls_get(sThreadContextSlot);
|
||||
if (context == NULL) {
|
||||
// try to allocate the context again; it might have
|
||||
// been deleted, or there was not enough memory last
|
||||
// time
|
||||
context = allocate_context();
|
||||
}
|
||||
if (context != NULL)
|
||||
return context;
|
||||
|
||||
return &sTeamContext;
|
||||
}
|
||||
|
||||
|
||||
/** Creates the message from the given context and sends it to the syslog
|
||||
* daemon, if the priority mask matches.
|
||||
* If the message couldn't be delivered, and LOG_CONS was set, it will
|
||||
* redirect the message to stderr.
|
||||
*/
|
||||
|
||||
static void
|
||||
send_syslog_message(syslog_context *context, int priority, const char *text, va_list args)
|
||||
{
|
||||
// do we have to do anything?
|
||||
if ((context->mask & LOG_MASK(priority)) == 0)
|
||||
return;
|
||||
|
||||
port_id port = find_port("syslog_daemon");
|
||||
if (port < B_OK) {
|
||||
// apparently, there is no syslog daemon running; if asked
|
||||
// for, print out the (simplified) message on stderr
|
||||
if (context->options & LOG_CONS) {
|
||||
if (context->ident[0])
|
||||
fprintf(stderr, "'%s' ", context->ident);
|
||||
if (context->options & LOG_PID)
|
||||
fprintf(stderr, "[%ld] ", find_thread(NULL));
|
||||
vfprintf(stderr, text, args);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[2048];
|
||||
syslog_message &message = *(syslog_message *)&buffer[0];
|
||||
|
||||
message.from = find_thread(NULL);
|
||||
message.when = real_time_clock();
|
||||
message.options = context->options | priority;
|
||||
strcpy(message.ident, context->ident);
|
||||
|
||||
int length = vsnprintf(message.message, sizeof(buffer) - sizeof(syslog_message), text, args);
|
||||
|
||||
while (write_port(port, SYSLOG_MESSAGE, &message, sizeof(syslog_message) + length) == B_INTERRUPTED);
|
||||
// make sure the message gets send (if there is a valid port)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// public API
|
||||
|
||||
|
||||
void
|
||||
closelog_team(void)
|
||||
{
|
||||
// nothing to do here...
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
openlog_team(const char *ident, int options, int facility)
|
||||
{
|
||||
if (ident != NULL)
|
||||
strcpy(sTeamContext.ident, ident);
|
||||
|
||||
sTeamContext.options = facility | options;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
setlogmask_team(int priorityMask)
|
||||
{
|
||||
sTeamContext.mask = priorityMask;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
log_team(int priority, const char *message, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, message);
|
||||
send_syslog_message(&sTeamContext, priority, message, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
closelog_thread(void)
|
||||
{
|
||||
if (sThreadContextSlot < 0)
|
||||
return;
|
||||
|
||||
free(tls_get(sThreadContextSlot));
|
||||
*tls_address(sThreadContextSlot) = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
openlog_thread(const char *ident, int options, int facility)
|
||||
{
|
||||
syslog_context *context = get_context();
|
||||
|
||||
if (ident)
|
||||
strcpy(context->ident, ident);
|
||||
|
||||
context->options = options | facility;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
setlogmask_thread(int priorityMask)
|
||||
{
|
||||
syslog_context *context = get_context();
|
||||
context->mask = priorityMask;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
log_thread(int priority, const char *message, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, message);
|
||||
send_syslog_message(get_context(), priority, message, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
// POSIX API - just uses the thread syslog functions
|
||||
|
||||
|
||||
void
|
||||
closelog(void)
|
||||
{
|
||||
closelog_thread();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
openlog(const char *ident, int options, int facility)
|
||||
{
|
||||
openlog_thread(ident, options, facility);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
setlogmask(int priorityMask)
|
||||
{
|
||||
setlogmask_thread(priorityMask);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
syslog(int priority, const char *message, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, message);
|
||||
send_syslog_message(get_context(), priority, message, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user