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 ;
|
SubDir OBOS_TOP src kernel libroot posix ;
|
||||||
|
|
||||||
|
UsePrivateHeaders [ FDirName syslog_daemon ] ;
|
||||||
|
|
||||||
KernelMergeObject posix_main.o :
|
KernelMergeObject posix_main.o :
|
||||||
<$(SOURCE_GRIST)>dlfcn.c
|
<$(SOURCE_GRIST)>dlfcn.c
|
||||||
<$(SOURCE_GRIST)>errno.c
|
<$(SOURCE_GRIST)>errno.c
|
||||||
@ -8,6 +10,7 @@ KernelMergeObject posix_main.o :
|
|||||||
<$(SOURCE_GRIST)>poll.c
|
<$(SOURCE_GRIST)>poll.c
|
||||||
<$(SOURCE_GRIST)>pwd.c
|
<$(SOURCE_GRIST)>pwd.c
|
||||||
<$(SOURCE_GRIST)>rlimit.c
|
<$(SOURCE_GRIST)>rlimit.c
|
||||||
|
<$(SOURCE_GRIST)>syslog.cpp
|
||||||
<$(SOURCE_GRIST)>utime.c
|
<$(SOURCE_GRIST)>utime.c
|
||||||
:
|
:
|
||||||
-fPIC -DPIC
|
-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 sys ;
|
||||||
SubInclude OBOS_TOP src kernel libroot posix termios ;
|
SubInclude OBOS_TOP src kernel libroot posix termios ;
|
||||||
SubInclude OBOS_TOP src kernel libroot posix time ;
|
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