diff --git a/arch/arm/src/arm/up_assert.c b/arch/arm/src/arm/up_assert.c index 27788451daf..f081035a316 100644 --- a/arch/arm/src/arm/up_assert.c +++ b/arch/arm/src/arm/up_assert.c @@ -151,7 +151,7 @@ static int usbtrace_syslog(FAR const char *fmt, ...) /* Let vsyslog do the real work */ va_start(ap, fmt); - ret = lowvsyslog(LOG_INFO, fmt, ap); + ret = vsyslog(LOG_EMERG, fmt, ap); va_end(ap); return ret; } diff --git a/arch/arm/src/armv6-m/up_assert.c b/arch/arm/src/armv6-m/up_assert.c index 93ff4a9f6fb..934f8b255b3 100644 --- a/arch/arm/src/armv6-m/up_assert.c +++ b/arch/arm/src/armv6-m/up_assert.c @@ -193,7 +193,7 @@ static int usbtrace_syslog(FAR const char *fmt, ...) /* Let vsyslog do the real work */ va_start(ap, fmt); - ret = lowvsyslog(LOG_INFO, fmt, ap); + ret = vsyslog(LOG_EMERG, fmt, ap); va_end(ap); return ret; } diff --git a/arch/arm/src/armv7-a/arm_assert.c b/arch/arm/src/armv7-a/arm_assert.c index bdeffa763cf..1fef0e7eb07 100644 --- a/arch/arm/src/armv7-a/arm_assert.c +++ b/arch/arm/src/armv7-a/arm_assert.c @@ -185,7 +185,7 @@ static int usbtrace_syslog(FAR const char *fmt, ...) /* Let vsyslog do the real work */ va_start(ap, fmt); - ret = lowvsyslog(LOG_INFO, fmt, ap); + ret = vsyslog(LOG_EMERG, fmt, ap); va_end(ap); return ret; } diff --git a/arch/arm/src/armv7-m/up_assert.c b/arch/arm/src/armv7-m/up_assert.c index eedfa522d81..144ea69fa76 100644 --- a/arch/arm/src/armv7-m/up_assert.c +++ b/arch/arm/src/armv7-m/up_assert.c @@ -198,7 +198,7 @@ static int usbtrace_syslog(FAR const char *fmt, ...) /* Let vsyslog do the real work */ va_start(ap, fmt); - ret = lowvsyslog(LOG_INFO, fmt, ap); + ret = vsyslog(LOG_EMERG, fmt, ap); va_end(ap); return ret; } diff --git a/arch/arm/src/armv7-r/arm_assert.c b/arch/arm/src/armv7-r/arm_assert.c index ccf01160457..4e3137512ae 100644 --- a/arch/arm/src/armv7-r/arm_assert.c +++ b/arch/arm/src/armv7-r/arm_assert.c @@ -186,7 +186,7 @@ static int usbtrace_syslog(FAR const char *fmt, ...) /* Let vsyslog do the real work */ va_start(ap, fmt); - ret = lowvsyslog(LOG_INFO, fmt, ap); + ret = vsyslog(LOG_EMERG, fmt, ap); va_end(ap); return ret; } diff --git a/arch/avr/src/common/up_assert.c b/arch/avr/src/common/up_assert.c index a93187c5238..7457fb8821a 100644 --- a/arch/avr/src/common/up_assert.c +++ b/arch/avr/src/common/up_assert.c @@ -109,7 +109,7 @@ static int usbtrace_syslog(FAR const char *fmt, ...) /* Let vsyslog do the real work */ va_start(ap, fmt); - ret = lowvsyslog(LOG_INFO, fmt, ap); + ret = vsyslog(LOG_EMERG, fmt, ap); va_end(ap); return ret; } diff --git a/arch/hc/src/m9s12/m9s12_assert.c b/arch/hc/src/m9s12/m9s12_assert.c index 2f859314f1d..b4a96f199c4 100644 --- a/arch/hc/src/m9s12/m9s12_assert.c +++ b/arch/hc/src/m9s12/m9s12_assert.c @@ -144,7 +144,7 @@ static int usbtrace_syslog(FAR const char *fmt, ...) /* Let vsyslog do the real work */ va_start(ap, fmt); - ret = lowvsyslog(LOG_INFO, fmt, ap); + ret = vsyslog(LOG_EMERG, fmt, ap); va_end(ap); return ret; } diff --git a/arch/mips/src/mips32/up_assert.c b/arch/mips/src/mips32/up_assert.c index 119844eb997..e8873b45671 100644 --- a/arch/mips/src/mips32/up_assert.c +++ b/arch/mips/src/mips32/up_assert.c @@ -109,7 +109,7 @@ static int usbtrace_syslog(FAR const char *fmt, ...) /* Let vsyslog do the real work */ va_start(ap, fmt); - ret = lowvsyslog(LOG_INFO, fmt, ap); + ret = vsyslog(LOG_EMERG, fmt, ap); va_end(ap); return ret; } diff --git a/arch/sh/src/common/up_assert.c b/arch/sh/src/common/up_assert.c index 95abc9b1903..0c3e9a6b858 100644 --- a/arch/sh/src/common/up_assert.c +++ b/arch/sh/src/common/up_assert.c @@ -110,7 +110,7 @@ static int usbtrace_syslog(FAR const char *fmt, ...) /* Let vsyslog do the real work */ va_start(ap, fmt); - ret = lowvsyslog(LOG_INFO, fmt, ap); + ret = vsyslog(LOG_EMERG, fmt, ap); va_end(ap); return ret; } diff --git a/arch/x86/src/common/up_assert.c b/arch/x86/src/common/up_assert.c index 3b6caececce..a011c101b82 100644 --- a/arch/x86/src/common/up_assert.c +++ b/arch/x86/src/common/up_assert.c @@ -103,7 +103,7 @@ static int usbtrace_syslog(FAR const char *fmt, ...) /* Let vsyslog do the real work */ va_start(ap, fmt); - ret = lowvsyslog(LOG_INFO, fmt, ap); + ret = vsyslog(LOG_EMERG, fmt, ap); va_end(ap); return ret; } diff --git a/arch/z16/src/common/up_assert.c b/arch/z16/src/common/up_assert.c index 628c34f1faa..9a755d63aa7 100644 --- a/arch/z16/src/common/up_assert.c +++ b/arch/z16/src/common/up_assert.c @@ -109,7 +109,7 @@ static int usbtrace_syslog(FAR const char *fmt, ...) /* Let vsyslog do the real work */ va_start(ap, fmt); - ret = lowvsyslog(LOG_INFO, fmt, ap); + ret = vsyslog(LOG_EMERG, fmt, ap); va_end(ap); return ret; } diff --git a/arch/z80/src/common/up_assert.c b/arch/z80/src/common/up_assert.c index 49b72409289..1bbfa09a24a 100644 --- a/arch/z80/src/common/up_assert.c +++ b/arch/z80/src/common/up_assert.c @@ -108,7 +108,7 @@ static int usbtrace_syslog(FAR const char *fmt, ...) /* Let vsyslog do the real work */ va_start(ap, fmt); - ret = lowvsyslog(LOG_INFO, fmt, ap); + ret = vsyslog(LOG_EMERG, fmt, ap); va_end(ap); return ret; } diff --git a/drivers/syslog/syslog.h b/drivers/syslog/syslog.h index ac52ebb0e14..7a90bb3541a 100644 --- a/drivers/syslog/syslog.h +++ b/drivers/syslog/syslog.h @@ -224,6 +224,25 @@ int syslog_flush_intbuffer(FAR const struct syslog_channel_s *channel, int syslog_putc(int ch); +/**************************************************************************** + * Name: syslog_force + * + * Description: + * This is the low-level system logging interface. This version forces + * the output and is only used in emergency situations (e.g., in assertion + * handling). + * + * Input Parameters: + * ch - The character to add to the SYSLOG (must be positive). + * + * Returned Value: + * On success, the character is echoed back to the caller. A negated + * errno value is returned on any failure. + * + ****************************************************************************/ + +int syslog_force(int ch); + /**************************************************************************** * Name: syslog_dev_putc * diff --git a/drivers/syslog/syslog_channel.c b/drivers/syslog/syslog_channel.c index 4f1cc44339b..fbdde1fdf91 100644 --- a/drivers/syslog/syslog_channel.c +++ b/drivers/syslog/syslog_channel.c @@ -210,6 +210,40 @@ int syslog_putc(int ch) } } +/**************************************************************************** + * Name: syslog_force + * + * Description: + * This is the low-level system logging interface. This version forces + * the output and is only used in emergency situations (e.g., in assertion + * handling). + * + * Input Parameters: + * ch - The character to add to the SYSLOG (must be positive). + * + * Returned Value: + * On success, the character is echoed back to the caller. A negated + * errno value is returned on any failure. + * + ****************************************************************************/ + +int syslog_force(int ch) +{ + DEBUGASSERT(g_syslog_channel != NULL && g_syslog_channel->sc_force != NULL); + +#ifdef CONFIG_SYSLOG_INTBUFFER + /* Flush any characters that may have been added to the interrupt + * buffer through the emergency channel + */ + + (void)syslog_flush_intbuffer(g_syslog_channel, true); +#endif + + /* Then send the character to the emergency channel */ + + return g_syslog_channel->sc_force(ch); +} + /**************************************************************************** * Name: syslog_flush * diff --git a/drivers/syslog/syslog_stream.c b/drivers/syslog/syslog_stream.c index 491da95c266..ecb68d256bf 100644 --- a/drivers/syslog/syslog_stream.c +++ b/drivers/syslog/syslog_stream.c @@ -86,6 +86,39 @@ static void syslogstream_putc(FAR struct lib_outstream_s *this, int ch) while (errno == -EINTR); } +/**************************************************************************** + * Name: emergstream_putc + ****************************************************************************/ + +static void emergstream_putc(FAR struct lib_outstream_s *this, int ch) +{ + int ret; + + /* Try writing until the write was successful or until an irrecoverable + * error occurs. + */ + + do + { + /* Write the character to the supported logging device. On failure, + * syslog_putc returns EOF with the errno value set; + */ + + ret = syslog_force(ch); + if (ret != EOF) + { + this->nput++; + return; + } + + /* The special errno value -EINTR means that syslog_putc() was + * awakened by a signal. This is not a real error and must be + * ignored in this context. + */ + } + while (errno == -EINTR); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -114,3 +147,28 @@ void syslogstream(FAR struct lib_outstream_s *stream) #endif stream->nput = 0; } + +/**************************************************************************** + * Name: emergstream + * + * Description: + * Initializes a stream for use with the configured emergency syslog + * interface. Only accessible from with the OS SYSLOG logic. + * + * Input parameters: + * stream - User allocated, uninitialized instance of struct + * lib_lowoutstream_s to be initialized. + * + * Returned Value: + * None (User allocated instance initialized). + * + ****************************************************************************/ + +void emergstream(FAR struct lib_outstream_s *stream) +{ + stream->put = emergstream_putc; +#ifdef CONFIG_STDIO_LINEBUFFER + stream->flush = lib_noflush; +#endif + stream->nput = 0; +} diff --git a/drivers/syslog/vsyslog.c b/drivers/syslog/vsyslog.c index ee87a1019e1..27fab399ecb 100644 --- a/drivers/syslog/vsyslog.c +++ b/drivers/syslog/vsyslog.c @@ -57,16 +57,15 @@ * * Description: * _vsyslog() handles the system logging system calls. It is functionally - * equivalent to vsyslog() except that the per-process priority filtering - * has already been performed and, hence, there is no priority argument. - * - * NOTE: The va_list parameter is passed by reference. That is because - * the va_list is a structure in some compilers and passing of structures - * in the NuttX sycalls does not work. + * equivalent to vsyslog() except that (1) the per-process priority + * filtering has already been performed and the va_list parameter is + * passed by reference. That is because the va_list is a structure in + * some compilers and passing of structures in the NuttX sycalls does + * not work. * ****************************************************************************/ -int _vsyslog(FAR const IPTR char *fmt, FAR va_list *ap) +int _vsyslog(int priority, FAR const IPTR char *fmt, FAR va_list *ap) { struct lib_outstream_s stream; #ifdef CONFIG_SYSLOG_TIMESTAMP @@ -87,17 +86,28 @@ int _vsyslog(FAR const IPTR char *fmt, FAR va_list *ap) #endif /* Wrap the low-level output in a stream object and let lib_vsprintf - * do the work. + * do the work. NOTE that emergency priority output is handled + * differently.. it will use the SYSLOG emergency stream. */ - syslogstream((FAR struct lib_outstream_s *)&stream); + if (priority == LOG_EMERG) + { + /* Use the SYSLOG emergency stream */ + + emergstream((FAR struct lib_outstream_s *)&stream); + } + else + { + /* Use the normal SYSLOG stream */ + + syslogstream((FAR struct lib_outstream_s *)&stream); + } #if defined(CONFIG_SYSLOG_TIMESTAMP) /* Pre-pend the message with the current time, if available */ (void)lib_sprintf((FAR struct lib_outstream_s *)&stream, "[%6d.%06d]", ts.tv_sec, ts.tv_nsec/1000); - #endif return lib_vsprintf((FAR struct lib_outstream_s *)&stream, fmt, *ap); diff --git a/drivers/usbdev/usbdev_trace.c b/drivers/usbdev/usbdev_trace.c index b532565e0e0..857cd3e0294 100644 --- a/drivers/usbdev/usbdev_trace.c +++ b/drivers/usbdev/usbdev_trace.c @@ -100,10 +100,10 @@ static int usbtrace_syslog(const char *fmt, ...) va_list ap; int ret; - /* Let lowvsyslog do the real work */ + /* Let vsyslog do the real work */ va_start(ap, fmt); - ret = lowvsyslog(LOG_INFO, fmt, ap); + ret = vsyslog(LOG_INFO, fmt, ap); va_end(ap); return ret; } diff --git a/include/nuttx/streams.h b/include/nuttx/streams.h index cf52324f2f7..6ae6b8c9430 100644 --- a/include/nuttx/streams.h +++ b/include/nuttx/streams.h @@ -371,6 +371,24 @@ void lib_nulloutstream(FAR struct lib_outstream_s *nulloutstream); void syslogstream(FAR struct lib_outstream_s *stream); +/**************************************************************************** + * Name: emergstream + * + * Description: + * Initializes a stream for use with the configured emergency syslog + * interface. Only accessible from with the OS SYSLOG logic. + * + * Input parameters: + * stream - User allocated, uninitialized instance of struct + * lib_lowoutstream_s to be initialized. + * + * Returned Value: + * None (User allocated instance initialized). + * + ****************************************************************************/ + +void emergstream(FAR struct lib_outstream_s *stream); + /**************************************************************************** * Name: lib_noflush * diff --git a/include/nuttx/syslog/syslog.h b/include/nuttx/syslog/syslog.h index b0d6694b596..c897a34801c 100644 --- a/include/nuttx/syslog/syslog.h +++ b/include/nuttx/syslog/syslog.h @@ -219,16 +219,15 @@ int syslog_flush(void); * * Description: * _vsyslog() handles the system logging system calls. It is functionally - * equivalent to vsyslog() except that the per-process priority filtering - * has already been performed and, hence, there is no priority argument. - * - * NOTE: The va_list parameter is passed by reference. That is because - * the va_list is a structure in some compilers and passing of structures - * in the NuttX sycalls does not work. + * equivalent to vsyslog() except that (1) the per-process priority + * filtering has already been performed and the va_list parameter is + * passed by reference. That is because the va_list is a structure in + * some compilers and passing of structures in the NuttX sycalls does + * not work. * ****************************************************************************/ -int _vsyslog(FAR const IPTR char *src, FAR va_list *ap); +int _vsyslog(int priority, FAR const IPTR char *src, FAR va_list *ap); #undef EXTERN #ifdef __cplusplus diff --git a/libc/misc/lib_debug.c b/libc/misc/lib_debug.c index 5fefcd2c433..d921c7c32ab 100644 --- a/libc/misc/lib_debug.c +++ b/libc/misc/lib_debug.c @@ -66,7 +66,7 @@ int _alert(const char *format, ...) int ret; va_start(ap, format); - ret = lowvsyslog(LOG_EMERG, format, ap); + ret = vsyslog(LOG_EMERG, format, ap); va_end(ap); return ret; diff --git a/libc/stdio/lib_fprintf.c b/libc/stdio/lib_fprintf.c index 191dc2e34a4..bb744c4698b 100644 --- a/libc/stdio/lib_fprintf.c +++ b/libc/stdio/lib_fprintf.c @@ -33,44 +33,12 @@ * ****************************************************************************/ -/**************************************************************************** - * Compilation Switches - ****************************************************************************/ - /**************************************************************************** * Included Files ****************************************************************************/ #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Public Constant Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Constant Data - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/libc/stdio/lib_printf.c b/libc/stdio/lib_printf.c index 5f1096a3a2f..b760abb4bb9 100644 --- a/libc/stdio/lib_printf.c +++ b/libc/stdio/lib_printf.c @@ -1,7 +1,7 @@ /**************************************************************************** * libc/stdio/lib_printf.c * - * Copyright (C) 2007-2008, 2011-2012, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2008, 2011-2012, 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -60,8 +60,6 @@ int printf(FAR const IPTR char *fmt, ...) ret = vfprintf(stdout, fmt, ap); #elif CONFIG_NFILE_DESCRIPTORS > 0 ret = vsyslog(LOG_INFO, fmt, ap); -#elif defined(CONFIG_ARCH_LOWPUTC) - ret = lowvsyslog(LOG_INFO, fmt, ap); #else # ifdef CONFIG_CPP_HAVE_WARNING # warning "printf has no data sink" diff --git a/libc/syslog/lib_syslog.c b/libc/syslog/lib_syslog.c index ec9ca3b7e57..408ffc10015 100644 --- a/libc/syslog/lib_syslog.c +++ b/libc/syslog/lib_syslog.c @@ -67,14 +67,14 @@ int vsyslog(int priority, FAR const IPTR char *fmt, va_list ap) if ((g_syslog_mask & LOG_MASK(priority)) != 0) { - /* Yes.. lPerform the _vsyslog system call. + /* Yes.. Perform the _vsyslog system call. * * NOTE: The va_list parameter is passed by reference. That is * because the va_list is a structure in some compilers and passing * of structures in the NuttX sycalls does not work. */ - ret = _vsyslog(fmt, &ap); + ret = _vsyslog(priority, fmt, &ap); } return ret; diff --git a/syscall/syscall.csv b/syscall/syscall.csv index 306d5c4cae9..29271925c46 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -159,7 +159,7 @@ "up_assert","assert.h","","void","FAR const uint8_t*","int" #"up_assert","assert.h","","void" "vfork","unistd.h","defined(CONFIG_ARCH_HAVE_VFORK)","pid_t" -"_vsyslog","syslog.h","","int","FAR const IPTR char*","FAR va_list*" +"_vsyslog","syslog.h","","int","int","FAR const IPTR char*","FAR va_list*" "wait","sys/wait.h","defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT)","pid_t","int*" "waitid","sys/wait.h","defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT)","int","idtype_t","id_t"," FAR siginfo_t *","int" "waitpid","sys/wait.h","defined(CONFIG_SCHED_WAITPID)","pid_t","pid_t","int*","int" diff --git a/syscall/syscall_lookup.h b/syscall/syscall_lookup.h index 2194a6e6448..4cd1a3d6765 100644 --- a/syscall/syscall_lookup.h +++ b/syscall/syscall_lookup.h @@ -165,7 +165,7 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert) /* System logging */ - SYSCALL_LOOKUP(_vsyslog, 2, STUB__vsyslog) + SYSCALL_LOOKUP(_vsyslog, 3, STUB__vsyslog) /* The following are defined if either file or socket descriptor are * enabled. diff --git a/syscall/syscall_stublookup.c b/syscall/syscall_stublookup.c index c587401b571..96862aa4062 100644 --- a/syscall/syscall_stublookup.c +++ b/syscall/syscall_stublookup.c @@ -167,7 +167,8 @@ uintptr_t STUB_timer_settime(int nbr, uintptr_t parm1, uintptr_t parm2, /* System logging */ -uintptr_t STUB__vsyslog(int nbr, uintptr_t parm1, uintptr_t parm2); +uintptr_t STUB__vsyslog(int nbr, uintptr_t parm1, uintptr_t parm2, + uintptr_t parm3); /* The following are defined if either file or socket descriptor are * enabled.