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:
Axel Dörfler 2003-11-12 14:35:22 +00:00
parent 7aaeb3f35a
commit 3b737adbda
2 changed files with 252 additions and 1 deletions

View File

@ -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 ;

View 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);
}