syslog: Added multi device support in syslog_device.

This commit is contained in:
Fotis Panagiotopoulos 2021-03-29 15:36:58 +03:00 committed by Xiang Xiao
parent a21d6b884e
commit 1dee243e29
18 changed files with 397 additions and 255 deletions

View File

@ -27,6 +27,7 @@
#include <stdio.h> #include <stdio.h>
#include <nuttx/syslog/syslog.h> #include <nuttx/syslog/syslog.h>
#include <nuttx/compiler.h>
#include "nvic.h" #include "nvic.h"
#include "itm.h" #include "itm.h"
@ -61,22 +62,29 @@
/* SYSLOG channel methods */ /* SYSLOG channel methods */
static int itm_putc(int ch); static int itm_putc(FAR struct syslog_channel_s *channel, int ch);
static int itm_flush(void); static int itm_flush(FAR struct syslog_channel_s *channel);
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
/* This structure describes the ITM SYSLOG channel */ /* This structure describes the ITM SYSLOG channel operations */
static const struct syslog_channel_s g_itm_channel = static const struct syslog_channel_ops_s g_itm_channel_ops =
{ {
.sc_putc = itm_putc, .sc_putc = itm_putc,
.sc_force = itm_putc, .sc_force = itm_putc,
.sc_flush = itm_flush, .sc_flush = itm_flush,
}; };
/* This structure describes the ITM SYSLOG channel */
static const struct syslog_channel_s g_itm_channel =
{
.sc_ops = &g_itm_channel_ops
};
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@ -89,8 +97,10 @@ static const struct syslog_channel_s g_itm_channel =
* *
****************************************************************************/ ****************************************************************************/
static int itm_putc(int ch) static int itm_putc(FAR struct syslog_channel_s *channel, int ch)
{ {
UNUSED(channel);
/* ITM enabled */ /* ITM enabled */
if ((getreg32(ITM_TCR) & ITM_TCR_ITMENA_MASK) == 0) if ((getreg32(ITM_TCR) & ITM_TCR_ITMENA_MASK) == 0)
@ -117,8 +127,9 @@ static int itm_putc(int ch)
* *
****************************************************************************/ ****************************************************************************/
static int itm_flush(void) static int itm_flush(FAR struct syslog_channel_s *channel)
{ {
UNUSED(channel);
return OK; return OK;
} }

View File

@ -27,6 +27,7 @@
#include <stdio.h> #include <stdio.h>
#include <nuttx/syslog/syslog.h> #include <nuttx/syslog/syslog.h>
#include <nuttx/compiler.h>
#include "nvic.h" #include "nvic.h"
#include "itm.h" #include "itm.h"
@ -61,22 +62,29 @@
/* SYSLOG channel methods */ /* SYSLOG channel methods */
static int itm_putc(int ch); static int itm_putc(FAR struct syslog_channel_s *channel, int ch);
static int itm_flush(void); static int itm_flush(FAR struct syslog_channel_s *channel);
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
/* This structure describes the ITM SYSLOG channel */ /* This structure describes the ITM SYSLOG channel operations */
static const struct syslog_channel_s g_itm_channel = static const struct syslog_channel_ops_s g_itm_channel_ops =
{ {
.sc_putc = itm_putc, .sc_putc = itm_putc,
.sc_force = itm_putc, .sc_force = itm_putc,
.sc_flush = itm_flush, .sc_flush = itm_flush,
}; };
/* This structure describes the ITM SYSLOG channel */
static const struct syslog_channel_s g_itm_channel =
{
.sc_ops = &g_itm_channel_ops
};
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@ -89,8 +97,10 @@ static const struct syslog_channel_s g_itm_channel =
* *
****************************************************************************/ ****************************************************************************/
static int itm_putc(int ch) static int itm_putc(FAR struct syslog_channel_s *channel, int ch)
{ {
UNUSED(channel);
/* ITM enabled */ /* ITM enabled */
if ((getreg32(ITM_TCR) & ITM_TCR_ITMENA_MASK) == 0) if ((getreg32(ITM_TCR) & ITM_TCR_ITMENA_MASK) == 0)
@ -117,8 +127,9 @@ static int itm_putc(int ch)
* *
****************************************************************************/ ****************************************************************************/
static int itm_flush(void) static int itm_flush(FAR struct syslog_channel_s *channel)
{ {
UNUSED(channel);
return OK; return OK;
} }

View File

@ -43,6 +43,7 @@
#include <nuttx/semaphore.h> #include <nuttx/semaphore.h>
#include <nuttx/fs/fs.h> #include <nuttx/fs/fs.h>
#include <nuttx/syslog/ramlog.h> #include <nuttx/syslog/ramlog.h>
#include <nuttx/compiler.h>
#include <nuttx/irq.h> #include <nuttx/irq.h>
@ -719,12 +720,14 @@ void ramlog_syslog_register(void)
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_RAMLOG_SYSLOG #ifdef CONFIG_RAMLOG_SYSLOG
int ramlog_putc(int ch) int ramlog_putc(FAR struct syslog_channel_s *channel, int ch)
{ {
FAR struct ramlog_dev_s *priv = &g_sysdev; FAR struct ramlog_dev_s *priv = &g_sysdev;
int readers_waken = 0; int readers_waken = 0;
int ret; int ret;
UNUSED(channel);
#ifdef CONFIG_RAMLOG_CRLF #ifdef CONFIG_RAMLOG_CRLF
/* Ignore carriage returns. But return success. */ /* Ignore carriage returns. But return success. */

View File

@ -48,7 +48,7 @@ extern "C"
*/ */
struct syslog_channel_s; /* Forward reference */ struct syslog_channel_s; /* Forward reference */
EXTERN FAR const struct syslog_channel_s *g_syslog_channel EXTERN FAR struct syslog_channel_s *g_syslog_channel
[CONFIG_SYSLOG_MAX_CHANNELS]; [CONFIG_SYSLOG_MAX_CHANNELS];
/**************************************************************************** /****************************************************************************
@ -73,16 +73,16 @@ EXTERN FAR const struct syslog_channel_s *g_syslog_channel
* *
* Input Parameters: * Input Parameters:
* devpath - The full path to the character device to be used. * devpath - The full path to the character device to be used.
* oflags - File open flags * oflags - File open flags.
* mode - File open mode (only if oflags include O_CREAT) * mode - File open mode (only if oflags include O_CREAT).
* *
* Returned Value: * Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on * Returns a newly created SYSLOG channel, or NULL in case of any failure.
* any failure.
* *
****************************************************************************/ ****************************************************************************/
int syslog_dev_initialize(FAR const char *devpath, int oflags, int mode); FAR struct syslog_channel_s *syslog_dev_initialize(FAR const char *devpath,
int oflags, int mode);
/**************************************************************************** /****************************************************************************
* Name: syslog_dev_uninitialize * Name: syslog_dev_uninitialize
@ -92,7 +92,7 @@ int syslog_dev_initialize(FAR const char *devpath, int oflags, int mode);
* a different SYSLOG device. Currently only used for CONFIG_SYSLOG_FILE. * a different SYSLOG device. Currently only used for CONFIG_SYSLOG_FILE.
* *
* Input Parameters: * Input Parameters:
* None * channel - Handle to syslog channel to be used.
* *
* Returned Value: * Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on * Zero (OK) is returned on success; a negated errno value is returned on
@ -104,9 +104,7 @@ int syslog_dev_initialize(FAR const char *devpath, int oflags, int mode);
* *
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_SYSLOG_FILE void syslog_dev_uninitialize(FAR struct syslog_channel_s *channel);
void syslog_dev_uninitialize(void);
#endif /* CONFIG_SYSLOG_FILE */
/**************************************************************************** /****************************************************************************
* Name: syslog_dev_channel * Name: syslog_dev_channel
@ -294,8 +292,9 @@ int syslog_force(int ch);
* for the character driver interface. * for the character driver interface.
* *
* Input Parameters: * Input Parameters:
* buffer - The buffer containing the data to be output * channel - Handle to syslog channel to be used.
* buflen - The number of bytes in the buffer * buffer - The buffer containing the data to be output.
* buflen - The number of bytes in the buffer.
* *
* Returned Value: * Returned Value:
* On success, the character is echoed back to the caller. A negated errno * On success, the character is echoed back to the caller. A negated errno
@ -303,7 +302,8 @@ int syslog_force(int ch);
* *
****************************************************************************/ ****************************************************************************/
ssize_t syslog_dev_write(FAR const char *buffer, size_t buflen); ssize_t syslog_dev_write(FAR struct syslog_channel_s *channel,
FAR const char *buffer, size_t buflen);
/**************************************************************************** /****************************************************************************
* Name: syslog_dev_putc * Name: syslog_dev_putc
@ -313,7 +313,8 @@ ssize_t syslog_dev_write(FAR const char *buffer, size_t buflen);
* character driver interface. * character driver interface.
* *
* Input Parameters: * Input Parameters:
* ch - The character to add to the SYSLOG (must be positive). * channel - Handle to syslog channel to be used.
* ch - The character to add to the SYSLOG (must be positive).
* *
* Returned Value: * Returned Value:
* On success, the character is echoed back to the caller. A negated * On success, the character is echoed back to the caller. A negated
@ -321,7 +322,7 @@ ssize_t syslog_dev_write(FAR const char *buffer, size_t buflen);
* *
****************************************************************************/ ****************************************************************************/
int syslog_dev_putc(int ch); int syslog_dev_putc(FAR struct syslog_channel_s *channel, int ch);
/**************************************************************************** /****************************************************************************
* Name: syslog_dev_flush * Name: syslog_dev_flush
@ -330,14 +331,14 @@ int syslog_dev_putc(int ch);
* Flush any buffer data in the file system to media. * Flush any buffer data in the file system to media.
* *
* Input Parameters: * Input Parameters:
* None * channel - Handle to syslog channel to be used.
* *
* Returned Value: * Returned Value:
* Zero (OK) on success; a negated errno value is returned on any failure. * Zero (OK) on success; a negated errno value is returned on any failure.
* *
****************************************************************************/ ****************************************************************************/
int syslog_dev_flush(void); int syslog_dev_flush(FAR struct syslog_channel_s *channel);
#undef EXTERN #undef EXTERN
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -29,6 +29,7 @@
#include <errno.h> #include <errno.h>
#include <nuttx/syslog/syslog.h> #include <nuttx/syslog/syslog.h>
#include <nuttx/compiler.h>
#ifdef CONFIG_RAMLOG_SYSLOG #ifdef CONFIG_RAMLOG_SYSLOG
# include <nuttx/syslog/ramlog.h> # include <nuttx/syslog/ramlog.h>
@ -44,9 +45,7 @@
* Private Function Prototypes * Private Function Prototypes
****************************************************************************/ ****************************************************************************/
#if defined(CONFIG_ARCH_LOWPUTC) #if !defined(CONFIG_RAMLOG_SYSLOG) && !defined(CONFIG_SYSLOG_RPMSG)
# define HAVE_LOWPUTC
#elif !defined(CONFIG_RAMLOG_SYSLOG) && !defined(CONFIG_SYSLOG_RPMSG)
# define NEED_LOWPUTC # define NEED_LOWPUTC
#endif #endif
@ -55,7 +54,8 @@
****************************************************************************/ ****************************************************************************/
#ifdef NEED_LOWPUTC #ifdef NEED_LOWPUTC
static int syslog_default_putc(int ch); static int syslog_default_putc(FAR struct syslog_channel_s *channel,
int ch);
#endif #endif
/**************************************************************************** /****************************************************************************
@ -63,36 +63,35 @@ static int syslog_default_putc(int ch);
****************************************************************************/ ****************************************************************************/
#if defined(CONFIG_RAMLOG_SYSLOG) #if defined(CONFIG_RAMLOG_SYSLOG)
static const struct syslog_channel_s g_default_channel = static const struct syslog_channel_ops_s g_default_channel_ops =
{ {
ramlog_putc, ramlog_putc,
ramlog_putc, ramlog_putc
}; };
#elif defined(CONFIG_SYSLOG_RPMSG) #elif defined(CONFIG_SYSLOG_RPMSG)
static const struct syslog_channel_s g_default_channel = static const struct syslog_channel_ops_s g_default_channel_ops =
{ {
syslog_rpmsg_putc, syslog_rpmsg_putc,
syslog_rpmsg_putc, syslog_rpmsg_putc,
syslog_rpmsg_flush, syslog_rpmsg_flush,
syslog_rpmsg_write syslog_rpmsg_write
}; };
#elif defined(HAVE_LOWPUTC)
static const struct syslog_channel_s g_default_channel =
{
up_putc,
up_putc,
};
#else #else
static const struct syslog_channel_s g_default_channel = static const struct syslog_channel_ops_s g_default_channel_ops =
{ {
syslog_default_putc, syslog_default_putc,
syslog_default_putc, syslog_default_putc
}; };
#endif #endif
static struct syslog_channel_s g_default_channel =
{
&g_default_channel_ops
};
/* This is the current syslog channel in use */ /* This is the current syslog channel in use */
FAR const struct syslog_channel_s FAR struct syslog_channel_s
*g_syslog_channel[CONFIG_SYSLOG_MAX_CHANNELS] = *g_syslog_channel[CONFIG_SYSLOG_MAX_CHANNELS] =
{ {
&g_default_channel &g_default_channel
@ -106,13 +105,20 @@ FAR const struct syslog_channel_s
* Name: syslog_default_putc and syslog_default_flush * Name: syslog_default_putc and syslog_default_flush
* *
* Description: * Description:
* Dummy, no-nothing channel interface methods * If the arch supports a low-level putc function, output will be
* redirected there. Else acts as a dummy, no-nothing channel.
* *
****************************************************************************/ ****************************************************************************/
#ifdef NEED_LOWPUTC #ifdef NEED_LOWPUTC
static int syslog_default_putc(int ch) static int syslog_default_putc(FAR struct syslog_channel_s *channel, int ch)
{ {
UNUSED(channel);
#if defined(CONFIG_ARCH_LOWPUTC)
return up_putc(ch);
#endif
return ch; return ch;
} }
#endif #endif
@ -137,7 +143,7 @@ static int syslog_default_putc(int ch)
* *
****************************************************************************/ ****************************************************************************/
int syslog_channel(FAR const struct syslog_channel_s *channel) int syslog_channel(FAR struct syslog_channel_s *channel)
{ {
#if (CONFIG_SYSLOG_MAX_CHANNELS != 1) #if (CONFIG_SYSLOG_MAX_CHANNELS != 1)
int i; int i;
@ -147,7 +153,8 @@ int syslog_channel(FAR const struct syslog_channel_s *channel)
if (channel != NULL) if (channel != NULL)
{ {
DEBUGASSERT(channel->sc_putc != NULL && channel->sc_force != NULL); DEBUGASSERT(channel->sc_ops->sc_putc != NULL &&
channel->sc_ops->sc_force != NULL);
#if (CONFIG_SYSLOG_MAX_CHANNELS == 1) #if (CONFIG_SYSLOG_MAX_CHANNELS == 1)
g_syslog_channel[0] = channel; g_syslog_channel[0] = channel;
@ -187,7 +194,7 @@ int syslog_channel(FAR const struct syslog_channel_s *channel)
* *
****************************************************************************/ ****************************************************************************/
int syslog_channel_remove(FAR const struct syslog_channel_s *channel) int syslog_channel_remove(FAR struct syslog_channel_s *channel)
{ {
int i; int i;

View File

@ -26,9 +26,11 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/syslog/syslog.h> #include <nuttx/syslog/syslog.h>
#include <nuttx/compiler.h>
#include "syslog.h" #include "syslog.h"
@ -56,30 +58,29 @@
/* SYSLOG channel methods */ /* SYSLOG channel methods */
#ifndef HAVE_LOWPUTC static int syslog_console_force(FAR struct syslog_channel_s *channel,
static int syslog_console_force(int ch); int ch);
#endif
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
/* This structure describes the SYSLOG channel */ /* This structure describes the channel's operations. */
static const struct syslog_channel_s g_syslog_console_channel = static const struct syslog_channel_ops_s g_syslog_ops =
{ {
syslog_dev_putc, syslog_dev_putc,
#ifdef HAVE_LOWPUTC
up_putc,
#else
syslog_console_force, syslog_console_force,
#endif
syslog_dev_flush, syslog_dev_flush,
#ifdef CONFIG_SYSLOG_WRITE #ifdef CONFIG_SYSLOG_WRITE
syslog_dev_write, syslog_dev_write,
#endif #endif
}; };
/* Handle to the SYSLOG channel */
FAR static struct syslog_channel_s *g_syslog_console_channel;
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@ -92,12 +93,17 @@ static const struct syslog_channel_s g_syslog_console_channel =
* *
****************************************************************************/ ****************************************************************************/
#ifndef HAVE_LOWPUTC static int syslog_console_force(FAR struct syslog_channel_s *channel,
static int syslog_console_force(int ch) int ch)
{ {
UNUSED(channel);
#ifdef HAVE_LOWPUTC
return up_putc(ch);
#endif
return ch; return ch;
} }
#endif
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
@ -132,19 +138,22 @@ static int syslog_console_force(int ch)
int syslog_console_channel(void) int syslog_console_channel(void)
{ {
int ret;
/* Initialize the character driver interface */ /* Initialize the character driver interface */
ret = syslog_dev_initialize("/dev/console", OPEN_FLAGS, OPEN_MODE); g_syslog_console_channel = syslog_dev_initialize("/dev/console",
if (ret < 0) OPEN_FLAGS, OPEN_MODE);
if (g_syslog_console_channel == NULL)
{ {
return ret; return -ENOMEM;
} }
/* Register the channel operations */
g_syslog_console_channel->sc_ops = &g_syslog_ops;
/* Use the character driver as the SYSLOG channel */ /* Use the character driver as the SYSLOG channel */
return syslog_channel(&g_syslog_console_channel); return syslog_channel(g_syslog_console_channel);
} }
#endif /* CONFIG_SYSLOG_CONSOLE */ #endif /* CONFIG_SYSLOG_CONSOLE */

View File

@ -26,8 +26,10 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h>
#include <nuttx/syslog/syslog.h> #include <nuttx/syslog/syslog.h>
#include <nuttx/compiler.h>
#include "syslog.h" #include "syslog.h"
@ -47,17 +49,19 @@
/* SYSLOG channel methods */ /* SYSLOG channel methods */
#ifdef CONFIG_SYSLOG_CHAR_CRLF #ifdef CONFIG_SYSLOG_CHAR_CRLF
static int syslog_devchan_putc(int ch); static int syslog_devchan_putc(FAR struct syslog_channel_s *channel,
int ch);
#endif #endif
static int syslog_devchan_force(int ch); static int syslog_devchan_force(FAR struct syslog_channel_s *channel,
int ch);
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
/* This structure describes the SYSLOG channel */ /* This structure describes the channel's operations. */
static const struct syslog_channel_s g_syslog_dev_channel = static const struct syslog_channel_ops_s g_syslog_ops =
{ {
#ifdef CONFIG_SYSLOG_CHAR_CRLF #ifdef CONFIG_SYSLOG_CHAR_CRLF
syslog_devchan_putc, syslog_devchan_putc,
@ -71,6 +75,10 @@ static const struct syslog_channel_s g_syslog_dev_channel =
#endif #endif
}; };
/* Handle to the SYSLOG channel */
FAR static struct syslog_channel_s *g_syslog_dev_channel;
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@ -84,7 +92,7 @@ static const struct syslog_channel_s g_syslog_dev_channel =
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_SYSLOG_CHAR_CRLF #ifdef CONFIG_SYSLOG_CHAR_CRLF
static int syslog_devchan_putc(int ch) static int syslog_devchan_putc(FAR struct syslog_channel_s *channel, int ch)
{ {
int ret; int ret;
@ -94,7 +102,7 @@ static int syslog_devchan_putc(int ch)
{ {
/* Pre-pend a carriage return */ /* Pre-pend a carriage return */
ret = syslog_dev_putc('\r'); ret = syslog_dev_putc(channel, '\r');
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
@ -103,7 +111,7 @@ static int syslog_devchan_putc(int ch)
/* Output the provided character */ /* Output the provided character */
return syslog_dev_putc(ch); return syslog_dev_putc(channel, ch);
} }
#endif #endif
@ -115,8 +123,10 @@ static int syslog_devchan_putc(int ch)
* *
****************************************************************************/ ****************************************************************************/
static int syslog_devchan_force(int ch) static int syslog_devchan_force(FAR struct syslog_channel_s *channel,
int ch)
{ {
UNUSED(channel);
return ch; return ch;
} }
@ -150,19 +160,22 @@ static int syslog_devchan_force(int ch)
int syslog_dev_channel(void) int syslog_dev_channel(void)
{ {
int ret;
/* Initialize the character driver interface */ /* Initialize the character driver interface */
ret = syslog_dev_initialize(CONFIG_SYSLOG_DEVPATH, OPEN_FLAGS, OPEN_MODE); g_syslog_dev_channel = syslog_dev_initialize(CONFIG_SYSLOG_DEVPATH,
if (ret < 0) OPEN_FLAGS, OPEN_MODE);
if (g_syslog_dev_channel == NULL)
{ {
return ret; return -ENOMEM;
} }
/* Register the channel operations */
g_syslog_dev_channel->sc_ops = &g_syslog_ops;
/* Use the character driver as the SYSLOG channel */ /* Use the character driver as the SYSLOG channel */
return syslog_channel(&g_syslog_dev_channel); return syslog_channel(g_syslog_dev_channel);
} }
#endif /* CONFIG_SYSLOG_CHAR */ #endif /* CONFIG_SYSLOG_CHAR */

View File

@ -77,6 +77,8 @@ enum syslog_dev_state
struct syslog_dev_s struct syslog_dev_s
{ {
struct syslog_channel_s channel;
uint8_t sl_state; /* See enum syslog_dev_state */ uint8_t sl_state; /* See enum syslog_dev_state */
uint8_t sl_oflags; /* Saved open mode (for re-open) */ uint8_t sl_oflags; /* Saved open mode (for re-open) */
uint16_t sl_mode; /* Saved open flags (for re-open) */ uint16_t sl_mode; /* Saved open flags (for re-open) */
@ -90,9 +92,6 @@ struct syslog_dev_s
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
/* This is the device structure for the console or syslogging function. */
static struct syslog_dev_s g_syslog_dev;
static const uint8_t g_syscrlf[2] = static const uint8_t g_syscrlf[2] =
{ {
'\r', '\n' '\r', '\n'
@ -106,7 +105,7 @@ static const uint8_t g_syscrlf[2] =
* Name: syslog_dev_takesem * Name: syslog_dev_takesem
****************************************************************************/ ****************************************************************************/
static inline int syslog_dev_takesem(void) static inline int syslog_dev_takesem(FAR struct syslog_dev_s *syslog_dev)
{ {
pid_t me = getpid(); pid_t me = getpid();
int ret; int ret;
@ -117,7 +116,7 @@ static inline int syslog_dev_takesem(void)
* error in that case. * error in that case.
*/ */
if (g_syslog_dev.sl_holder == me) if (syslog_dev->sl_holder == me)
{ {
/* Return an error (instead of deadlocking) */ /* Return an error (instead of deadlocking) */
@ -128,7 +127,7 @@ static inline int syslog_dev_takesem(void)
* thread. Wait for it to become available. * thread. Wait for it to become available.
*/ */
ret = nxsem_wait(&g_syslog_dev.sl_sem); ret = nxsem_wait(&syslog_dev->sl_sem);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
@ -138,7 +137,7 @@ static inline int syslog_dev_takesem(void)
* of the semaphore. * of the semaphore.
*/ */
g_syslog_dev.sl_holder = me; syslog_dev->sl_holder = me;
return OK; return OK;
} }
@ -146,17 +145,115 @@ static inline int syslog_dev_takesem(void)
* Name: syslog_dev_givesem * Name: syslog_dev_givesem
****************************************************************************/ ****************************************************************************/
static inline void syslog_dev_givesem(void) static inline void syslog_dev_givesem(FAR struct syslog_dev_s *syslog_dev)
{ {
#ifdef CONFIG_DEBUG_ASSERTIONS #ifdef CONFIG_DEBUG_ASSERTIONS
pid_t me = getpid(); pid_t me = getpid();
DEBUGASSERT(g_syslog_dev.sl_holder == me); DEBUGASSERT(syslog_dev->sl_holder == me);
#endif #endif
/* Relinquish the semaphore */ /* Relinquish the semaphore */
g_syslog_dev.sl_holder = NO_HOLDER; syslog_dev->sl_holder = NO_HOLDER;
nxsem_post(&g_syslog_dev.sl_sem); nxsem_post(&syslog_dev->sl_sem);
}
/****************************************************************************
* Name: syslog_dev_open
*
* Description:
* Opens the SYSLOG character device (or file).
*
* Input Parameters:
* syslog_dev - Handle to syslog device to be used.
* devpath - The full path to the character device to be used.
* oflags - File open flags.
* mode - File open mode (only if oflags include O_CREAT).
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure.
*
****************************************************************************/
static int syslog_dev_open(FAR struct syslog_dev_s *syslog_dev,
FAR const char *devpath, int oflags, int mode)
{
int ret;
/* At this point, the only expected states are SYSLOG_UNINITIALIZED or
* SYSLOG_REOPEN. Not SYSLOG_INITIALIZING, SYSLOG_FAILURE, SYSLOG_OPENED.
*/
DEBUGASSERT(syslog_dev->sl_state == SYSLOG_UNINITIALIZED ||
syslog_dev->sl_state == SYSLOG_REOPEN);
/* Save the path to the device in case we have to re-open it.
* If we get here and sl_devpath is not equal to NULL, that is a clue
* that we are re-opening the file.
*/
if (syslog_dev->sl_state == SYSLOG_REOPEN)
{
/* Re-opening: Then we should already have a copy of the path to the
* device. But that may be for a different device if we revert back
* to old syslog destination after the previous attempt failed.
*/
DEBUGASSERT(syslog_dev->sl_devpath != NULL);
}
else
{
/* Initializing. We do not have the device path yet. */
DEBUGASSERT(syslog_dev->sl_devpath == NULL);
}
/* Copy the device path so that we can use it if we
* have to re-open the file.
*/
syslog_dev->sl_oflags = oflags;
syslog_dev->sl_mode = mode;
if (syslog_dev->sl_devpath != devpath)
{
if (syslog_dev->sl_devpath != NULL)
{
kmm_free(syslog_dev->sl_devpath);
}
syslog_dev->sl_devpath = strdup(devpath);
}
DEBUGASSERT(syslog_dev->sl_devpath != NULL);
syslog_dev->sl_state = SYSLOG_INITIALIZING;
/* Open the device driver. */
ret = file_open(&syslog_dev->sl_file, devpath, oflags, mode);
if (ret < 0)
{
/* We failed to open the file. Perhaps it does exist? Perhaps it
* exists, but is not ready because it depends on insertion of a
* removable device?
*
* In any case we will attempt to re-open the device repeatedly.
* The assumption is that the device path is valid but that the
* driver has not yet been registered or a removable device has
* not yet been installed.
*/
syslog_dev->sl_state = SYSLOG_REOPEN;
return ret;
}
/* The SYSLOG device is open and ready for writing. */
nxsem_init(&syslog_dev->sl_sem, 0, 1);
syslog_dev->sl_holder = NO_HOLDER;
syslog_dev->sl_state = SYSLOG_OPENED;
return OK;
} }
/**************************************************************************** /****************************************************************************
@ -188,7 +285,7 @@ static inline void syslog_dev_givesem(void)
* that is why that case is handled in syslog_semtake(). * that is why that case is handled in syslog_semtake().
* *
* Input Parameters: * Input Parameters:
* None. * syslog_dev - Handle to syslog device to be used.
* *
* Returned Value: * Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on * Zero (OK) is returned on success; a negated errno value is returned on
@ -196,7 +293,7 @@ static inline void syslog_dev_givesem(void)
* *
****************************************************************************/ ****************************************************************************/
static int syslog_dev_outputready(void) static int syslog_dev_outputready(FAR struct syslog_dev_s *syslog_dev)
{ {
int ret; int ret;
@ -211,19 +308,19 @@ static int syslog_dev_outputready(void)
* has been successfully opened. * has been successfully opened.
*/ */
if (g_syslog_dev.sl_state != SYSLOG_OPENED) if (syslog_dev->sl_state != SYSLOG_OPENED)
{ {
/* Case (1) and (2) */ /* Case (1) and (2) */
if (g_syslog_dev.sl_state == SYSLOG_UNINITIALIZED || if (syslog_dev->sl_state == SYSLOG_UNINITIALIZED ||
g_syslog_dev.sl_state == SYSLOG_INITIALIZING) syslog_dev->sl_state == SYSLOG_INITIALIZING)
{ {
return -EAGAIN; /* Can't access the SYSLOG now... maybe next time? */ return -EAGAIN; /* Can't access the SYSLOG now... maybe next time? */
} }
/* Case (6) */ /* Case (6) */
if (g_syslog_dev.sl_state == SYSLOG_FAILURE) if (syslog_dev->sl_state == SYSLOG_FAILURE)
{ {
return -ENXIO; /* There is no SYSLOG device */ return -ENXIO; /* There is no SYSLOG device */
} }
@ -240,7 +337,7 @@ static int syslog_dev_outputready(void)
*/ */
sched_lock(); sched_lock();
if (g_syslog_dev.sl_state == SYSLOG_REOPEN) if (syslog_dev->sl_state == SYSLOG_REOPEN)
{ {
/* Try again to initialize the device. We may do this repeatedly /* Try again to initialize the device. We may do this repeatedly
* because the log device might be something that was not ready * because the log device might be something that was not ready
@ -249,10 +346,10 @@ static int syslog_dev_outputready(void)
* an NFS mounted file system that has not yet been mounted). * an NFS mounted file system that has not yet been mounted).
*/ */
DEBUGASSERT(g_syslog_dev.sl_devpath != NULL); DEBUGASSERT(syslog_dev->sl_devpath != NULL);
ret = syslog_dev_initialize(g_syslog_dev.sl_devpath, ret = syslog_dev_open(syslog_dev, syslog_dev->sl_devpath,
(int)g_syslog_dev.sl_oflags, (int)syslog_dev->sl_oflags,
(int)g_syslog_dev.sl_mode); (int)syslog_dev->sl_mode);
if (ret < 0) if (ret < 0)
{ {
sched_unlock(); sched_unlock();
@ -261,7 +358,7 @@ static int syslog_dev_outputready(void)
} }
sched_unlock(); sched_unlock();
DEBUGASSERT(g_syslog_dev.sl_state == SYSLOG_OPENED); DEBUGASSERT(syslog_dev->sl_state == SYSLOG_OPENED);
} }
return OK; return OK;
@ -289,92 +386,29 @@ static int syslog_dev_outputready(void)
* *
* Input Parameters: * Input Parameters:
* devpath - The full path to the character device to be used. * devpath - The full path to the character device to be used.
* oflags - File open flags * oflags - File open flags.
* mode - File open mode (only if oflags include O_CREAT) * mode - File open mode (only if oflags include O_CREAT).
* *
* Returned Value: * Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on * Returns a newly created SYSLOG channel, or NULL in case of any failure.
* any failure.
* *
****************************************************************************/ ****************************************************************************/
int syslog_dev_initialize(FAR const char *devpath, int oflags, int mode) FAR struct syslog_channel_s *syslog_dev_initialize(FAR const char *devpath,
int oflags, int mode)
{ {
int ret; FAR struct syslog_dev_s * syslog_dev;
/* At this point, the only expected states are SYSLOG_UNINITIALIZED or syslog_dev = kmm_zalloc(sizeof(struct syslog_dev_s));
* SYSLOG_REOPEN. Not SYSLOG_INITIALIZING, SYSLOG_FAILURE, SYSLOG_OPENED.
*/
DEBUGASSERT(g_syslog_dev.sl_state == SYSLOG_UNINITIALIZED || if (syslog_dev == NULL)
g_syslog_dev.sl_state == SYSLOG_REOPEN);
/* Save the path to the device in case we have to re-open it.
* If we get here and sl_devpath is not equal to NULL, that is a clue
* that we are re-opening the file.
*/
if (g_syslog_dev.sl_state == SYSLOG_REOPEN)
{ {
/* Re-opening: Then we should already have a copy of the path to the return NULL;
* device. But that may be for a different device if we revert back
* to old syslog destination after the previous attempt failed.
*/
DEBUGASSERT(g_syslog_dev.sl_devpath != NULL);
}
else
{
/* Initializing. We do not have the device path yet. */
DEBUGASSERT(g_syslog_dev.sl_devpath == NULL);
} }
/* Copy the device path so that we can use it if we syslog_dev_open(syslog_dev, devpath, oflags, mode);
* have to re-open the file.
*/
g_syslog_dev.sl_oflags = oflags; return (FAR struct syslog_channel_s *)syslog_dev;
g_syslog_dev.sl_mode = mode;
if (g_syslog_dev.sl_devpath != devpath)
{
if (g_syslog_dev.sl_devpath != NULL)
{
kmm_free(g_syslog_dev.sl_devpath);
}
g_syslog_dev.sl_devpath = strdup(devpath);
}
DEBUGASSERT(g_syslog_dev.sl_devpath != NULL);
g_syslog_dev.sl_state = SYSLOG_INITIALIZING;
/* Open the device driver. */
ret = file_open(&g_syslog_dev.sl_file, devpath, oflags, mode);
if (ret < 0)
{
/* We failed to open the file. Perhaps it does exist? Perhaps it
* exists, but is not ready because it depends on insertion of a
* removable device?
*
* In any case we will attempt to re-open the device repeatedly.
* The assumption is that the device path is valid but that the
* driver has not yet been registered or a removable device has
* not yet been installed.
*/
g_syslog_dev.sl_state = SYSLOG_REOPEN;
return ret;
}
/* The SYSLOG device is open and ready for writing. */
nxsem_init(&g_syslog_dev.sl_sem, 0, 1);
g_syslog_dev.sl_holder = NO_HOLDER;
g_syslog_dev.sl_state = SYSLOG_OPENED;
return OK;
} }
/**************************************************************************** /****************************************************************************
@ -385,7 +419,7 @@ int syslog_dev_initialize(FAR const char *devpath, int oflags, int mode)
* a different SYSLOG device. Currently only used for CONFIG_SYSLOG_FILE. * a different SYSLOG device. Currently only used for CONFIG_SYSLOG_FILE.
* *
* Input Parameters: * Input Parameters:
* None * channel - Handle to syslog channel to be used.
* *
* Returned Value: * Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on * Zero (OK) is returned on success; a negated errno value is returned on
@ -397,12 +431,13 @@ int syslog_dev_initialize(FAR const char *devpath, int oflags, int mode)
* *
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_SYSLOG_FILE /* Currently only used in this configuration */ void syslog_dev_uninitialize(FAR struct syslog_channel_s *channel)
void syslog_dev_uninitialize(void)
{ {
FAR struct syslog_dev_s *syslog_dev = (FAR struct syslog_dev_s *)channel;
/* Check if the system is ready */ /* Check if the system is ready */
if (syslog_dev_outputready() < 0) if (syslog_dev_outputready(syslog_dev) < 0)
{ {
return; return;
} }
@ -410,30 +445,29 @@ void syslog_dev_uninitialize(void)
/* Attempt to flush any buffered data */ /* Attempt to flush any buffered data */
sched_lock(); sched_lock();
syslog_dev_flush(); syslog_dev_flush(channel);
/* Close the detached file instance */ /* Close the detached file instance */
g_syslog_dev.sl_state = SYSLOG_UNINITIALIZED; syslog_dev->sl_state = SYSLOG_UNINITIALIZED;
file_close(&g_syslog_dev.sl_file); file_close(&syslog_dev->sl_file);
/* Free the device path */ /* Free the device path */
if (g_syslog_dev.sl_devpath != NULL) if (syslog_dev->sl_devpath != NULL)
{ {
kmm_free(g_syslog_dev.sl_devpath); kmm_free(syslog_dev->sl_devpath);
} }
/* Destroy the semaphore */ /* Destroy the semaphore */
nxsem_destroy(&g_syslog_dev.sl_sem); nxsem_destroy(&syslog_dev->sl_sem);
/* Reset the state structure */ /* Free the channel structure */
memset(&g_syslog_dev, 0, sizeof(struct syslog_dev_s)); kmm_free(syslog_dev);
sched_unlock(); sched_unlock();
} }
#endif /* CONFIG_SYSLOG_FILE */
/**************************************************************************** /****************************************************************************
* Name: syslog_dev_write * Name: syslog_dev_write
@ -443,8 +477,9 @@ void syslog_dev_uninitialize(void)
* for the character driver interface. * for the character driver interface.
* *
* Input Parameters: * Input Parameters:
* buffer - The buffer containing the data to be output * channel - Handle to syslog channel to be used.
* buflen - The number of bytes in the buffer * buffer - The buffer containing the data to be output.
* buflen - The number of bytes in the buffer.
* *
* Returned Value: * Returned Value:
* On success, the character is echoed back to the caller. A negated errno * On success, the character is echoed back to the caller. A negated errno
@ -452,8 +487,10 @@ void syslog_dev_uninitialize(void)
* *
****************************************************************************/ ****************************************************************************/
ssize_t syslog_dev_write(FAR const char *buffer, size_t buflen) ssize_t syslog_dev_write(FAR struct syslog_channel_s *channel,
FAR const char *buffer, size_t buflen)
{ {
FAR struct syslog_dev_s *syslog_dev = (FAR struct syslog_dev_s *)channel;
FAR const char *endptr; FAR const char *endptr;
ssize_t nwritten; ssize_t nwritten;
size_t writelen; size_t writelen;
@ -462,7 +499,7 @@ ssize_t syslog_dev_write(FAR const char *buffer, size_t buflen)
/* Check if the system is ready to do output operations */ /* Check if the system is ready to do output operations */
ret = syslog_dev_outputready(); ret = syslog_dev_outputready(syslog_dev);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
@ -470,7 +507,7 @@ ssize_t syslog_dev_write(FAR const char *buffer, size_t buflen)
/* The syslog device is ready for writing */ /* The syslog device is ready for writing */
ret = syslog_dev_takesem(); ret = syslog_dev_takesem(syslog_dev);
if (ret < 0) if (ret < 0)
{ {
/* We probably already hold the semaphore and were probably /* We probably already hold the semaphore and were probably
@ -515,7 +552,7 @@ ssize_t syslog_dev_write(FAR const char *buffer, size_t buflen)
writelen = (size_t)((uintptr_t)endptr - (uintptr_t)buffer); writelen = (size_t)((uintptr_t)endptr - (uintptr_t)buffer);
if (writelen > 0) if (writelen > 0)
{ {
nwritten = file_write(&g_syslog_dev.sl_file, nwritten = file_write(&syslog_dev->sl_file,
buffer, writelen); buffer, writelen);
if (nwritten < 0) if (nwritten < 0)
{ {
@ -530,7 +567,8 @@ ssize_t syslog_dev_write(FAR const char *buffer, size_t buflen)
if (*endptr == '\n') if (*endptr == '\n')
{ {
nwritten = file_write(&g_syslog_dev.sl_file, g_syscrlf, 2); nwritten = file_write(&syslog_dev->sl_file,
g_syscrlf, 2);
if (nwritten < 0) if (nwritten < 0)
{ {
ret = (int)nwritten; ret = (int)nwritten;
@ -555,7 +593,7 @@ ssize_t syslog_dev_write(FAR const char *buffer, size_t buflen)
writelen = (size_t)((uintptr_t)endptr - (uintptr_t)buffer); writelen = (size_t)((uintptr_t)endptr - (uintptr_t)buffer);
if (writelen > 0) if (writelen > 0)
{ {
nwritten = file_write(&g_syslog_dev.sl_file, buffer, writelen); nwritten = file_write(&syslog_dev->sl_file, buffer, writelen);
if (nwritten < 0) if (nwritten < 0)
{ {
ret = (int)nwritten; ret = (int)nwritten;
@ -563,11 +601,11 @@ ssize_t syslog_dev_write(FAR const char *buffer, size_t buflen)
} }
} }
syslog_dev_givesem(); syslog_dev_givesem(syslog_dev);
return buflen; return buflen;
errout_with_sem: errout_with_sem:
syslog_dev_givesem(); syslog_dev_givesem(syslog_dev);
return ret; return ret;
} }
@ -579,7 +617,8 @@ errout_with_sem:
* provided for the character driver interface. * provided for the character driver interface.
* *
* Input Parameters: * Input Parameters:
* ch - The character to add to the SYSLOG (must be positive). * channel - Handle to syslog channel to be used.
* ch - The character to add to the SYSLOG (must be positive).
* *
* Returned Value: * Returned Value:
* On success, the character is echoed back to the caller. A negated errno * On success, the character is echoed back to the caller. A negated errno
@ -587,15 +626,16 @@ errout_with_sem:
* *
****************************************************************************/ ****************************************************************************/
int syslog_dev_putc(int ch) int syslog_dev_putc(FAR struct syslog_channel_s *channel, int ch)
{ {
FAR struct syslog_dev_s *syslog_dev = (FAR struct syslog_dev_s *)channel;
ssize_t nbytes; ssize_t nbytes;
uint8_t uch; uint8_t uch;
int ret; int ret;
/* Check if the system is ready to do output operations */ /* Check if the system is ready to do output operations */
ret = syslog_dev_outputready(); ret = syslog_dev_outputready(syslog_dev);
if (ret < 0) if (ret < 0)
{ {
return ret; return ret;
@ -612,7 +652,7 @@ int syslog_dev_putc(int ch)
* value to write. * value to write.
*/ */
ret = syslog_dev_takesem(); ret = syslog_dev_takesem(syslog_dev);
if (ret < 0) if (ret < 0)
{ {
/* We probably already hold the semaphore and were probably /* We probably already hold the semaphore and were probably
@ -630,7 +670,7 @@ int syslog_dev_putc(int ch)
{ {
/* Write the CR-LF sequence */ /* Write the CR-LF sequence */
nbytes = file_write(&g_syslog_dev.sl_file, g_syscrlf, 2); nbytes = file_write(&syslog_dev->sl_file, g_syscrlf, 2);
/* Synchronize the file when each CR-LF is encountered (i.e., /* Synchronize the file when each CR-LF is encountered (i.e.,
* implements line buffering always). * implements line buffering always).
@ -639,7 +679,7 @@ int syslog_dev_putc(int ch)
#ifndef CONFIG_DISABLE_MOUNTPOINT #ifndef CONFIG_DISABLE_MOUNTPOINT
if (nbytes > 0) if (nbytes > 0)
{ {
syslog_dev_flush(); syslog_dev_flush(channel);
} }
#endif #endif
} }
@ -648,10 +688,10 @@ int syslog_dev_putc(int ch)
/* Write the non-newline character (and don't flush) */ /* Write the non-newline character (and don't flush) */
uch = (uint8_t)ch; uch = (uint8_t)ch;
nbytes = file_write(&g_syslog_dev.sl_file, &uch, 1); nbytes = file_write(&syslog_dev->sl_file, &uch, 1);
} }
syslog_dev_givesem(); syslog_dev_givesem(syslog_dev);
/* Check if the write was successful. If not, nbytes will be /* Check if the write was successful. If not, nbytes will be
* a negated errno value. * a negated errno value.
@ -672,22 +712,24 @@ int syslog_dev_putc(int ch)
* Flush any buffer data in the file system to media. * Flush any buffer data in the file system to media.
* *
* Input Parameters: * Input Parameters:
* None * channel - Handle to syslog channel to be used.
* *
* Returned Value: * Returned Value:
* Zero (OK) on success; a negated errno value is returned on any failure. * Zero (OK) on success; a negated errno value is returned on any failure.
* *
****************************************************************************/ ****************************************************************************/
int syslog_dev_flush(void) int syslog_dev_flush(FAR struct syslog_channel_s *channel)
{ {
#if defined(CONFIG_SYSLOG_FILE) && !defined(CONFIG_DISABLE_MOUNTPOINT) #if defined(CONFIG_SYSLOG_FILE) && !defined(CONFIG_DISABLE_MOUNTPOINT)
FAR struct syslog_dev_s *syslog_dev = (FAR struct syslog_dev_s *)channel;
/* Ignore return value, always return success. file_fsync() could fail /* Ignore return value, always return success. file_fsync() could fail
* because the file is not open, the inode is not a mountpoint, or the * because the file is not open, the inode is not a mountpoint, or the
* mountpoint does not support the sync() method. * mountpoint does not support the sync() method.
*/ */
file_fsync(&g_syslog_dev.sl_file); file_fsync(&syslog_dev->sl_file);
#endif #endif
return OK; return OK;

View File

@ -27,8 +27,10 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sched.h> #include <sched.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h>
#include <nuttx/syslog/syslog.h> #include <nuttx/syslog/syslog.h>
#include <nuttx/compiler.h>
#include "syslog.h" #include "syslog.h"
@ -47,15 +49,15 @@
/* SYSLOG channel methods */ /* SYSLOG channel methods */
static int syslog_file_force(int ch); static int syslog_file_force(FAR struct syslog_channel_s *channel, int ch);
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
****************************************************************************/ ****************************************************************************/
/* This structure describes the SYSLOG channel */ /* This structure describes the channel's operations. */
static const struct syslog_channel_s g_syslog_file_channel = static const struct syslog_channel_ops_s g_syslog_ops =
{ {
syslog_dev_putc, syslog_dev_putc,
syslog_file_force, syslog_file_force,
@ -65,6 +67,10 @@ static const struct syslog_channel_s g_syslog_file_channel =
#endif #endif
}; };
/* Handle to the SYSLOG channel */
FAR static struct syslog_channel_s *g_syslog_file_channel;
/**************************************************************************** /****************************************************************************
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
@ -77,8 +83,9 @@ static const struct syslog_channel_s g_syslog_file_channel =
* *
****************************************************************************/ ****************************************************************************/
static int syslog_file_force(int ch) static int syslog_file_force(FAR struct syslog_channel_s *channel, int ch)
{ {
UNUSED(channel);
return ch; return ch;
} }
@ -138,21 +145,30 @@ int syslog_file_channel(FAR const char *devpath)
/* Uninitialize any driver interface that may have been in place */ /* Uninitialize any driver interface that may have been in place */
syslog_dev_uninitialize(); if (g_syslog_file_channel != NULL)
{
syslog_dev_uninitialize(g_syslog_file_channel);
}
/* Then initialize the file interface */ /* Then initialize the file interface */
ret = syslog_dev_initialize(devpath, OPEN_FLAGS, OPEN_MODE); g_syslog_file_channel = syslog_dev_initialize(devpath, OPEN_FLAGS,
if (ret < 0) OPEN_MODE);
if (g_syslog_file_channel == NULL)
{ {
ret = -ENOMEM;
goto errout_with_lock; goto errout_with_lock;
} }
/* Register the channel operations */
g_syslog_file_channel->sc_ops = &g_syslog_ops;
/* Use the file as the SYSLOG channel. If this fails we are pretty much /* Use the file as the SYSLOG channel. If this fails we are pretty much
* screwed. * screwed.
*/ */
ret = syslog_channel(&g_syslog_file_channel); ret = syslog_channel(g_syslog_file_channel);
errout_with_lock: errout_with_lock:
sched_unlock(); sched_unlock();

View File

@ -83,9 +83,9 @@ int syslog_flush(void)
/* Then flush all of the buffered output to the SYSLOG device */ /* Then flush all of the buffered output to the SYSLOG device */
if (g_syslog_channel[i]->sc_flush != NULL) if (g_syslog_channel[i]->sc_ops->sc_flush != NULL)
{ {
g_syslog_channel[i]->sc_flush(); g_syslog_channel[i]->sc_ops->sc_flush(g_syslog_channel[i]);
} }
} }

View File

@ -72,11 +72,11 @@ int syslog_force(int ch)
break; break;
} }
DEBUGASSERT(g_syslog_channel[i]->sc_force != NULL); DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_force != NULL);
/* Then send the character to the emergency channel */ /* Then send the character to the emergency channel */
g_syslog_channel[i]->sc_force(ch); g_syslog_channel[i]->sc_ops->sc_force(g_syslog_channel[i], ch);
} }
return ch; return ch;

View File

@ -307,10 +307,10 @@ int syslog_flush_intbuffer(bool force)
/* Select which putc function to use for this flush */ /* Select which putc function to use for this flush */
putfunc = force ? g_syslog_channel[i]->sc_putc : putfunc = force ? g_syslog_channel[i]->sc_ops->sc_putc :
g_syslog_channel[i]->sc_force; g_syslog_channel[i]->sc_ops->sc_force;
putfunc(ch); putfunc(g_syslog_channel[i], ch);
} }
} }
while (ch != EOF); while (ch != EOF);

View File

@ -88,9 +88,10 @@ int syslog_putc(int ch)
break; break;
} }
DEBUGASSERT(g_syslog_channel[i]->sc_force != NULL); DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_force != NULL);
g_syslog_channel[i]->sc_force(ch); g_syslog_channel[i]->sc_ops->sc_force(g_syslog_channel[i],
ch);
} }
} }
} }
@ -111,9 +112,9 @@ int syslog_putc(int ch)
break; break;
} }
DEBUGASSERT(g_syslog_channel[i]->sc_putc != NULL); DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_putc != NULL);
g_syslog_channel[i]->sc_putc(ch); g_syslog_channel[i]->sc_ops->sc_putc(g_syslog_channel[i], ch);
} }
} }

View File

@ -33,6 +33,7 @@
#include <nuttx/syslog/syslog.h> #include <nuttx/syslog/syslog.h>
#include <nuttx/syslog/syslog_rpmsg.h> #include <nuttx/syslog/syslog_rpmsg.h>
#include <nuttx/wqueue.h> #include <nuttx/wqueue.h>
#include <nuttx/compiler.h>
#include "syslog.h" #include "syslog.h"
#include "syslog_rpmsg.h" #include "syslog_rpmsg.h"
@ -298,11 +299,13 @@ static int syslog_rpmsg_ept_cb(FAR struct rpmsg_endpoint *ept,
* Public Functions * Public Functions
****************************************************************************/ ****************************************************************************/
int syslog_rpmsg_putc(int ch) int syslog_rpmsg_putc(FAR struct syslog_channel_s *channel, int ch)
{ {
FAR struct syslog_rpmsg_s *priv = &g_syslog_rpmsg; FAR struct syslog_rpmsg_s *priv = &g_syslog_rpmsg;
irqstate_t flags; irqstate_t flags;
UNUSED(channel);
flags = enter_critical_section(); flags = enter_critical_section();
syslog_rpmsg_putchar(priv, ch, true); syslog_rpmsg_putchar(priv, ch, true);
leave_critical_section(flags); leave_critical_section(flags);
@ -310,20 +313,25 @@ int syslog_rpmsg_putc(int ch)
return ch; return ch;
} }
int syslog_rpmsg_flush(void) int syslog_rpmsg_flush(FAR struct syslog_channel_s *channel)
{ {
UNUSED(channel);
FAR struct syslog_rpmsg_s *priv = &g_syslog_rpmsg; FAR struct syslog_rpmsg_s *priv = &g_syslog_rpmsg;
work_queue(HPWORK, &priv->work, syslog_rpmsg_work, priv, 0); work_queue(HPWORK, &priv->work, syslog_rpmsg_work, priv, 0);
return OK; return OK;
} }
ssize_t syslog_rpmsg_write(FAR const char *buffer, size_t buflen) ssize_t syslog_rpmsg_write(FAR struct syslog_channel_s *channel,
FAR const char *buffer, size_t buflen)
{ {
FAR struct syslog_rpmsg_s *priv = &g_syslog_rpmsg; FAR struct syslog_rpmsg_s *priv = &g_syslog_rpmsg;
irqstate_t flags; irqstate_t flags;
size_t nwritten; size_t nwritten;
UNUSED(channel);
flags = enter_critical_section(); flags = enter_critical_section();
for (nwritten = 1; nwritten <= buflen; nwritten++) for (nwritten = 1; nwritten <= buflen; nwritten++)
{ {

View File

@ -78,8 +78,9 @@ static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen)
break; break;
} }
DEBUGASSERT(g_syslog_channel[i]->sc_force != NULL); DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_force != NULL);
g_syslog_channel[i]->sc_force(*buffer++); g_syslog_channel[i]->sc_ops->sc_force(g_syslog_channel[i],
*buffer++);
} }
} }
} }
@ -94,18 +95,21 @@ static ssize_t syslog_default_write(FAR const char *buffer, size_t buflen)
} }
#ifdef CONFIG_SYSLOG_WRITE #ifdef CONFIG_SYSLOG_WRITE
if (g_syslog_channel[i]->sc_write) if (g_syslog_channel[i]->sc_ops->sc_write)
{ {
nwritten = g_syslog_channel[i]->sc_write(buffer, buflen); nwritten =
g_syslog_channel[i]->sc_ops->sc_write(g_syslog_channel[i],
buffer, buflen);
} }
else else
#endif #endif
{ {
DEBUGASSERT(g_syslog_channel[i]->sc_putc != NULL); DEBUGASSERT(g_syslog_channel[i]->sc_ops->sc_putc != NULL);
for (nwritten = 0; nwritten < buflen; nwritten++) for (nwritten = 0; nwritten < buflen; nwritten++)
{ {
g_syslog_channel[i]->sc_putc(*buffer++); g_syslog_channel[i]->sc_ops->sc_putc(g_syslog_channel[i],
*buffer++);
} }
} }
} }

