132115b10SPawel Jakub Dawidek /*- 232115b10SPawel Jakub Dawidek * Copyright (c) 2009-2010 The FreeBSD Foundation 332115b10SPawel Jakub Dawidek * All rights reserved. 432115b10SPawel Jakub Dawidek * 532115b10SPawel Jakub Dawidek * This software was developed by Pawel Jakub Dawidek under sponsorship from 632115b10SPawel Jakub Dawidek * the FreeBSD Foundation. 732115b10SPawel Jakub Dawidek * 832115b10SPawel Jakub Dawidek * Redistribution and use in source and binary forms, with or without 932115b10SPawel Jakub Dawidek * modification, are permitted provided that the following conditions 1032115b10SPawel Jakub Dawidek * are met: 1132115b10SPawel Jakub Dawidek * 1. Redistributions of source code must retain the above copyright 1232115b10SPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer. 1332115b10SPawel Jakub Dawidek * 2. Redistributions in binary form must reproduce the above copyright 1432115b10SPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer in the 1532115b10SPawel Jakub Dawidek * documentation and/or other materials provided with the distribution. 1632115b10SPawel Jakub Dawidek * 1732115b10SPawel Jakub Dawidek * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 1832115b10SPawel Jakub Dawidek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1932115b10SPawel Jakub Dawidek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2032115b10SPawel Jakub Dawidek * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 2132115b10SPawel Jakub Dawidek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2232115b10SPawel Jakub Dawidek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2332115b10SPawel Jakub Dawidek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2432115b10SPawel Jakub Dawidek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2532115b10SPawel Jakub Dawidek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2632115b10SPawel Jakub Dawidek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2732115b10SPawel Jakub Dawidek * SUCH DAMAGE. 2832115b10SPawel Jakub Dawidek * 2932115b10SPawel Jakub Dawidek * $FreeBSD$ 3032115b10SPawel Jakub Dawidek */ 3132115b10SPawel Jakub Dawidek 3232115b10SPawel Jakub Dawidek #include <sys/cdefs.h> 3332115b10SPawel Jakub Dawidek __FBSDID("$FreeBSD$"); 3432115b10SPawel Jakub Dawidek 3532115b10SPawel Jakub Dawidek #include <assert.h> 3632115b10SPawel Jakub Dawidek #include <errno.h> 3732115b10SPawel Jakub Dawidek #include <stdarg.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 4532115b10SPawel Jakub Dawidek static int pjdlog_mode = PJDLOG_MODE_STD; 4632115b10SPawel Jakub Dawidek static int pjdlog_debug_level = 0; 4732115b10SPawel Jakub Dawidek static char pjdlog_prefix[128]; 4832115b10SPawel Jakub Dawidek 4932115b10SPawel Jakub Dawidek /* 5032115b10SPawel Jakub Dawidek * Configure where the logs should go. 5132115b10SPawel Jakub Dawidek * By default they are send to stdout/stderr, but after going into background 5232115b10SPawel Jakub Dawidek * (eg. by calling daemon(3)) application is responsible for changing mode to 5332115b10SPawel Jakub Dawidek * PJDLOG_MODE_SYSLOG, so logs will be send to syslog. 5432115b10SPawel Jakub Dawidek */ 5532115b10SPawel Jakub Dawidek void 5632115b10SPawel Jakub Dawidek pjdlog_mode_set(int mode) 5732115b10SPawel Jakub Dawidek { 5832115b10SPawel Jakub Dawidek 5932115b10SPawel Jakub Dawidek assert(mode == PJDLOG_MODE_STD || mode == PJDLOG_MODE_SYSLOG); 6032115b10SPawel Jakub Dawidek 6132115b10SPawel Jakub Dawidek pjdlog_mode = mode; 6232115b10SPawel Jakub Dawidek } 6332115b10SPawel Jakub Dawidek 6432115b10SPawel Jakub Dawidek /* 6532115b10SPawel Jakub Dawidek * Return current mode. 6632115b10SPawel Jakub Dawidek */ 6732115b10SPawel Jakub Dawidek int 6832115b10SPawel Jakub Dawidek pjdlog_mode_get(void) 6932115b10SPawel Jakub Dawidek { 7032115b10SPawel Jakub Dawidek 7132115b10SPawel Jakub Dawidek return (pjdlog_mode); 7232115b10SPawel Jakub Dawidek } 7332115b10SPawel Jakub Dawidek 7432115b10SPawel Jakub Dawidek /* 7532115b10SPawel Jakub Dawidek * Set debug level. All the logs above the level specified here will be 7632115b10SPawel Jakub Dawidek * ignored. 7732115b10SPawel Jakub Dawidek */ 7832115b10SPawel Jakub Dawidek void 7932115b10SPawel Jakub Dawidek pjdlog_debug_set(int level) 8032115b10SPawel Jakub Dawidek { 8132115b10SPawel Jakub Dawidek 8232115b10SPawel Jakub Dawidek assert(level >= 0); 8332115b10SPawel Jakub Dawidek 8432115b10SPawel Jakub Dawidek pjdlog_debug_level = level; 8532115b10SPawel Jakub Dawidek } 8632115b10SPawel Jakub Dawidek 8732115b10SPawel Jakub Dawidek /* 8832115b10SPawel Jakub Dawidek * Return current debug level. 8932115b10SPawel Jakub Dawidek */ 9032115b10SPawel Jakub Dawidek int 9132115b10SPawel Jakub Dawidek pjdlog_debug_get(void) 9232115b10SPawel Jakub Dawidek { 9332115b10SPawel Jakub Dawidek 9432115b10SPawel Jakub Dawidek return (pjdlog_debug_level); 9532115b10SPawel Jakub Dawidek } 9632115b10SPawel Jakub Dawidek 9732115b10SPawel Jakub Dawidek /* 9832115b10SPawel Jakub Dawidek * Set prefix that will be used before each log. 9932115b10SPawel Jakub Dawidek * Setting prefix to NULL will remove it. 10032115b10SPawel Jakub Dawidek */ 10132115b10SPawel Jakub Dawidek void 10232115b10SPawel Jakub Dawidek pjdlog_prefix_set(const char *fmt, ...) 10332115b10SPawel Jakub Dawidek { 10432115b10SPawel Jakub Dawidek va_list ap; 10532115b10SPawel Jakub Dawidek 10632115b10SPawel Jakub Dawidek va_start(ap, fmt); 10732115b10SPawel Jakub Dawidek pjdlog_prefix_setv(fmt, ap); 10832115b10SPawel Jakub Dawidek va_end(ap); 10932115b10SPawel Jakub Dawidek } 11032115b10SPawel Jakub Dawidek 11132115b10SPawel Jakub Dawidek /* 11232115b10SPawel Jakub Dawidek * Set prefix that will be used before each log. 11332115b10SPawel Jakub Dawidek * Setting prefix to NULL will remove it. 11432115b10SPawel Jakub Dawidek */ 11532115b10SPawel Jakub Dawidek void 11632115b10SPawel Jakub Dawidek pjdlog_prefix_setv(const char *fmt, va_list ap) 11732115b10SPawel Jakub Dawidek { 11832115b10SPawel Jakub Dawidek 11932115b10SPawel Jakub Dawidek assert(fmt != NULL); 12032115b10SPawel Jakub Dawidek 12132115b10SPawel Jakub Dawidek vsnprintf(pjdlog_prefix, sizeof(pjdlog_prefix), fmt, ap); 12232115b10SPawel Jakub Dawidek } 12332115b10SPawel Jakub Dawidek 12432115b10SPawel Jakub Dawidek /* 12532115b10SPawel Jakub Dawidek * Convert log level into string. 12632115b10SPawel Jakub Dawidek */ 12732115b10SPawel Jakub Dawidek static const char * 12832115b10SPawel Jakub Dawidek pjdlog_level_string(int loglevel) 12932115b10SPawel Jakub Dawidek { 13032115b10SPawel Jakub Dawidek 13132115b10SPawel Jakub Dawidek switch (loglevel) { 13232115b10SPawel Jakub Dawidek case LOG_EMERG: 13332115b10SPawel Jakub Dawidek return ("EMERG"); 13432115b10SPawel Jakub Dawidek case LOG_ALERT: 13532115b10SPawel Jakub Dawidek return ("ALERT"); 13632115b10SPawel Jakub Dawidek case LOG_CRIT: 13732115b10SPawel Jakub Dawidek return ("CRIT"); 13832115b10SPawel Jakub Dawidek case LOG_ERR: 13932115b10SPawel Jakub Dawidek return ("ERROR"); 14032115b10SPawel Jakub Dawidek case LOG_WARNING: 14132115b10SPawel Jakub Dawidek return ("WARNING"); 14232115b10SPawel Jakub Dawidek case LOG_NOTICE: 14332115b10SPawel Jakub Dawidek return ("NOTICE"); 14432115b10SPawel Jakub Dawidek case LOG_INFO: 14532115b10SPawel Jakub Dawidek return ("INFO"); 14632115b10SPawel Jakub Dawidek case LOG_DEBUG: 14732115b10SPawel Jakub Dawidek return ("DEBUG"); 14832115b10SPawel Jakub Dawidek } 14932115b10SPawel Jakub Dawidek assert(!"Invalid log level."); 15032115b10SPawel Jakub Dawidek abort(); /* XXX: gcc */ 15132115b10SPawel Jakub Dawidek } 15232115b10SPawel Jakub Dawidek 15332115b10SPawel Jakub Dawidek /* 15432115b10SPawel Jakub Dawidek * Common log routine. 15532115b10SPawel Jakub Dawidek */ 15632115b10SPawel Jakub Dawidek void 15732115b10SPawel Jakub Dawidek pjdlog_common(int loglevel, int debuglevel, int error, const char *fmt, ...) 15832115b10SPawel Jakub Dawidek { 15932115b10SPawel Jakub Dawidek va_list ap; 16032115b10SPawel Jakub Dawidek 16132115b10SPawel Jakub Dawidek va_start(ap, fmt); 16232115b10SPawel Jakub Dawidek pjdlogv_common(loglevel, debuglevel, error, fmt, ap); 16332115b10SPawel Jakub Dawidek va_end(ap); 16432115b10SPawel Jakub Dawidek } 16532115b10SPawel Jakub Dawidek 16632115b10SPawel Jakub Dawidek /* 16732115b10SPawel Jakub Dawidek * Common log routine, which can handle regular log level as well as debug 16832115b10SPawel Jakub Dawidek * level. We decide here where to send the logs (stdout/stderr or syslog). 16932115b10SPawel Jakub Dawidek */ 17032115b10SPawel Jakub Dawidek void 17132115b10SPawel Jakub Dawidek pjdlogv_common(int loglevel, int debuglevel, int error, const char *fmt, 17232115b10SPawel Jakub Dawidek va_list ap) 17332115b10SPawel Jakub Dawidek { 17432115b10SPawel Jakub Dawidek 17532115b10SPawel Jakub Dawidek assert(loglevel == LOG_EMERG || loglevel == LOG_ALERT || 17632115b10SPawel Jakub Dawidek loglevel == LOG_CRIT || loglevel == LOG_ERR || 17732115b10SPawel Jakub Dawidek loglevel == LOG_WARNING || loglevel == LOG_NOTICE || 17832115b10SPawel Jakub Dawidek loglevel == LOG_INFO || loglevel == LOG_DEBUG); 17932115b10SPawel Jakub Dawidek assert(loglevel != LOG_DEBUG || debuglevel > 0); 18032115b10SPawel Jakub Dawidek assert(error >= -1); 18132115b10SPawel Jakub Dawidek 18232115b10SPawel Jakub Dawidek /* Ignore debug above configured level. */ 18332115b10SPawel Jakub Dawidek if (loglevel == LOG_DEBUG && debuglevel > pjdlog_debug_level) 18432115b10SPawel Jakub Dawidek return; 18532115b10SPawel Jakub Dawidek 18632115b10SPawel Jakub Dawidek switch (pjdlog_mode) { 18732115b10SPawel Jakub Dawidek case PJDLOG_MODE_STD: 18832115b10SPawel Jakub Dawidek { 18932115b10SPawel Jakub Dawidek FILE *out; 19032115b10SPawel Jakub Dawidek 19132115b10SPawel Jakub Dawidek /* 19232115b10SPawel Jakub Dawidek * We send errors and warning to stderr and the rest to stdout. 19332115b10SPawel Jakub Dawidek */ 19432115b10SPawel Jakub Dawidek switch (loglevel) { 19532115b10SPawel Jakub Dawidek case LOG_EMERG: 19632115b10SPawel Jakub Dawidek case LOG_ALERT: 19732115b10SPawel Jakub Dawidek case LOG_CRIT: 19832115b10SPawel Jakub Dawidek case LOG_ERR: 19932115b10SPawel Jakub Dawidek case LOG_WARNING: 20032115b10SPawel Jakub Dawidek out = stderr; 20132115b10SPawel Jakub Dawidek break; 20232115b10SPawel Jakub Dawidek case LOG_NOTICE: 20332115b10SPawel Jakub Dawidek case LOG_INFO: 20432115b10SPawel Jakub Dawidek case LOG_DEBUG: 20532115b10SPawel Jakub Dawidek out = stdout; 20632115b10SPawel Jakub Dawidek break; 20732115b10SPawel Jakub Dawidek default: 20832115b10SPawel Jakub Dawidek assert(!"Invalid loglevel."); 20932115b10SPawel Jakub Dawidek abort(); /* XXX: gcc */ 21032115b10SPawel Jakub Dawidek } 21132115b10SPawel Jakub Dawidek 21232115b10SPawel Jakub Dawidek fprintf(out, "[%s]", pjdlog_level_string(loglevel)); 21332115b10SPawel Jakub Dawidek /* Attach debuglevel if this is debug log. */ 21432115b10SPawel Jakub Dawidek if (loglevel == LOG_DEBUG) 21532115b10SPawel Jakub Dawidek fprintf(out, "[%d]", debuglevel); 21632115b10SPawel Jakub Dawidek fprintf(out, " "); 21732115b10SPawel Jakub Dawidek fprintf(out, "%s", pjdlog_prefix); 21832115b10SPawel Jakub Dawidek vfprintf(out, fmt, ap); 21932115b10SPawel Jakub Dawidek if (error != -1) 22032115b10SPawel Jakub Dawidek fprintf(out, ": %s.", strerror(error)); 22132115b10SPawel Jakub Dawidek fprintf(out, "\n"); 22232115b10SPawel Jakub Dawidek break; 22332115b10SPawel Jakub Dawidek } 22432115b10SPawel Jakub Dawidek case PJDLOG_MODE_SYSLOG: 22532115b10SPawel Jakub Dawidek { 22632115b10SPawel Jakub Dawidek char log[1024]; 22732115b10SPawel Jakub Dawidek int len; 22832115b10SPawel Jakub Dawidek 22932115b10SPawel Jakub Dawidek len = snprintf(log, sizeof(log), "%s", pjdlog_prefix); 23032115b10SPawel Jakub Dawidek if ((size_t)len < sizeof(log)) 23120ec52dcSPawel Jakub Dawidek len += vsnprintf(log + len, sizeof(log) - len, fmt, ap); 23232115b10SPawel Jakub Dawidek if (error != -1 && (size_t)len < sizeof(log)) { 23332115b10SPawel Jakub Dawidek (void)snprintf(log + len, sizeof(log) - len, ": %s.", 23432115b10SPawel Jakub Dawidek strerror(error)); 23532115b10SPawel Jakub Dawidek } 23632115b10SPawel Jakub Dawidek syslog(loglevel, "%s", log); 23732115b10SPawel Jakub Dawidek break; 23832115b10SPawel Jakub Dawidek } 23932115b10SPawel Jakub Dawidek default: 24032115b10SPawel Jakub Dawidek assert(!"Invalid mode."); 24132115b10SPawel Jakub Dawidek } 24232115b10SPawel Jakub Dawidek } 24332115b10SPawel Jakub Dawidek 24432115b10SPawel Jakub Dawidek /* 24532115b10SPawel Jakub Dawidek * Regular logs. 24632115b10SPawel Jakub Dawidek */ 24732115b10SPawel Jakub Dawidek void 24832115b10SPawel Jakub Dawidek pjdlogv(int loglevel, const char *fmt, va_list ap) 24932115b10SPawel Jakub Dawidek { 25032115b10SPawel Jakub Dawidek 25132115b10SPawel Jakub Dawidek /* LOG_DEBUG is invalid here, pjdlogv?_debug() should be used. */ 25232115b10SPawel Jakub Dawidek assert(loglevel == LOG_EMERG || loglevel == LOG_ALERT || 25332115b10SPawel Jakub Dawidek loglevel == LOG_CRIT || loglevel == LOG_ERR || 25432115b10SPawel Jakub Dawidek loglevel == LOG_WARNING || loglevel == LOG_NOTICE || 25532115b10SPawel Jakub Dawidek loglevel == LOG_INFO); 25632115b10SPawel Jakub Dawidek 25732115b10SPawel Jakub Dawidek pjdlogv_common(loglevel, 0, -1, fmt, ap); 25832115b10SPawel Jakub Dawidek } 25932115b10SPawel Jakub Dawidek 26032115b10SPawel Jakub Dawidek /* 26132115b10SPawel Jakub Dawidek * Regular logs. 26232115b10SPawel Jakub Dawidek */ 26332115b10SPawel Jakub Dawidek void 26432115b10SPawel Jakub Dawidek pjdlog(int loglevel, const char *fmt, ...) 26532115b10SPawel Jakub Dawidek { 26632115b10SPawel Jakub Dawidek va_list ap; 26732115b10SPawel Jakub Dawidek 26832115b10SPawel Jakub Dawidek va_start(ap, fmt); 26932115b10SPawel Jakub Dawidek pjdlogv(loglevel, fmt, ap); 27032115b10SPawel Jakub Dawidek va_end(ap); 27132115b10SPawel Jakub Dawidek } 27232115b10SPawel Jakub Dawidek 27332115b10SPawel Jakub Dawidek /* 27432115b10SPawel Jakub Dawidek * Debug logs. 27532115b10SPawel Jakub Dawidek */ 27632115b10SPawel Jakub Dawidek void 27732115b10SPawel Jakub Dawidek pjdlogv_debug(int debuglevel, const char *fmt, va_list ap) 27832115b10SPawel Jakub Dawidek { 27932115b10SPawel Jakub Dawidek 28032115b10SPawel Jakub Dawidek pjdlogv_common(LOG_DEBUG, debuglevel, -1, fmt, ap); 28132115b10SPawel Jakub Dawidek } 28232115b10SPawel Jakub Dawidek 28332115b10SPawel Jakub Dawidek /* 28432115b10SPawel Jakub Dawidek * Debug logs. 28532115b10SPawel Jakub Dawidek */ 28632115b10SPawel Jakub Dawidek void 28732115b10SPawel Jakub Dawidek pjdlog_debug(int debuglevel, const char *fmt, ...) 28832115b10SPawel Jakub Dawidek { 28932115b10SPawel Jakub Dawidek va_list ap; 29032115b10SPawel Jakub Dawidek 29132115b10SPawel Jakub Dawidek va_start(ap, fmt); 29232115b10SPawel Jakub Dawidek pjdlogv_debug(debuglevel, fmt, ap); 29332115b10SPawel Jakub Dawidek va_end(ap); 29432115b10SPawel Jakub Dawidek } 29532115b10SPawel Jakub Dawidek 29632115b10SPawel Jakub Dawidek /* 29732115b10SPawel Jakub Dawidek * Error logs with errno logging. 29832115b10SPawel Jakub Dawidek */ 29932115b10SPawel Jakub Dawidek void 30032115b10SPawel Jakub Dawidek pjdlogv_errno(int loglevel, const char *fmt, va_list ap) 30132115b10SPawel Jakub Dawidek { 30232115b10SPawel Jakub Dawidek 30332115b10SPawel Jakub Dawidek pjdlogv_common(loglevel, 0, errno, fmt, ap); 30432115b10SPawel Jakub Dawidek } 30532115b10SPawel Jakub Dawidek 30632115b10SPawel Jakub Dawidek /* 30732115b10SPawel Jakub Dawidek * Error logs with errno logging. 30832115b10SPawel Jakub Dawidek */ 30932115b10SPawel Jakub Dawidek void 31032115b10SPawel Jakub Dawidek pjdlog_errno(int loglevel, const char *fmt, ...) 31132115b10SPawel Jakub Dawidek { 31232115b10SPawel Jakub Dawidek va_list ap; 31332115b10SPawel Jakub Dawidek 31432115b10SPawel Jakub Dawidek va_start(ap, fmt); 31532115b10SPawel Jakub Dawidek pjdlogv_errno(loglevel, fmt, ap); 31632115b10SPawel Jakub Dawidek va_end(ap); 31732115b10SPawel Jakub Dawidek } 31832115b10SPawel Jakub Dawidek 31932115b10SPawel Jakub Dawidek /* 32032115b10SPawel Jakub Dawidek * Log error, errno and exit. 32132115b10SPawel Jakub Dawidek */ 32232115b10SPawel Jakub Dawidek void 32332115b10SPawel Jakub Dawidek pjdlogv_exit(int exitcode, const char *fmt, va_list ap) 32432115b10SPawel Jakub Dawidek { 32532115b10SPawel Jakub Dawidek 32632115b10SPawel Jakub Dawidek pjdlogv_errno(LOG_ERR, fmt, ap); 32732115b10SPawel Jakub Dawidek exit(exitcode); 328*e3031161SPawel Jakub Dawidek /* NOTREACHED */ 32932115b10SPawel Jakub Dawidek } 33032115b10SPawel Jakub Dawidek 33132115b10SPawel Jakub Dawidek /* 33232115b10SPawel Jakub Dawidek * Log error, errno and exit. 33332115b10SPawel Jakub Dawidek */ 33432115b10SPawel Jakub Dawidek void 33532115b10SPawel Jakub Dawidek pjdlog_exit(int exitcode, const char *fmt, ...) 33632115b10SPawel Jakub Dawidek { 33732115b10SPawel Jakub Dawidek va_list ap; 33832115b10SPawel Jakub Dawidek 33932115b10SPawel Jakub Dawidek va_start(ap, fmt); 34032115b10SPawel Jakub Dawidek pjdlogv_exit(exitcode, fmt, ap); 34132115b10SPawel Jakub Dawidek /* NOTREACHED */ 34232115b10SPawel Jakub Dawidek va_end(ap); 34332115b10SPawel Jakub Dawidek } 34432115b10SPawel Jakub Dawidek 34532115b10SPawel Jakub Dawidek /* 34632115b10SPawel Jakub Dawidek * Log error and exit. 34732115b10SPawel Jakub Dawidek */ 34832115b10SPawel Jakub Dawidek void 34932115b10SPawel Jakub Dawidek pjdlogv_exitx(int exitcode, const char *fmt, va_list ap) 35032115b10SPawel Jakub Dawidek { 35132115b10SPawel Jakub Dawidek 35232115b10SPawel Jakub Dawidek pjdlogv(LOG_ERR, fmt, ap); 35332115b10SPawel Jakub Dawidek exit(exitcode); 354*e3031161SPawel Jakub Dawidek /* NOTREACHED */ 35532115b10SPawel Jakub Dawidek } 35632115b10SPawel Jakub Dawidek 35732115b10SPawel Jakub Dawidek /* 35832115b10SPawel Jakub Dawidek * Log error and exit. 35932115b10SPawel Jakub Dawidek */ 36032115b10SPawel Jakub Dawidek void 36132115b10SPawel Jakub Dawidek pjdlog_exitx(int exitcode, const char *fmt, ...) 36232115b10SPawel Jakub Dawidek { 36332115b10SPawel Jakub Dawidek va_list ap; 36432115b10SPawel Jakub Dawidek 36532115b10SPawel Jakub Dawidek va_start(ap, fmt); 36632115b10SPawel Jakub Dawidek pjdlogv_exitx(exitcode, fmt, ap); 36732115b10SPawel Jakub Dawidek /* NOTREACHED */ 36832115b10SPawel Jakub Dawidek va_end(ap); 36932115b10SPawel Jakub Dawidek } 370