From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/lib/direct/log.c | 414 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 414 insertions(+) create mode 100755 Source/DirectFB/lib/direct/log.c (limited to 'Source/DirectFB/lib/direct/log.c') diff --git a/Source/DirectFB/lib/direct/log.c b/Source/DirectFB/lib/direct/log.c new file mode 100755 index 0000000..774b7a5 --- /dev/null +++ b/Source/DirectFB/lib/direct/log.c @@ -0,0 +1,414 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + + +struct __D_DirectLog { + int magic; + + DirectLogType type; + + int fd; + + pthread_mutex_t lock; +}; + +/**********************************************************************************************************************/ + +/* Statically allocated to avoid endless loops between D_CALLOC() and D_DEBUG(), while the latter would only + * call the allocation once, if there wouldn't be the loopback... + */ +static DirectLog fallback_log; + +static DirectLog *default_log = NULL; +static pthread_once_t init_fallback = PTHREAD_ONCE_INIT; + +/**********************************************************************************************************************/ + +static DirectResult init_stderr( DirectLog *log ); + +static DirectResult init_file ( DirectLog *log, + const char *filename ); + +static DirectResult init_udp ( DirectLog *log, + const char *hostport ); + +/**********************************************************************************************************************/ + +DirectResult +direct_log_create( DirectLogType type, + const char *param, + DirectLog **ret_log ) +{ + DirectResult ret = DR_INVARG; + DirectLog *log; + + log = D_CALLOC( 1, sizeof(DirectLog) ); + if (!log) + return D_OOM(); + + log->type = type; + + switch (type) { + case DLT_STDERR: + ret = init_stderr( log ); + break; + + case DLT_FILE: + ret = init_file( log, param ); + break; + + case DLT_UDP: + ret = init_udp( log, param ); + break; + } + + if (ret) + D_FREE( log ); + else { + direct_util_recursive_pthread_mutex_init( &log->lock ); + + D_MAGIC_SET( log, DirectLog ); + + *ret_log = log; + } + + return ret; +} + +DirectResult +direct_log_destroy( DirectLog *log ) +{ + D_MAGIC_ASSERT( log, DirectLog ); + + D_ASSERT( &fallback_log != log ); + + if (log == default_log) + default_log = NULL; + + close( log->fd ); + + D_MAGIC_CLEAR( log ); + + D_FREE( log ); + + return DR_OK; +} + +__attribute__((no_instrument_function)) +DirectResult +direct_log_printf( DirectLog *log, + const char *format, ... ) +{ + va_list args; + + /* + * Don't use D_MAGIC_ASSERT or any other + * macros/functions that might cause an endless loop. + */ + + va_start( args, format ); + + /* Use the default log if passed log is invalid. */ + if (!log || log->magic != D_MAGIC("DirectLog")) + log = direct_log_default(); + + /* Write to stderr as a fallback if default is invalid, too. */ + if (!log || log->magic != D_MAGIC("DirectLog")) { + + printf(format,args); + + + + //vfprintf( stderr, format, args ); + + + + + fflush( stderr ); + } + else { + int len; + char buf[512]; + + len = vsnprintf( buf, sizeof(buf), format, args ); + + pthread_mutex_lock( &log->lock ); + + + + + // write( log->fd, buf, len ); + printf("%s\n",buf); + + + + + pthread_mutex_unlock( &log->lock ); + } + + va_end( args ); + + return DR_OK; +} + +DirectResult +direct_log_set_default( DirectLog *log ) +{ + D_MAGIC_ASSERT( log, DirectLog ); + + default_log = log; + + return DR_OK; +} + +__attribute__((no_instrument_function)) +void +direct_log_lock( DirectLog *log ) +{ + D_MAGIC_ASSERT_IF( log, DirectLog ); + + if (!log) + log = direct_log_default(); + + D_MAGIC_ASSERT( log, DirectLog ); + + pthread_mutex_lock( &log->lock ); +} + +__attribute__((no_instrument_function)) +void +direct_log_unlock( DirectLog *log ) +{ + D_MAGIC_ASSERT_IF( log, DirectLog ); + + if (!log) + log = direct_log_default(); + + D_MAGIC_ASSERT( log, DirectLog ); + + pthread_mutex_unlock( &log->lock ); +} + +__attribute__((no_instrument_function)) +static void +init_fallback_log( void ) +{ + fallback_log.type = DLT_STDERR; + fallback_log.fd = fileno( stderr ); + + direct_util_recursive_pthread_mutex_init( &fallback_log.lock ); + + D_MAGIC_SET( &fallback_log, DirectLog ); +} + +__attribute__((no_instrument_function)) +DirectLog * +direct_log_default( void ) +{ + pthread_once( &init_fallback, init_fallback_log ); + + if (!default_log) + default_log = &fallback_log; + + D_MAGIC_ASSERT( default_log, DirectLog ); + + return default_log; +} + +/**********************************************************************************************************************/ + +static DirectResult +init_stderr( DirectLog *log ) +{ + log->fd = dup( fileno( stderr ) ); + + return DR_OK; +} + +static DirectResult +init_file( DirectLog *log, + const char *filename ) +{ + DirectResult ret; + int fd; + + fd = open( filename, O_WRONLY | O_CREAT | O_APPEND, 0664 ); + if (fd < 0) { + ret = errno2result( errno ); + D_PERROR( "Direct/Log: Could not open '%s' for writing!\n", filename ); + return ret; + } + + log->fd = fd; + + return DR_OK; +} + +static DirectResult +parse_host_addr( const char *hostport, + struct addrinfo **ret_addr ) +{ + int i, ret; + + int size = strlen( hostport ) + 1; + char buf[size]; + + char *hoststr = buf; + char *portstr = NULL; + char *end; + + struct addrinfo hints; + + memcpy( buf, hostport, size ); + + for (i=0; i:'!\n", hostport ); + return DR_INVARG; + } + + strtoul( portstr, &end, 10 ); + if (end && *end) { + D_ERROR( "Direct/Log: Parse error in port number '%s'!\n", portstr ); + return DR_INVARG; + } + + memset( &hints, 0, sizeof(hints) ); + hints.ai_socktype = SOCK_DGRAM; + hints.ai_family = PF_UNSPEC; + + ret = getaddrinfo( hoststr, portstr, &hints, ret_addr ); + if (ret) { + switch (ret) { + case EAI_FAMILY: + D_ERROR( "Direct/Log: Unsupported address family!\n" ); + return DR_UNSUPPORTED; + + case EAI_SOCKTYPE: + D_ERROR( "Direct/Log: Unsupported socket type!\n" ); + return DR_UNSUPPORTED; + + case EAI_NONAME: + D_ERROR( "Direct/Log: Host not found!\n" ); + return DR_FAILURE; + + case EAI_SERVICE: + D_ERROR( "Direct/Log: Port %s is unreachable!\n", portstr ); + return DR_FAILURE; + +#ifdef EAI_ADDRFAMILY + case EAI_ADDRFAMILY: +#endif + case EAI_NODATA: + D_ERROR( "Direct/Log: Host found, but has no address!\n" ); + return DR_FAILURE; + + case EAI_MEMORY: + return D_OOM(); + + case EAI_FAIL: + D_ERROR( "Direct/Log: A non-recoverable name server error occurred!\n" ); + return DR_FAILURE; + + case EAI_AGAIN: + D_ERROR( "Direct/Log: Temporary error, try again!\n" ); + return DR_TEMPUNAVAIL; + + default: + D_ERROR( "Direct/Log: Unknown error occured!?\n" ); + return DR_FAILURE; + } + } + + return DR_OK; +} + +static DirectResult +init_udp( DirectLog *log, + const char *hostport ) +{ + DirectResult ret; + int fd; + struct addrinfo *addr; + + ret = parse_host_addr( hostport, &addr ); + if (ret) + return ret; + + fd = socket( addr->ai_family, SOCK_DGRAM, 0 ); + if (fd < 0) { + ret = errno2result( errno ); + D_PERROR( "Direct/Log: Could not create a UDP socket!\n" ); + freeaddrinfo( addr ); + return ret; + } + + ret = connect( fd, addr->ai_addr, addr->ai_addrlen ); + freeaddrinfo( addr ); + + if (ret) { + ret = errno2result( errno ); + D_PERROR( "Direct/Log: Could not connect UDP socket to '%s'!\n", hostport ); + close( fd ); + return ret; + } + + log->fd = fd; + + return DR_OK; +} -- cgit