1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/sys/logd/logd.c

194 lines
5.1 KiB
C
Raw Normal View History

/******************************************************************************
Copyright 2009-2010, Freie Universitaet Berlin (FUB). All rights reserved.
These sources were developed at the Freie Universitaet Berlin, Computer Systems
and Telematics group (http://cst.mi.fu-berlin.de).
-------------------------------------------------------------------------------
This file is part of RIOT.
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
RIOT 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 General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see http://www.gnu.org/licenses/ .
--------------------------------------------------------------------------------
For further information and questions please use the web site
http://scatterweb.mi.fu-berlin.de
and the mailinglist (subscription via web site)
scatterweb@lists.spline.inf.fu-berlin.de
*******************************************************************************/
/**
* @file
* @brief Simple logging demon implementation
*
* @author Freie Universität Berlin, Computer Systems & Telematics
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
* @version $Revision: 3854 $
*
* @note $Id: logd.c 3854 2011-12-06 15:27:01Z hwill $
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
// core
#include "msg.h"
#include "flags.h"
#include "mutex.h"
#include "thread.h"
#include "kernel.h"
// system
#include "logd.h"
#include "list.h"
typedef struct log_queue_t
{
list_node_t listnode;
char* str;
int str_len;
} log_queue_t;
static volatile int log_pid = -1;
static int logd_stack_size = LOGD_STACK_SIZE_NORMAL;
static FILE* fh = NULL;
static int log_count = 0;
static mutex_t log_mutex;
static list_t log_msg_queue;
static volatile bool exit_flag = false;
static volatile bool echo_on = false;
/*---------------------------------------------------------------------------*/
static void close_file_handle(void)
{
if (fh != NULL) {
fclose(fh);
fh = NULL;
}
}
static void write_to_file(char* str, int str_len)
{
if (fh != NULL && str_len > 0) {
if (fwrite(str, sizeof(char), str_len, fh) != str_len) {
if (echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) {
printf("LOGD [WARN]: file write failed, closing file\n");
}
close_file_handle();
return;
}
if (fflush(fh) == EOF) {
if (echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) {
printf("LOGD [WARN]: file write failed, closing file\n");
}
close_file_handle();
return;
}
} else {
fh = fopen("/LOGD.LOG", "w");
if (!fh) {
if (echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) {
printf("LOGD [WARN]: file reopen failed, damn!\n");
}
} else {
write_to_file(str, str_len);
}
}
}
static void logd_process(void)
{
msg m;
log_queue_t* node;
do
{
if (!exit_flag) msg_receive(&m);
mutex_lock(&log_mutex);
while ((node = (log_queue_t*) list_remove_head(&log_msg_queue)) != NULL) {
write_to_file(node->str, node->str_len);
if (echo_on && logd_stack_size >= LOGD_STACK_SIZE_CONSOLE) {
printf("%s", node->str);
}
log_count++;
free(node->str);
free(node);
}
mutex_unlock(&log_mutex, 0);
} while (m.type != MSG_EXIT && !exit_flag);
/* Logging thread is terminating, close log file */
close_file_handle();
}
/*---------------------------------------------------------------------------*/
static void logd_init0(void) {
fh = fopen("/LOGD.LOG", "w");
if (!fh) return;
log_pid = thread_create(logd_stack_size, PRIORITY_LOGD, CREATE_STACKTEST, logd_process, "logd");
}
void logd_init(int stack_size)
{
logd_stack_size = stack_size;
mutex_init(&log_mutex);
list_init(&log_msg_queue);
logd_init0();
}
void logd_set_console_enabled(bool enabled)
{
echo_on = enabled;
}
bool logd_log(char* str, int str_len)
{
msg m;
// Test if logd process was created
if (log_pid == -1) {
// no logd created, because fopen() on log file failed. So try again
logd_init0();
if (log_pid == -1) {
// Still errors opening log file, exit now
return false;
}
}
log_queue_t* lq = malloc(sizeof(*lq));
if (lq == NULL) return false;
lq->str = malloc(sizeof(char) * str_len + 1); // 1 byte for string termination char
if (lq->str == NULL) {
free(lq);
return false;
}
strncpy(lq->str, str, str_len);
lq->str_len = str_len;
lq->str[str_len] = '\0'; // add string termination char at end of buffer
mutex_lock(&log_mutex);
list_append(&log_msg_queue, (list_node_t*) lq);
mutex_unlock(&log_mutex, 0);
m.type = MSG_POLL;
m.content.ptr = NULL;
msg_send(&m, log_pid, false);
return true;
}
void logd_exit(void)
{
msg m;
// Test if logd process was created
if (log_pid == -1) {
return;
}
exit_flag = true;
m.type = MSG_EXIT;
m.content.ptr = NULL;
msg_send(&m, log_pid, false);
}