View File

@ -137,7 +137,7 @@ void ramlog_syslog_register(void);
****************************************************************************/ ****************************************************************************/
#ifdef CONFIG_RAMLOG_SYSLOG #ifdef CONFIG_RAMLOG_SYSLOG
int ramlog_putc(int ch); int ramlog_putc(FAR struct syslog_channel_s *channel, int ch);
#endif #endif
#undef EXTERN #undef EXTERN

View File

@ -82,22 +82,37 @@
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
/* This structure provides the interface to a SYSLOG device */ /* Forward declaration */
typedef CODE ssize_t (*syslog_write_t)(FAR const char *buf, size_t buflen); struct syslog_channel_s;
typedef CODE int (*syslog_putc_t)(int ch);
typedef CODE int (*syslog_flush_t)(void);
struct syslog_channel_s /* SYSLOG I/O redirection methods */
typedef CODE ssize_t (*syslog_write_t)(FAR struct syslog_channel_s *channel,
FAR const char *buf, size_t buflen);
typedef CODE int (*syslog_putc_t)(FAR struct syslog_channel_s *channel,
int ch);
typedef CODE int (*syslog_flush_t)(FAR struct syslog_channel_s *channel);
/* SYSLOG device operations */
struct syslog_channel_ops_s
{ {
/* I/O redirection methods */
syslog_putc_t sc_putc; /* Normal buffered output */ syslog_putc_t sc_putc; /* Normal buffered output */
syslog_putc_t sc_force; /* Low-level output for interrupt handlers */ syslog_putc_t sc_force; /* Low-level output for interrupt handlers */
syslog_flush_t sc_flush; /* Flush buffered output (on crash) */ syslog_flush_t sc_flush; /* Flush buffered output (on crash) */
#ifdef CONFIG_SYSLOG_WRITE #ifdef CONFIG_SYSLOG_WRITE
syslog_write_t sc_write; /* Write multiple bytes */ syslog_write_t sc_write; /* Write multiple bytes */
#endif #endif
};
/* This structure provides the interface to a SYSLOG channel */
struct syslog_channel_s
{
/* Channel operations */
FAR const struct syslog_channel_ops_s *sc_ops;
/* Implementation specific logic may follow */ /* Implementation specific logic may follow */
}; };
@ -136,7 +151,7 @@ extern "C"
* *
****************************************************************************/ ****************************************************************************/
int syslog_channel(FAR const struct syslog_channel_s *channel); int syslog_channel(FAR struct syslog_channel_s *channel);
/**************************************************************************** /****************************************************************************
* Name: syslog_channel_remove * Name: syslog_channel_remove
@ -154,7 +169,7 @@ int syslog_channel(FAR const struct syslog_channel_s *channel);
* *
****************************************************************************/ ****************************************************************************/
int syslog_channel_remove(FAR const struct syslog_channel_s *channel); int syslog_channel_remove(FAR struct syslog_channel_s *channel);
/**************************************************************************** /****************************************************************************
* Name: syslog_initialize * Name: syslog_initialize

View File

@ -44,9 +44,10 @@ void syslog_rpmsg_init_early(FAR const char *cpu_name, FAR void *buffer,
size_t size); size_t size);
int syslog_rpmsg_init(void); int syslog_rpmsg_init(void);
int syslog_rpmsg_putc(int ch); int syslog_rpmsg_putc(FAR struct syslog_channel_s *channel, int ch);
int syslog_rpmsg_flush(void); int syslog_rpmsg_flush(FAR struct syslog_channel_s *channel);
ssize_t syslog_rpmsg_write(FAR const char *buffer, size_t buflen); ssize_t syslog_rpmsg_write(FAR struct syslog_channel_s *channel,
FAR const char *buffer, size_t buflen);
#endif #endif
#ifdef CONFIG_SYSLOG_RPMSG_SERVER #ifdef CONFIG_SYSLOG_RPMSG_SERVER