Git Product home page Git Product logo

liblogging's Introduction

What?

Liblogging is an easy to use library for logging. It offers an enhanced replacement for the syslog() call, but retains its ease of use.

If you dig deeper, liblogging actually has three components, which address different needs.

stdlog

This is the core component. Think of it as a the next version of the syslog(3) API. We retain the easy semantics, but make it more sophisticated "behind the scenes" with better support for multiple threads and flexibility for different log destinations. It also is signal-safe and thus can be used from within signal handlers.

Right now, it actually does more or less what syslog() did. In the next couple of weeks, this will change. It supports different log destionations:

  • syslog()
  • systemd journal native API
  • unix domain socket
  • files

The key point here is that we provide a separation of concerns: the application developer will do the logging calls, but the sysadmin will be able to configure where log messages actually are send to. We will use a driver layer to do so.

With the current version, the logging driver is set via an environment variable or directly specified from within the application code. The latter provides applications the ability to request specific logging drivers. At the smame time, a single application can log to multiple channels which in turn use multiple logging providers -- all at the same time.

This follows much the successful log4j paradigm. However, we have a focus on simplicity. No app developer likes logging, and so we really want to make it as easy, simple and unintrusive as syslog() was.

An interesting side-effect of that approach is that an application developer can write code that natively logs to the journal on platforms that support it but uses different methods on platforms that do not.

journalemu

This component (not yet committed) emulates the most important logging calls of systemd journal. This permits applications to be written to this spec, even though the journal is not available on all platforms. Of course, we recommend writing directly to libstdlog, as this solves the problem more cleanly.

rfc3195

This is liblogging's original component. Back in 2002, we thought that logging would be taken over by rfc3195 and thus we begun working on a library -liblogging- that makes this easy. While the lib is there, rfc3195 has turned out to be a big failure. This component is no longer enhanced, but it is still available for those apps that need it.

Motivation for this library

The syslog(3) API is the de-facto standard for application logging on Linux and Unix. While very simplistic, this is exactly the main feature the app developer wants. We want to keep this but improve it to

  • provide separation of concerns as described above under the stdlog component
  • support reentrancy
  • provide multiple concurrent log channels to different destinations
  • provide an interface for structured logging - but only if there is a real demand for it (to be seen based on feedback)

Liblogging's goal is also to be a very slim library without any notable memory or performance footprint (and also simple and small code).

Note to packagers

We recommend to create three different packages for this library, one for each component. As we do not anticipate new applications to use the rfc3195 component, we do not suggest building a package for it. On systems where systemd journal is present, there is hardly a point in packaging the journalemu component. So in esscence, the stdlog component is the only one we suggest to be packaged on many platforms.

Depending on distro policies, package names like liblogging1-stdlog are suggested. This prevents confusion with liblogging v0, which only supported rfc3195.

History

Liblogging is around since 2002. See HISTORY file for some background information on how it evolved and why it is structured like it currently is.

liblogging's People

Contributors

dabright avatar jgerhards avatar mbiebl avatar purnimam1 avatar rgerhards avatar uggedal avatar whissi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

liblogging's Issues

clarify library structure

most importantly, specify components available; would definitely help to add some history information (why are we where we are?).

stdlogctl.c, tester.c don't include <stdarg.h> - don't compile

$ make
make  all-recursive
make[1]: Entering directory `/data/gordon/sources/liblogging'
Making all in stdlog
make[2]: Entering directory `/data/gordon/sources/liblogging/stdlog'
  CC       stdlogctl-stdlogctl.o
In file included from stdlogctl.c:32:0:
stdlog.h:80:75: error: unknown type name ‘va_list’
 int stdlog_vlog(stdlog_channel_t ch, const int severity, const char *fmt, va_list ap);
                                                                           ^
In file included from stdlogctl.c:32:0:
stdlog.h:81:131: error: unknown type name ‘va_list’
 int stdlog_vlog_b(stdlog_channel_t ch, const int severity, char *__restrict__ const wrkbuf, const size_t buflen, const char *fmt, va_list ap);
                                                                                                                                   ^
