132115b10SPawel Jakub Dawidek /*- 26ef7ddd7SPawel Jakub Dawidek * Copyright (c) 2009-2010 The FreeBSD Foundation 36ef7ddd7SPawel Jakub Dawidek * Copyright (c) 2011 Pawel Jakub Dawidek <pjd@FreeBSD.org> 432115b10SPawel Jakub Dawidek * All rights reserved. 532115b10SPawel Jakub Dawidek * 632115b10SPawel Jakub Dawidek * This software was developed by Pawel Jakub Dawidek under sponsorship from 732115b10SPawel Jakub Dawidek * the FreeBSD Foundation. 832115b10SPawel Jakub Dawidek * 932115b10SPawel Jakub Dawidek * Redistribution and use in source and binary forms, with or without 1032115b10SPawel Jakub Dawidek * modification, are permitted provided that the following conditions 1132115b10SPawel Jakub Dawidek * are met: 1232115b10SPawel Jakub Dawidek * 1. Redistributions of source code must retain the above copyright 1332115b10SPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer. 1432115b10SPawel Jakub Dawidek * 2. Redistributions in binary form must reproduce the above copyright 1532115b10SPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer in the 1632115b10SPawel Jakub Dawidek * documentation and/or other materials provided with the distribution. 1732115b10SPawel Jakub Dawidek * 1832115b10SPawel Jakub Dawidek * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 1932115b10SPawel Jakub Dawidek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2032115b10SPawel Jakub Dawidek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2132115b10SPawel Jakub Dawidek * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 2232115b10SPawel Jakub Dawidek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2332115b10SPawel Jakub Dawidek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2432115b10SPawel Jakub Dawidek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2532115b10SPawel Jakub Dawidek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2632115b10SPawel Jakub Dawidek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2732115b10SPawel Jakub Dawidek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2832115b10SPawel Jakub Dawidek * SUCH DAMAGE. 2932115b10SPawel Jakub Dawidek */ 3032115b10SPawel Jakub Dawidek 3132115b10SPawel Jakub Dawidek #include <sys/cdefs.h> 3232115b10SPawel Jakub Dawidek __FBSDID("$FreeBSD$"); 3332115b10SPawel Jakub Dawidek 3432115b10SPawel Jakub Dawidek #include <assert.h> 3532115b10SPawel Jakub Dawidek #include <errno.h> 3632115b10SPawel Jakub Dawidek #include <stdarg.h> 37eeb3cd67SPawel Jakub Dawidek #include <stdbool.h> 3832115b10SPawel Jakub Dawidek #include <stdio.h> 3932115b10SPawel Jakub Dawidek #include <stdlib.h> 4032115b10SPawel Jakub Dawidek #include <string.h> 4132115b10SPawel Jakub Dawidek #include <syslog.h> 4232115b10SPawel Jakub Dawidek 4332115b10SPawel Jakub Dawidek #include "pjdlog.h" 4432115b10SPawel Jakub Dawidek 45eeb3cd67SPawel Jakub Dawidek static bool pjdlog_initialized = false; 46*70db96bfSPawel Jakub Dawidek static int pjdlog_mode, pjdlog_debug_level; 4732115b10SPawel Jakub Dawidek static char pjdlog_prefix[128]; 4832115b10SPawel Jakub Dawidek 49eeb3cd67SPawel Jakub Dawidek void 50eeb3cd67SPawel Jakub Dawidek pjdlog_init(int mode) 51eeb3cd67SPawel Jakub Dawidek { 52eeb3cd67SPawel Jakub Dawidek 53eeb3cd67SPawel Jakub Dawidek assert(!pjdlog_initialized); 54eeb3cd67SPawel Jakub Dawidek assert(mode == PJDLOG_MODE_STD || mode == PJDLOG_MODE_SYSLOG); 55eeb3cd67SPawel Jakub Dawidek 56eeb3cd67SPawel Jakub Dawidek if (mode == PJDLOG_MODE_SYSLOG) 57eeb3cd67SPawel Jakub Dawidek openlog(NULL, LOG_PID | LOG_NDELAY, LOG_DAEMON); 58eeb3cd67SPawel Jakub Dawidek pjdlog_mode = mode; 59*70db96bfSPawel Jakub Dawidek pjdlog_debug_level = 0; 60*70db96bfSPawel Jakub Dawidek bzero(pjdlog_prefix, sizeof(pjdlog_prefix)); 61eeb3cd67SPawel Jakub Dawidek 62eeb3cd67SPawel Jakub Dawidek pjdlog_initialized = true; 63eeb3cd67SPawel Jakub Dawidek } 64eeb3cd67SPawel Jakub Dawidek 65eeb3cd67SPawel Jakub Dawidek void 66eeb3cd67SPawel Jakub Dawidek pjdlog_fini(void) 67eeb3cd67SPawel Jakub Dawidek { 68eeb3cd67SPawel Jakub Dawidek 69eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 70eeb3cd67SPawel Jakub Dawidek 71eeb3cd67SPawel Jakub Dawidek if (pjdlog_mode == PJDLOG_MODE_SYSLOG) 72eeb3cd67SPawel Jakub Dawidek closelog(); 73eeb3cd67SPawel Jakub Dawidek 74eeb3cd67SPawel Jakub Dawidek pjdlog_initialized = false; 75eeb3cd67SPawel Jakub Dawidek } 76eeb3cd67SPawel Jakub Dawidek 7732115b10SPawel Jakub Dawidek /* 7832115b10SPawel Jakub Dawidek * Configure where the logs should go. 7932115b10SPawel Jakub Dawidek * By default they are send to stdout/stderr, but after going into background 8032115b10SPawel Jakub Dawidek * (eg. by calling daemon(3)) application is responsible for changing mode to 8132115b10SPawel Jakub Dawidek * PJDLOG_MODE_SYSLOG, so logs will be send to syslog. 8232115b10SPawel Jakub Dawidek */ 8332115b10SPawel Jakub Dawidek void 8432115b10SPawel Jakub Dawidek pjdlog_mode_set(int mode) 8532115b10SPawel Jakub Dawidek { 8632115b10SPawel Jakub Dawidek 87eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 8832115b10SPawel Jakub Dawidek assert(mode == PJDLOG_MODE_STD || mode == PJDLOG_MODE_SYSLOG); 8932115b10SPawel Jakub Dawidek 90eeb3cd67SPawel Jakub Dawidek if (pjdlog_mode == mode) 91eeb3cd67SPawel Jakub Dawidek return; 926d19256bSPawel Jakub Dawidek 936d19256bSPawel Jakub Dawidek if (mode == PJDLOG_MODE_SYSLOG) 94c6245737SPawel Jakub Dawidek openlog(NULL, LOG_PID | LOG_NDELAY, LOG_DAEMON); 95eeb3cd67SPawel Jakub Dawidek else /* if (mode == PJDLOG_MODE_STD) */ 96eeb3cd67SPawel Jakub Dawidek closelog(); 97eeb3cd67SPawel Jakub Dawidek 98eeb3cd67SPawel Jakub Dawidek pjdlog_mode = mode; 9932115b10SPawel Jakub Dawidek } 10032115b10SPawel Jakub Dawidek 10132115b10SPawel Jakub Dawidek /* 10232115b10SPawel Jakub Dawidek * Return current mode. 10332115b10SPawel Jakub Dawidek */ 10432115b10SPawel Jakub Dawidek int 10532115b10SPawel Jakub Dawidek pjdlog_mode_get(void) 10632115b10SPawel Jakub Dawidek { 10732115b10SPawel Jakub Dawidek 108eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 109eeb3cd67SPawel Jakub Dawidek 11032115b10SPawel Jakub Dawidek return (pjdlog_mode); 11132115b10SPawel Jakub Dawidek } 11232115b10SPawel Jakub Dawidek 11332115b10SPawel Jakub Dawidek /* 11432115b10SPawel Jakub Dawidek * Set debug level. All the logs above the level specified here will be 11532115b10SPawel Jakub Dawidek * ignored. 11632115b10SPawel Jakub Dawidek */ 11732115b10SPawel Jakub Dawidek void 11832115b10SPawel Jakub Dawidek pjdlog_debug_set(int level) 11932115b10SPawel Jakub Dawidek { 12032115b10SPawel Jakub Dawidek 121eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 12232115b10SPawel Jakub Dawidek assert(level >= 0); 12332115b10SPawel Jakub Dawidek 12432115b10SPawel Jakub Dawidek pjdlog_debug_level = level; 12532115b10SPawel Jakub Dawidek } 12632115b10SPawel Jakub Dawidek 12732115b10SPawel Jakub Dawidek /* 12832115b10SPawel Jakub Dawidek * Return current debug level. 12932115b10SPawel Jakub Dawidek */ 13032115b10SPawel Jakub Dawidek int 13132115b10SPawel Jakub Dawidek pjdlog_debug_get(void) 13232115b10SPawel Jakub Dawidek { 13332115b10SPawel Jakub Dawidek 134eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 135eeb3cd67SPawel Jakub Dawidek 13632115b10SPawel Jakub Dawidek return (pjdlog_debug_level); 13732115b10SPawel Jakub Dawidek } 13832115b10SPawel Jakub Dawidek 13932115b10SPawel Jakub Dawidek /* 14032115b10SPawel Jakub Dawidek * Set prefix that will be used before each log. 14132115b10SPawel Jakub Dawidek * Setting prefix to NULL will remove it. 14232115b10SPawel Jakub Dawidek */ 14332115b10SPawel Jakub Dawidek void 14432115b10SPawel Jakub Dawidek pjdlog_prefix_set(const char *fmt, ...) 14532115b10SPawel Jakub Dawidek { 14632115b10SPawel Jakub Dawidek va_list ap; 14732115b10SPawel Jakub Dawidek 148eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 149eeb3cd67SPawel Jakub Dawidek 15032115b10SPawel Jakub Dawidek va_start(ap, fmt); 15109d6ae1bSPawel Jakub Dawidek pjdlogv_prefix_set(fmt, ap); 15232115b10SPawel Jakub Dawidek va_end(ap); 15332115b10SPawel Jakub Dawidek } 15432115b10SPawel Jakub Dawidek 15532115b10SPawel Jakub Dawidek /* 15632115b10SPawel Jakub Dawidek * Set prefix that will be used before each log. 15732115b10SPawel Jakub Dawidek * Setting prefix to NULL will remove it. 15832115b10SPawel Jakub Dawidek */ 15932115b10SPawel Jakub Dawidek void 16009d6ae1bSPawel Jakub Dawidek pjdlogv_prefix_set(const char *fmt, va_list ap) 16132115b10SPawel Jakub Dawidek { 16232115b10SPawel Jakub Dawidek 163eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 16432115b10SPawel Jakub Dawidek assert(fmt != NULL); 16532115b10SPawel Jakub Dawidek 16632115b10SPawel Jakub Dawidek vsnprintf(pjdlog_prefix, sizeof(pjdlog_prefix), fmt, ap); 16732115b10SPawel Jakub Dawidek } 16832115b10SPawel Jakub Dawidek 16932115b10SPawel Jakub Dawidek /* 17032115b10SPawel Jakub Dawidek * Convert log level into string. 17132115b10SPawel Jakub Dawidek */ 17232115b10SPawel Jakub Dawidek static const char * 17332115b10SPawel Jakub Dawidek pjdlog_level_string(int loglevel) 17432115b10SPawel Jakub Dawidek { 17532115b10SPawel Jakub Dawidek 17632115b10SPawel Jakub Dawidek switch (loglevel) { 17732115b10SPawel Jakub Dawidek case LOG_EMERG: 17832115b10SPawel Jakub Dawidek return ("EMERG"); 17932115b10SPawel Jakub Dawidek case LOG_ALERT: 18032115b10SPawel Jakub Dawidek return ("ALERT"); 18132115b10SPawel Jakub Dawidek case LOG_CRIT: 18232115b10SPawel Jakub Dawidek return ("CRIT"); 18332115b10SPawel Jakub Dawidek case LOG_ERR: 18432115b10SPawel Jakub Dawidek return ("ERROR"); 18532115b10SPawel Jakub Dawidek case LOG_WARNING: 18632115b10SPawel Jakub Dawidek return ("WARNING"); 18732115b10SPawel Jakub Dawidek case LOG_NOTICE: 18832115b10SPawel Jakub Dawidek return ("NOTICE"); 18932115b10SPawel Jakub Dawidek case LOG_INFO: 19032115b10SPawel Jakub Dawidek return ("INFO"); 19132115b10SPawel Jakub Dawidek case LOG_DEBUG: 19232115b10SPawel Jakub Dawidek return ("DEBUG"); 19332115b10SPawel Jakub Dawidek } 19432115b10SPawel Jakub Dawidek assert(!"Invalid log level."); 19532115b10SPawel Jakub Dawidek abort(); /* XXX: gcc */ 19632115b10SPawel Jakub Dawidek } 19732115b10SPawel Jakub Dawidek 19832115b10SPawel Jakub Dawidek /* 19932115b10SPawel Jakub Dawidek * Common log routine. 20032115b10SPawel Jakub Dawidek */ 20132115b10SPawel Jakub Dawidek void 20232115b10SPawel Jakub Dawidek pjdlog_common(int loglevel, int debuglevel, int error, const char *fmt, ...) 20332115b10SPawel Jakub Dawidek { 20432115b10SPawel Jakub Dawidek va_list ap; 20532115b10SPawel Jakub Dawidek 206eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 207eeb3cd67SPawel Jakub Dawidek 20832115b10SPawel Jakub Dawidek va_start(ap, fmt); 20932115b10SPawel Jakub Dawidek pjdlogv_common(loglevel, debuglevel, error, fmt, ap); 21032115b10SPawel Jakub Dawidek va_end(ap); 21132115b10SPawel Jakub Dawidek } 21232115b10SPawel Jakub Dawidek 21332115b10SPawel Jakub Dawidek /* 21432115b10SPawel Jakub Dawidek * Common log routine, which can handle regular log level as well as debug 21532115b10SPawel Jakub Dawidek * level. We decide here where to send the logs (stdout/stderr or syslog). 21632115b10SPawel Jakub Dawidek */ 21732115b10SPawel Jakub Dawidek void 21832115b10SPawel Jakub Dawidek pjdlogv_common(int loglevel, int debuglevel, int error, const char *fmt, 21932115b10SPawel Jakub Dawidek va_list ap) 22032115b10SPawel Jakub Dawidek { 22132115b10SPawel Jakub Dawidek 222eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 22332115b10SPawel Jakub Dawidek assert(loglevel == LOG_EMERG || loglevel == LOG_ALERT || 22432115b10SPawel Jakub Dawidek loglevel == LOG_CRIT || loglevel == LOG_ERR || 22532115b10SPawel Jakub Dawidek loglevel == LOG_WARNING || loglevel == LOG_NOTICE || 22632115b10SPawel Jakub Dawidek loglevel == LOG_INFO || loglevel == LOG_DEBUG); 22732115b10SPawel Jakub Dawidek assert(loglevel != LOG_DEBUG || debuglevel > 0); 22832115b10SPawel Jakub Dawidek assert(error >= -1); 22932115b10SPawel Jakub Dawidek 23032115b10SPawel Jakub Dawidek /* Ignore debug above configured level. */ 23132115b10SPawel Jakub Dawidek if (loglevel == LOG_DEBUG && debuglevel > pjdlog_debug_level) 23232115b10SPawel Jakub Dawidek return; 23332115b10SPawel Jakub Dawidek 23432115b10SPawel Jakub Dawidek switch (pjdlog_mode) { 23532115b10SPawel Jakub Dawidek case PJDLOG_MODE_STD: 23632115b10SPawel Jakub Dawidek { 23732115b10SPawel Jakub Dawidek FILE *out; 23832115b10SPawel Jakub Dawidek 23932115b10SPawel Jakub Dawidek /* 24032115b10SPawel Jakub Dawidek * We send errors and warning to stderr and the rest to stdout. 24132115b10SPawel Jakub Dawidek */ 24232115b10SPawel Jakub Dawidek switch (loglevel) { 24332115b10SPawel Jakub Dawidek case LOG_EMERG: 24432115b10SPawel Jakub Dawidek case LOG_ALERT: 24532115b10SPawel Jakub Dawidek case LOG_CRIT: 24632115b10SPawel Jakub Dawidek case LOG_ERR: 24732115b10SPawel Jakub Dawidek case LOG_WARNING: 24832115b10SPawel Jakub Dawidek out = stderr; 24932115b10SPawel Jakub Dawidek break; 25032115b10SPawel Jakub Dawidek case LOG_NOTICE: 25132115b10SPawel Jakub Dawidek case LOG_INFO: 25232115b10SPawel Jakub Dawidek case LOG_DEBUG: 25332115b10SPawel Jakub Dawidek out = stdout; 25432115b10SPawel Jakub Dawidek break; 25532115b10SPawel Jakub Dawidek default: 25632115b10SPawel Jakub Dawidek assert(!"Invalid loglevel."); 25732115b10SPawel Jakub Dawidek abort(); /* XXX: gcc */ 25832115b10SPawel Jakub Dawidek } 25932115b10SPawel Jakub Dawidek 26032115b10SPawel Jakub Dawidek fprintf(out, "[%s]", pjdlog_level_string(loglevel)); 26132115b10SPawel Jakub Dawidek /* Attach debuglevel if this is debug log. */ 26232115b10SPawel Jakub Dawidek if (loglevel == LOG_DEBUG) 26332115b10SPawel Jakub Dawidek fprintf(out, "[%d]", debuglevel); 26432115b10SPawel Jakub Dawidek fprintf(out, " %s", pjdlog_prefix); 26532115b10SPawel Jakub Dawidek vfprintf(out, fmt, ap); 26632115b10SPawel Jakub Dawidek if (error != -1) 26732115b10SPawel Jakub Dawidek fprintf(out, ": %s.", strerror(error)); 26832115b10SPawel Jakub Dawidek fprintf(out, "\n"); 2694767ee29SPawel Jakub Dawidek fflush(out); 27032115b10SPawel Jakub Dawidek break; 27132115b10SPawel Jakub Dawidek } 27232115b10SPawel Jakub Dawidek case PJDLOG_MODE_SYSLOG: 27332115b10SPawel Jakub Dawidek { 27432115b10SPawel Jakub Dawidek char log[1024]; 27532115b10SPawel Jakub Dawidek int len; 27632115b10SPawel Jakub Dawidek 27732115b10SPawel Jakub Dawidek len = snprintf(log, sizeof(log), "%s", pjdlog_prefix); 27832115b10SPawel Jakub Dawidek if ((size_t)len < sizeof(log)) 27920ec52dcSPawel Jakub Dawidek len += vsnprintf(log + len, sizeof(log) - len, fmt, ap); 28032115b10SPawel Jakub Dawidek if (error != -1 && (size_t)len < sizeof(log)) { 28132115b10SPawel Jakub Dawidek (void)snprintf(log + len, sizeof(log) - len, ": %s.", 28232115b10SPawel Jakub Dawidek strerror(error)); 28332115b10SPawel Jakub Dawidek } 28432115b10SPawel Jakub Dawidek syslog(loglevel, "%s", log); 28532115b10SPawel Jakub Dawidek break; 28632115b10SPawel Jakub Dawidek } 28732115b10SPawel Jakub Dawidek default: 28832115b10SPawel Jakub Dawidek assert(!"Invalid mode."); 28932115b10SPawel Jakub Dawidek } 29032115b10SPawel Jakub Dawidek } 29132115b10SPawel Jakub Dawidek 29232115b10SPawel Jakub Dawidek /* 29332115b10SPawel Jakub Dawidek * Regular logs. 29432115b10SPawel Jakub Dawidek */ 29532115b10SPawel Jakub Dawidek void 29632115b10SPawel Jakub Dawidek pjdlogv(int loglevel, const char *fmt, va_list ap) 29732115b10SPawel Jakub Dawidek { 29832115b10SPawel Jakub Dawidek 299eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 300eeb3cd67SPawel Jakub Dawidek 30132115b10SPawel Jakub Dawidek /* LOG_DEBUG is invalid here, pjdlogv?_debug() should be used. */ 30232115b10SPawel Jakub Dawidek assert(loglevel == LOG_EMERG || loglevel == LOG_ALERT || 30332115b10SPawel Jakub Dawidek loglevel == LOG_CRIT || loglevel == LOG_ERR || 30432115b10SPawel Jakub Dawidek loglevel == LOG_WARNING || loglevel == LOG_NOTICE || 30532115b10SPawel Jakub Dawidek loglevel == LOG_INFO); 30632115b10SPawel Jakub Dawidek 30732115b10SPawel Jakub Dawidek pjdlogv_common(loglevel, 0, -1, fmt, ap); 30832115b10SPawel Jakub Dawidek } 30932115b10SPawel Jakub Dawidek 31032115b10SPawel Jakub Dawidek /* 31132115b10SPawel Jakub Dawidek * Regular logs. 31232115b10SPawel Jakub Dawidek */ 31332115b10SPawel Jakub Dawidek void 31432115b10SPawel Jakub Dawidek pjdlog(int loglevel, const char *fmt, ...) 31532115b10SPawel Jakub Dawidek { 31632115b10SPawel Jakub Dawidek va_list ap; 31732115b10SPawel Jakub Dawidek 318eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 319eeb3cd67SPawel Jakub Dawidek 32032115b10SPawel Jakub Dawidek va_start(ap, fmt); 32132115b10SPawel Jakub Dawidek pjdlogv(loglevel, fmt, ap); 32232115b10SPawel Jakub Dawidek va_end(ap); 32332115b10SPawel Jakub Dawidek } 32432115b10SPawel Jakub Dawidek 32532115b10SPawel Jakub Dawidek /* 32632115b10SPawel Jakub Dawidek * Debug logs. 32732115b10SPawel Jakub Dawidek */ 32832115b10SPawel Jakub Dawidek void 32932115b10SPawel Jakub Dawidek pjdlogv_debug(int debuglevel, const char *fmt, va_list ap) 33032115b10SPawel Jakub Dawidek { 33132115b10SPawel Jakub Dawidek 332eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 333eeb3cd67SPawel Jakub Dawidek 33432115b10SPawel Jakub Dawidek pjdlogv_common(LOG_DEBUG, debuglevel, -1, fmt, ap); 33532115b10SPawel Jakub Dawidek } 33632115b10SPawel Jakub Dawidek 33732115b10SPawel Jakub Dawidek /* 33832115b10SPawel Jakub Dawidek * Debug logs. 33932115b10SPawel Jakub Dawidek */ 34032115b10SPawel Jakub Dawidek void 34132115b10SPawel Jakub Dawidek pjdlog_debug(int debuglevel, const char *fmt, ...) 34232115b10SPawel Jakub Dawidek { 34332115b10SPawel Jakub Dawidek va_list ap; 34432115b10SPawel Jakub Dawidek 345eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 346eeb3cd67SPawel Jakub Dawidek 34732115b10SPawel Jakub Dawidek va_start(ap, fmt); 34832115b10SPawel Jakub Dawidek pjdlogv_debug(debuglevel, fmt, ap); 34932115b10SPawel Jakub Dawidek va_end(ap); 35032115b10SPawel Jakub Dawidek } 35132115b10SPawel Jakub Dawidek 35232115b10SPawel Jakub Dawidek /* 35332115b10SPawel Jakub Dawidek * Error logs with errno logging. 35432115b10SPawel Jakub Dawidek */ 35532115b10SPawel Jakub Dawidek void 35632115b10SPawel Jakub Dawidek pjdlogv_errno(int loglevel, const char *fmt, va_list ap) 35732115b10SPawel Jakub Dawidek { 35832115b10SPawel Jakub Dawidek 359eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 360eeb3cd67SPawel Jakub Dawidek 36132115b10SPawel Jakub Dawidek pjdlogv_common(loglevel, 0, errno, fmt, ap); 36232115b10SPawel Jakub Dawidek } 36332115b10SPawel Jakub Dawidek 36432115b10SPawel Jakub Dawidek /* 36532115b10SPawel Jakub Dawidek * Error logs with errno logging. 36632115b10SPawel Jakub Dawidek */ 36732115b10SPawel Jakub Dawidek void 36832115b10SPawel Jakub Dawidek pjdlog_errno(int loglevel, const char *fmt, ...) 36932115b10SPawel Jakub Dawidek { 37032115b10SPawel Jakub Dawidek va_list ap; 37132115b10SPawel Jakub Dawidek 372eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 373eeb3cd67SPawel Jakub Dawidek 37432115b10SPawel Jakub Dawidek va_start(ap, fmt); 37532115b10SPawel Jakub Dawidek pjdlogv_errno(loglevel, fmt, ap); 37632115b10SPawel Jakub Dawidek va_end(ap); 37732115b10SPawel Jakub Dawidek } 37832115b10SPawel Jakub Dawidek 37932115b10SPawel Jakub Dawidek /* 38032115b10SPawel Jakub Dawidek * Log error, errno and exit. 38132115b10SPawel Jakub Dawidek */ 38232115b10SPawel Jakub Dawidek void 38332115b10SPawel Jakub Dawidek pjdlogv_exit(int exitcode, const char *fmt, va_list ap) 38432115b10SPawel Jakub Dawidek { 38532115b10SPawel Jakub Dawidek 386eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 387eeb3cd67SPawel Jakub Dawidek 38832115b10SPawel Jakub Dawidek pjdlogv_errno(LOG_ERR, fmt, ap); 38932115b10SPawel Jakub Dawidek exit(exitcode); 390e3031161SPawel Jakub Dawidek /* NOTREACHED */ 39132115b10SPawel Jakub Dawidek } 39232115b10SPawel Jakub Dawidek 39332115b10SPawel Jakub Dawidek /* 39432115b10SPawel Jakub Dawidek * Log error, errno and exit. 39532115b10SPawel Jakub Dawidek */ 39632115b10SPawel Jakub Dawidek void 39732115b10SPawel Jakub Dawidek pjdlog_exit(int exitcode, const char *fmt, ...) 39832115b10SPawel Jakub Dawidek { 39932115b10SPawel Jakub Dawidek va_list ap; 40032115b10SPawel Jakub Dawidek 401eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 402eeb3cd67SPawel Jakub Dawidek 40332115b10SPawel Jakub Dawidek va_start(ap, fmt); 40432115b10SPawel Jakub Dawidek pjdlogv_exit(exitcode, fmt, ap); 40532115b10SPawel Jakub Dawidek /* NOTREACHED */ 40632115b10SPawel Jakub Dawidek va_end(ap); 40732115b10SPawel Jakub Dawidek } 40832115b10SPawel Jakub Dawidek 40932115b10SPawel Jakub Dawidek /* 41032115b10SPawel Jakub Dawidek * Log error and exit. 41132115b10SPawel Jakub Dawidek */ 41232115b10SPawel Jakub Dawidek void 41332115b10SPawel Jakub Dawidek pjdlogv_exitx(int exitcode, const char *fmt, va_list ap) 41432115b10SPawel Jakub Dawidek { 41532115b10SPawel Jakub Dawidek 416eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 417eeb3cd67SPawel Jakub Dawidek 41832115b10SPawel Jakub Dawidek pjdlogv(LOG_ERR, fmt, ap); 41932115b10SPawel Jakub Dawidek exit(exitcode); 420e3031161SPawel Jakub Dawidek /* NOTREACHED */ 42132115b10SPawel Jakub Dawidek } 42232115b10SPawel Jakub Dawidek 42332115b10SPawel Jakub Dawidek /* 42432115b10SPawel Jakub Dawidek * Log error and exit. 42532115b10SPawel Jakub Dawidek */ 42632115b10SPawel Jakub Dawidek void 42732115b10SPawel Jakub Dawidek pjdlog_exitx(int exitcode, const char *fmt, ...) 42832115b10SPawel Jakub Dawidek { 42932115b10SPawel Jakub Dawidek va_list ap; 43032115b10SPawel Jakub Dawidek 431eeb3cd67SPawel Jakub Dawidek assert(pjdlog_initialized); 432eeb3cd67SPawel Jakub Dawidek 43332115b10SPawel Jakub Dawidek va_start(ap, fmt); 43432115b10SPawel Jakub Dawidek pjdlogv_exitx(exitcode, fmt, ap); 43532115b10SPawel Jakub Dawidek /* NOTREACHED */ 43632115b10SPawel Jakub Dawidek va_end(ap); 43732115b10SPawel Jakub Dawidek } 438524840d8SPawel Jakub Dawidek 439524840d8SPawel Jakub Dawidek /* 440524840d8SPawel Jakub Dawidek * Log assertion and exit. 441524840d8SPawel Jakub Dawidek */ 442524840d8SPawel Jakub Dawidek void 443524840d8SPawel Jakub Dawidek pjdlog_verify(const char *func, const char *file, int line, 44494bf851dSPawel Jakub Dawidek const char *failedexpr, const char *fmt, ...) 445524840d8SPawel Jakub Dawidek { 44694bf851dSPawel Jakub Dawidek va_list ap; 447524840d8SPawel Jakub Dawidek 44894bf851dSPawel Jakub Dawidek assert(pjdlog_initialized); 44994bf851dSPawel Jakub Dawidek 45094bf851dSPawel Jakub Dawidek /* 45194bf851dSPawel Jakub Dawidek * When there is no message we pass __func__ as 'fmt'. 45294bf851dSPawel Jakub Dawidek * It would be cleaner to pass NULL or "", but gcc generates a warning 45394bf851dSPawel Jakub Dawidek * for both of those. 45494bf851dSPawel Jakub Dawidek */ 45594bf851dSPawel Jakub Dawidek if (fmt != func) { 45694bf851dSPawel Jakub Dawidek va_start(ap, fmt); 45794bf851dSPawel Jakub Dawidek pjdlogv_critical(fmt, ap); 45894bf851dSPawel Jakub Dawidek va_end(ap); 45994bf851dSPawel Jakub Dawidek } 46094bf851dSPawel Jakub Dawidek if (failedexpr == NULL) { 46194bf851dSPawel Jakub Dawidek if (func == NULL) { 46294bf851dSPawel Jakub Dawidek pjdlog_critical("Aborted at file %s, line %d.", file, 46394bf851dSPawel Jakub Dawidek line); 46494bf851dSPawel Jakub Dawidek } else { 46594bf851dSPawel Jakub Dawidek pjdlog_critical("Aborted at function %s, file %s, line %d.", 46694bf851dSPawel Jakub Dawidek func, file, line); 46794bf851dSPawel Jakub Dawidek } 46894bf851dSPawel Jakub Dawidek } else { 469524840d8SPawel Jakub Dawidek if (func == NULL) { 470524840d8SPawel Jakub Dawidek pjdlog_critical("Assertion failed: (%s), file %s, line %d.", 471524840d8SPawel Jakub Dawidek failedexpr, file, line); 472524840d8SPawel Jakub Dawidek } else { 473524840d8SPawel Jakub Dawidek pjdlog_critical("Assertion failed: (%s), function %s, file %s, line %d.", 474524840d8SPawel Jakub Dawidek failedexpr, func, file, line); 475524840d8SPawel Jakub Dawidek } 47694bf851dSPawel Jakub Dawidek } 477524840d8SPawel Jakub Dawidek abort(); 478524840d8SPawel Jakub Dawidek } 479