#include <stddef.h>
#include <stdio.h>
#include <stumpless/config.h>
#include <stumpless/target.h>
#include <stumpless/target/file.h>
#include "private/config/wrapper/locale.h"
#include "private/config/wrapper/thread_safety.h"
#include "private/error.h"
#include "private/inthelper.h"
#include "private/memory.h"
#include "private/target.h"
#include "private/target/file.h"
#include "private/validate.h"
#include "private/config/wrapper/fopen.h"
void
stumpless_close_file_target( struct stumpless_target *target ) {
if( !target ) {
raise_argument_empty( L10N_NULL_ARG_ERROR_MESSAGE( "target" ) );
return;
}
if( target->type != STUMPLESS_FILE_TARGET ) {
raise_target_incompatible( L10N_INVALID_TARGET_TYPE_ERROR_MESSAGE );
return;
}
destroy_file_target( target->id );
destroy_target( target );
clear_error( );
}
struct stumpless_target *
stumpless_open_file_target( const char *name ) {
struct stumpless_target *target;
VALIDATE_ARG_NOT_NULL( name );
target = new_target( STUMPLESS_FILE_TARGET, name );
if( !target ) {
goto fail;
}
target->id = new_file_target( name );
if( !target->id ) {
goto fail_id;
}
stumpless_set_current_target( target );
return target;
fail_id:
destroy_target( target );
fail:
return NULL;
}
void
destroy_file_target( struct file_target *target ) {
config_destroy_mutex( &target->stream_mutex );
fclose( target->stream );
free_mem( target );
}
struct stumpless_target *
file_open_default_target( void ) {
return stumpless_open_file_target( STUMPLESS_DEFAULT_FILE );
}
struct file_target *
new_file_target( const char *filename ) {
struct file_target *target;
target = alloc_mem( sizeof( *target ) );
if( !target ) {
goto fail;
}
target->stream = config_fopen( filename, "a" );
if( !target->stream ) {
raise_file_open_failure( );
goto fail_stream;
}
config_init_mutex( &target->stream_mutex );
return target;
fail_stream:
free_mem( target );
fail:
return NULL;
}
int
sendto_file_target( struct file_target *target,
const char *msg,
size_t msg_length ) {
size_t fwrite_result;
config_lock_mutex( &target->stream_mutex );
fwrite_result = fwrite( msg, sizeof( char ), msg_length, target->stream );
config_unlock_mutex( &target->stream_mutex );
if( fwrite_result != msg_length ) {
goto write_failure;
}
return cap_size_t_to_int( fwrite_result + 1 );
write_failure:
raise_file_write_failure( );
return -1;
}