make[2]: *** [stdlogctl-stdlogctl.o] Error 1
make[2]: Leaving directory `/data/gordon/sources/liblogging/stdlog'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/data/gordon/sources/liblogging'
make: *** [all] Error 2

build_file_line and build_syslog_frame call the __stdlog_print_* functions incorrectly

In constructing the message header, both file.c/build_file_line() and uxsock.c/build_syslog_frame() will call the _stdlog_fmt_print* functions. However, in so doing, it incorrectly passes the buffer length minus the length of the characters already inserted. Those functions already take into account the length of the characters previously inserted into the buffer, so there is no reason to subtract their length. Doing so will cause needless truncation of the messages. Granted, this will only be a problem with very short buffer lengths, but you can see the effect when running the tester.c program (which uses such a short buffer). See the output from this sample run (using the syslog: channel spec):

Jun 9 11:45:30 testhost001 : Test abc, 4712,

You can see that the TAG ("tester", the ident supplied in stdlog_open()) is missing but the following colon and the first part of the message text is present. The TAG is missing since when calling the __stdlog_fmt_print_str() call, the size of the buffer passed is 40 (the actual buffer size) - 21 (the current value of idx) = 19, so when __stdlog_fmt_print_str() checks the room available it checks 21 against the passed-in buffer size (19) and finds the buffer (over-)full and so does not insert any characters.

The corrected log line would look like:

Jun 9 11:45:30 testhost001 tester: Test abc,

Don't override {C,LD}FLAGS

$CFLAGS and $LDFLAGS are user variables. Therefore we shouldn't override them. Instead of

if test "$GCC" = "yes"; then
   CFLAGS="${CFLAGS} -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g"
fi

use something like

if test "$GCC" = "yes"; then
    AM_CFLAGS="-W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g"
fi

But the problem is that we would have to add $AM_CFLAGS to every declaration, for example we would have to add something like

liblogging_stdlog_la_CFLAGS = ${AM_CFLAGS}

to stdlog/Makefile.am because the root Makefile won't automatically pass the value to Makefiles in subdirs.

Another approach would be to create a common.am Makefile where we would set AM_CFLAGS and to include common.am in all the Makefiles in subdirs...

Interface for structured logging

The README.md file lists the following motivation for this library:

  • provide an interface for structured logging - but only if there is a real demand for it (to be seen based on feedback)

I think this would be very valuable. Machines with systemd can use native journal API calls to add structured data to the system journal. Some packages are adding support for this, but it has to be a compile-time option for the package to remain portable to non-systemd (or even non-Linux) machines. I see a need for a universal system call for "log this with structured data" that can work with the journal or syslog daemons.

The hard question is: how should the structured message be formatted? For journal output, it's easy. Just call the native API and let journald figure it out. When writing to /dev/log, we have to use an easy-to-parse structure. We can use RFC-5424, raw JSON, @Cee JSON (umberlog?), or some new format. Do we really want a JSON serializer in liblogging? Or require packages to pull in an external JSON serializer? Anyway, I'm not a big fan of taking a tree of key-value pairs, serializing them to a JSON string, having the syslog daemon deserialize it back into variables (possibly modifying or adding fields), and then syslog serializes it for output (to a file or over the network).

journald still uses a UNIX socket, right? Maybe we could borrow it's over-the-socket format? I wonder if that's a public/stable protocol?

__stdlog_sigsafe_printf incorrectly formats int or unsigned

When processing an int or unsigned (%d or %u) format specification, __stdlog_sigsafe_printf loads a long instead of int or unsigned.

The following patch fixes the issue:

diff --git a/extras/liblogging/stdlog/formatter.c b/extras/liblogging/stdlog/formatter.c
index 7325c99..563fa07 100644
--- a/extras/liblogging/stdlog/formatter.c
+++ b/extras/liblogging/stdlog/formatter.c
@@ -188,7 +188,7 @@ __stdlog_sigsafe_printf(char *buf, size_t lenbuf, const char *fmt, va_list ap)
        int precision;
        int i = 0;
        double dbl;
-       enum {LMOD_LONG, LMOD_LONG_LONG,
+       enum {LMOD_NONE, LMOD_LONG, LMOD_LONG_LONG,
              LMOD_SIZE_T, LMOD_SHORT, LMOD_CHAR} length_modifier;

        --lenbuf; /* reserve for terminal \0 */
@@ -237,7 +237,7 @@ __stdlog_sigsafe_printf(char *buf, size_t lenbuf, const char *fmt, va_list ap)
                        }

                        /* length modifiers */
-                       length_modifier = 0;
+                       length_modifier = LMOD_NONE;
                        switch(*fmt) {
                        case '\0':
                                goto done;

License for the ligblogging?

Based on the stdlog.rst, my understanding is that the liblogging should be BSD 2-clause license. Just want to confirm if it is BSD 2-clause license?

clarify license

select most liberal one, given the restrictions of the existing code

make distcheck fails on systems without systemd journal

"make distcheck" fails because the journal driver is enabled by default and as such ./configure fails if libsystemd-journal is not present.

A simple solution is obviously to disable building journal during distcheck. But that reduces the checked code paths. Ideally, I would like to disable it if the journal is not present, but enable it otherwise. Unfortunately, I don't know how to do that in autotools...

Anyone can lend a helping hand?

Add more \xxx escapes to printf implementation

We currently support a too-small subset. But before we extend it, we should think if we really want to have control characters inside our log messages (or maybe make this a config option?).

libsystemd pc file name changes

from http://www.liblogging.org/2014/04/liblogging-104-released.html :

This version stills finding for "libsystemd-journal.pc" when the option "--enable-journal" is passed to the configure script. From system-209 the default behaviour is merging the libraries into single libsystemd(.pc) files, so there is no more "libsystemd-journal.pc" but a "libsystemd.pc" instead.
Those old files are installed only if you pass the "--enable-compat-libs" to the systemd configure script, but that option is disabled by default.
I suggest to fix this problem changing your configure script to find for "libsystemd.pc" instead of "libsystemd-journal.pc".
Is it possible to see this fix in the next release?

Potential buffer overrun

From Assaf Gordon's review:

The internal message building functions (e.g. build_file_line, build_syslog_frame) do not check the length of the buffer when adding characters, e.g.:

frame[i++] = ':';
frame[i++] = ' ';

A maliciously constructed message (which consumes all the way up to __STDLOG_MSGBUF_SIZE (4096 bytes)) will cause a stack buffer overflow.

new release

Can we get a new release? Want to update brew formula and we don't build agains head resources.

libloggin-1.0.2: make[2]: stdlogctl.rst: Command not found

Hi,

issue #10 was mostly about a QA issue. The *.rst files are in the tarball. But there's another problem:

>>> Configuring source in /var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2 ...
>>> Working in BUILD_DIR: "/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2_build"
 * econf: updating liblogging-1.0.2/config.guess with /usr/share/gnuconfig/config.guess
 * econf: updating liblogging-1.0.2/config.sub with /usr/share/gnuconfig/config.sub
/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/configure --prefix=/usr --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --mandir=/usr/share/man --infodir=/usr/share/info --datadir=/usr/share --sysconfdir=/etc --localstatedir=/var/lib --libdir=/usr/lib64 --disable-silent-rules --disable-dependency-tracking --docdir=/usr/share/doc/liblogging-1.0.2 --enable-shared --disable-static --enable-cached-man-pages --disable-rfc3195 --enable-stdlog --disable-journal
configure: loading site script /usr/share/config.site
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking whether make supports nested variables... (cached) yes
checking for x86_64-pc-linux-gnu-gcc... x86_64-pc-linux-gnu-gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether x86_64-pc-linux-gnu-gcc accepts -g... yes
checking for x86_64-pc-linux-gnu-gcc option to accept ISO C89... none needed
checking whether x86_64-pc-linux-gnu-gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of x86_64-pc-linux-gnu-gcc... none
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking how to print strings... printf
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by x86_64-pc-linux-gnu-gcc... /usr/x86_64-pc-linux-gnu/bin/ld
checking if the linker (/usr/x86_64-pc-linux-gnu/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/x86_64-pc-linux-gnu-nm -B
checking the name lister (/usr/bin/x86_64-pc-linux-gnu-nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noop
checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop
checking for /usr/x86_64-pc-linux-gnu/bin/ld option to reload object files... -r
checking for x86_64-pc-linux-gnu-objdump... x86_64-pc-linux-gnu-objdump
checking how to recognize dependent libraries... pass_all
checking for x86_64-pc-linux-gnu-dlltool... no
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for x86_64-pc-linux-gnu-ar... x86_64-pc-linux-gnu-ar
checking for archiver @FILE support... @
checking for x86_64-pc-linux-gnu-strip... x86_64-pc-linux-gnu-strip
checking for x86_64-pc-linux-gnu-ranlib... x86_64-pc-linux-gnu-ranlib
checking command to parse /usr/bin/x86_64-pc-linux-gnu-nm -B output from x86_64-pc-linux-gnu-gcc object... ok
checking for sysroot... no
checking for x86_64-pc-linux-gnu-mt... no
checking for mt... no
checking if : is a manifest tool... no
checking how to run the C preprocessor... x86_64-pc-linux-gnu-gcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if x86_64-pc-linux-gnu-gcc supports -fno-rtti -fno-exceptions... no
checking for x86_64-pc-linux-gnu-gcc option to produce PIC... -fPIC -DPIC
checking if x86_64-pc-linux-gnu-gcc PIC flag -fPIC -DPIC works... yes
checking if x86_64-pc-linux-gnu-gcc static flag -static works... yes
checking if x86_64-pc-linux-gnu-gcc supports -c -o file.o... yes
checking if x86_64-pc-linux-gnu-gcc supports -c -o file.o... (cached) yes
checking whether the x86_64-pc-linux-gnu-gcc linker (/usr/x86_64-pc-linux-gnu/bin/ld -m elf_x86_64) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no
checking for ANSI C header files... (cached) yes
checking netdb.h usability... yes
checking netdb.h presence... yes
checking for netdb.h... yes
checking netinet/in.h usability... yes
checking netinet/in.h presence... yes
checking for netinet/in.h... yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking sys/socket.h usability... yes
checking sys/socket.h presence... yes
checking for sys/socket.h... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking for unistd.h... (cached) yes
checking for an ANSI C-conforming const... yes
checking for size_t... yes
checking whether time.h and sys/time.h may both be included... yes
checking whether struct tm is in sys/time.h or time.h... time.h
checking for stdlib.h... (cached) yes
checking for GNU libc compatible malloc... yes
checking sys/select.h usability... yes
checking sys/select.h presence... yes
checking for sys/select.h... yes
checking for sys/socket.h... (cached) yes
checking types of arguments for select... int,fd_set *,struct timeval *
checking return type of signal handlers... void
checking for gethostbyname... yes
checking for gethostname... yes
checking for gettimeofday... yes
checking for inet_ntoa... yes
checking for memset... yes
checking for select... yes
checking for socket... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating rfc3195/liblogging-rfc3195.pc
config.status: creating rfc3195/doc/Makefile
config.status: creating rfc3195/doc/html/Makefile
config.status: creating rfc3195/src/Makefile
config.status: creating stdlog/liblogging-stdlog.pc
config.status: creating stdlog/Makefile
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing libtool commands
********************************************************
liblogging will be compiled with the following settings:

stdlog support enabled:               yes
systemd journal support:              no
rfc3195 support enabled:              no
using cached copies of man files:     yes
>>> Source configured.

[...]

libtool: link: x86_64-pc-linux-gnu-gcc -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -Wl,-O1 -o .libs/tester tester.o  -Wl,--as-needed ./.libs/liblogging-stdlog.so
stdlogctl.rst stdlogctl.1
make[2]: stdlogctl.rst: Command not found
Makefile:926: recipe for target 'stdlogctl.1' failed
make[2]: *** [stdlogctl.1] Error 127

make[2]: execvp: liblogging-1.0.2/stdlog/stdlogctl.rst: Permission denied

Hi,

I've problems preparing an ebuild for Gentoo:

>>> Unpacking source...
>>> Unpacking liblogging-1.0.2.tar.gz to /var/tmp/portage/dev-libs/liblogging-1.0.2/work
>>> Source unpacked in /var/tmp/portage/dev-libs/liblogging-1.0.2/work
>>> Preparing source in /var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2 ...
 * Running eautoreconf in '/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2' ...
 * Running libtoolize --install --copy --force --automake ...                                                 [ ok ]
 * Running aclocal -I m4 ...                                                                                  [ ok ]
 * Running autoconf ...                                                                                       [ ok ]
 * Running autoheader ...                                                                                     [ ok ]
 * Running automake --add-missing --copy --foreign --force-missing ...                                        [ ok ]
 * Running elibtoolize in: liblogging-1.0.2/
 *   Applying portage/1.2.0 patch ...
 *   Applying sed/1.5.6 patch ...
 *   Applying as-needed/2.4.2 patch ...
 *   Applying target-nm/2.4.2 patch ...
>>> Source prepared.
>>> Configuring source in /var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2 ...
>>> Working in BUILD_DIR: "/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2_build"
 * econf: updating liblogging-1.0.2/config.guess with /usr/share/gnuconfig/config.guess
 * econf: updating liblogging-1.0.2/config.sub with /usr/share/gnuconfig/config.sub
/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/configure --prefix=/usr --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --mandir=/usr/share/man --infodir=/usr/share/info --datadir=/usr/share --sysconfdir=/etc --localstatedir=/var/lib --libdir=/usr/lib64 --disable-silent-rules --disable-dependency-tracking --docdir=/usr/share/doc/liblogging-1.0.2 --enable-shared --disable-static --enable-cached-man-pages --disable-rfc3195 --enable-stdlog --disable-journal
configure: loading site script /usr/share/config.site
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking whether make supports nested variables... (cached) yes
checking for x86_64-pc-linux-gnu-gcc... x86_64-pc-linux-gnu-gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether x86_64-pc-linux-gnu-gcc accepts -g... yes
checking for x86_64-pc-linux-gnu-gcc option to accept ISO C89... none needed
checking whether x86_64-pc-linux-gnu-gcc understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of x86_64-pc-linux-gnu-gcc... none
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking how to print strings... printf
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F
checking for ld used by x86_64-pc-linux-gnu-gcc... /usr/x86_64-pc-linux-gnu/bin/ld
checking if the linker (/usr/x86_64-pc-linux-gnu/bin/ld) is GNU ld... yes
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/x86_64-pc-linux-gnu-nm -B
checking the name lister (/usr/bin/x86_64-pc-linux-gnu-nm -B) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 1572864
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking how to convert x86_64-pc-linux-gnu file names to x86_64-pc-linux-gnu format... func_convert_file_noop
checking how to convert x86_64-pc-linux-gnu file names to toolchain format... func_convert_file_noop
checking for /usr/x86_64-pc-linux-gnu/bin/ld option to reload object files... -r
checking for x86_64-pc-linux-gnu-objdump... x86_64-pc-linux-gnu-objdump
checking how to recognize dependent libraries... pass_all
checking for x86_64-pc-linux-gnu-dlltool... no
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for x86_64-pc-linux-gnu-ar... x86_64-pc-linux-gnu-ar
checking for archiver @FILE support... @
checking for x86_64-pc-linux-gnu-strip... x86_64-pc-linux-gnu-strip
checking for x86_64-pc-linux-gnu-ranlib... x86_64-pc-linux-gnu-ranlib
checking command to parse /usr/bin/x86_64-pc-linux-gnu-nm -B output from x86_64-pc-linux-gnu-gcc object... ok
checking for sysroot... no
checking for x86_64-pc-linux-gnu-mt... no
checking for mt... no
checking if : is a manifest tool... no
checking how to run the C preprocessor... x86_64-pc-linux-gnu-gcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if x86_64-pc-linux-gnu-gcc supports -fno-rtti -fno-exceptions... no
checking for x86_64-pc-linux-gnu-gcc option to produce PIC... -fPIC -DPIC
checking if x86_64-pc-linux-gnu-gcc PIC flag -fPIC -DPIC works... yes
checking if x86_64-pc-linux-gnu-gcc static flag -static works... yes
checking if x86_64-pc-linux-gnu-gcc supports -c -o file.o... yes
checking if x86_64-pc-linux-gnu-gcc supports -c -o file.o... (cached) yes
checking whether the x86_64-pc-linux-gnu-gcc linker (/usr/x86_64-pc-linux-gnu/bin/ld -m elf_x86_64) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no
checking for ANSI C header files... (cached) yes
checking netdb.h usability... yes
checking netdb.h presence... yes
checking for netdb.h... yes
checking netinet/in.h usability... yes
checking netinet/in.h presence... yes
checking for netinet/in.h... yes
checking for stdlib.h... (cached) yes
checking for string.h... (cached) yes
checking sys/socket.h usability... yes
checking sys/socket.h presence... yes
checking for sys/socket.h... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking for unistd.h... (cached) yes
checking for an ANSI C-conforming const... yes
checking for size_t... yes
checking whether time.h and sys/time.h may both be included... yes
checking whether struct tm is in sys/time.h or time.h... time.h
checking for stdlib.h... (cached) yes
checking for GNU libc compatible malloc... yes
checking sys/select.h usability... yes
checking sys/select.h presence... yes
checking for sys/select.h... yes
checking for sys/socket.h... (cached) yes
checking types of arguments for select... int,fd_set *,struct timeval *
checking return type of signal handlers... void
checking for gethostbyname... yes
checking for gethostname... yes
checking for gettimeofday... yes
checking for inet_ntoa... yes
checking for memset... yes
checking for select... yes
checking for socket... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating rfc3195/liblogging-rfc3195.pc
config.status: creating rfc3195/doc/Makefile
config.status: creating rfc3195/doc/html/Makefile
config.status: creating rfc3195/src/Makefile
config.status: creating stdlog/liblogging-stdlog.pc
config.status: creating stdlog/Makefile
config.status: creating config.h
config.status: executing depfiles commands
config.status: executing libtool commands
********************************************************
liblogging will be compiled with the following settings:

stdlog support enabled:               yes
systemd journal support:              no
rfc3195 support enabled:              no
using cached copies of man files:     yes
>>> Source configured.
>>> Compiling source in /var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2 ...
>>> Working in BUILD_DIR: "/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2_build"
make -j1
make  all-recursive
make[1]: Entering directory '/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2_build'
Making all in stdlog
make[2]: Entering directory '/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2_build/stdlog'
/bin/sh ../libtool  --tag=CC   --mode=compile x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog -I..     -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -c -o liblogging_stdlog_la-stdlog.lo `test -f 'stdlog.c' || echo '/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/'`stdlog.c
libtool: compile:  x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog -I.. -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -c /var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/stdlog.c  -fPIC -DPIC -o .libs/liblogging_stdlog_la-stdlog.o
/bin/sh ../libtool  --tag=CC   --mode=compile x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog -I..     -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -c -o liblogging_stdlog_la-uxsock.lo `test -f 'uxsock.c' || echo '/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/'`uxsock.c
libtool: compile:  x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog -I.. -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -c /var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/uxsock.c  -fPIC -DPIC -o .libs/liblogging_stdlog_la-uxsock.o
/bin/sh ../libtool  --tag=CC   --mode=compile x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog -I..     -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -c -o liblogging_stdlog_la-file.lo `test -f 'file.c' || echo '/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/'`file.c
libtool: compile:  x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog -I.. -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -c /var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/file.c  -fPIC -DPIC -o .libs/liblogging_stdlog_la-file.o
/bin/sh ../libtool  --tag=CC   --mode=compile x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog -I..     -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -c -o liblogging_stdlog_la-formatter.lo `test -f 'formatter.c' || echo '/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/'`formatter.c
libtool: compile:  x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog -I.. -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -c /var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/formatter.c  -fPIC -DPIC -o .libs/liblogging_stdlog_la-formatter.o
/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/formatter.c: In function '__stdlog_wrapper_vsnprintf':
/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/formatter.c:348:2: warning: function might be possible candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
  len = vsnprintf(buf, lenbuf, fmt, ap);
  ^
/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/formatter.c:348:2: warning: function might be possible candidate for 'gnu_printf' format attribute [-Wsuggest-attribute=format]
/bin/sh ../libtool  --tag=CC   --mode=compile x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog -I..     -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -c -o liblogging_stdlog_la-timeutils.lo `test -f 'timeutils.c' || echo '/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/'`timeutils.c
libtool: compile:  x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog -I.. -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -c /var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/timeutils.c  -fPIC -DPIC -o .libs/liblogging_stdlog_la-timeutils.o
/bin/sh ../libtool  --tag=CC   --mode=link x86_64-pc-linux-gnu-gcc  -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g  -Wl,-O1 -Wl,--as-needed -o liblogging-stdlog.la -rpath /usr/lib64 liblogging_stdlog_la-stdlog.lo liblogging_stdlog_la-uxsock.lo liblogging_stdlog_la-file.lo liblogging_stdlog_la-formatter.lo liblogging_stdlog_la-timeutils.lo
libtool: link: x86_64-pc-linux-gnu-gcc -shared  -fPIC -DPIC  .libs/liblogging_stdlog_la-stdlog.o .libs/liblogging_stdlog_la-uxsock.o .libs/liblogging_stdlog_la-file.o .libs/liblogging_stdlog_la-formatter.o .libs/liblogging_stdlog_la-timeutils.o   -Wl,--as-needed  -O2 -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt -mtune=generic -Wl,-O1   -Wl,-soname -Wl,liblogging-stdlog.so.0 -o .libs/liblogging-stdlog.so.0.0.0
libtool: link: (cd ".libs" && rm -f "liblogging-stdlog.so.0" && ln -s "liblogging-stdlog.so.0.0.0" "liblogging-stdlog.so.0")
libtool: link: (cd ".libs" && rm -f "liblogging-stdlog.so" && ln -s "liblogging-stdlog.so.0.0.0" "liblogging-stdlog.so")
libtool: link: ( cd ".libs" && rm -f "liblogging-stdlog.la" && ln -s "../liblogging-stdlog.la" "liblogging-stdlog.la" )
x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog -I..     -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -c -o stdlogctl-stdlogctl.o `test -f 'stdlogctl.c' || echo '/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/'`stdlogctl.c
/bin/sh ../libtool  --tag=CC   --mode=link x86_64-pc-linux-gnu-gcc  -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g  -Wl,-O1 -Wl,--as-needed -o stdlogctl stdlogctl-stdlogctl.o liblogging-stdlog.la
libtool: link: x86_64-pc-linux-gnu-gcc -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -Wl,-O1 -o .libs/stdlogctl stdlogctl-stdlogctl.o  -Wl,--as-needed ./.libs/liblogging-stdlog.so
x86_64-pc-linux-gnu-gcc -DHAVE_CONFIG_H -I. -I/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog -I..     -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -c -o tester.o /var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/tester.c
/bin/sh ../libtool  --tag=CC   --mode=link x86_64-pc-linux-gnu-gcc  -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g  -Wl,-O1 -Wl,--as-needed -o tester tester.o liblogging-stdlog.la
libtool: link: x86_64-pc-linux-gnu-gcc -O2 -pipe -march=core-avx-i -mno-movbe -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mno-avx2 -mno-lzcnt -mno-rtm -mno-hle -mno-rdseed -mno-prfchw -mno-adx -mxsave -mxsaveopt --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=8192 -mtune=generic -W -Wall -Wformat-security -Wshadow -Wcast-align -Wpointer-arith -Wmissing-format-attribute -g -Wl,-O1 -o .libs/tester tester.o  -Wl,--as-needed ./.libs/liblogging-stdlog.so
/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/stdlogctl.rst stdlogctl.1
make[2]: execvp: /var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2/stdlog/stdlogctl.rst: Permission denied
Makefile:926: recipe for target 'stdlogctl.1' failed
make[2]: *** [stdlogctl.1] Error 127
make[2]: Leaving directory '/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2_build/stdlog'
Makefile:452: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/var/tmp/portage/dev-libs/liblogging-1.0.2/work/liblogging-1.0.2_build'
Makefile:360: recipe for target 'all' failed
make: *** [all] Error 2

add stdlog_log_r() API?

This may be useful for apps that want to log to the same channel, but do so in different threads or from different signal handlers. Would most probably make most sense when writing to text files.

To implement it, the message buffer as well as frame/line buffers need to be provided by the caller. The later is a bit of concern, as we need to expose a bit of our internal buffer handling.

__stdlog_sigsafe_printf gets SEGV if NULL is passed for %s format specification

If the caller of __stdlog_sigsafe_printf has a %s in the format specification and passes NULL for the pointer value (e.g., __stdlog_sigsafe_printf(buf, lenbuf, "%s", NULL) [which isn't exactly the calling sequence, but you probably get the idea]), __stdlog_fmt_print_str will end up with a SEGV when it tries to dereference the (NULL) pointer. Of course, passing NULL in this case is technically invalid and so the SEGV is in some sense justified behavior, but many systems will detect this situation in the standard printf() and avoid the SEGV. The following patch will give __stdlog_sigsafe_printf the same behavior:

diff --git a/extras/liblogging/stdlog/formatter.c b/extras/liblogging/stdlog/formatter.c
index ff57789..563fa07 100644
--- a/extras/liblogging/stdlog/formatter.c
+++ b/extras/liblogging/stdlog/formatter.c
@@ -164,11 +164,13 @@ void
 __stdlog_fmt_print_str (char *__restrict__ const buf, const size_t lenbuf,
        int *__restrict__ const idx, const char *const str)
 {
+       const char *const strornull = str ? str : "(null)";
        int i = *idx;
        int j = 0;

-       while(i < (int) lenbuf && str[j])
-               buf[i++] = str[j++];
+       while(i < (int) lenbuf && strornull[j])
+               buf[i++] = strornull[j++];
        *idx = i;
 }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.