#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)assert.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: assert.c,v 1.18 2017/05/15 16:09:09 christos Exp $");
#endif
#endif
#include "namespace.h"
#include <sys/types.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include "extern.h"
static int
fmtassert(char *buf, size_t len, const char *file, int line,
const char *function, const char *failedexpr)
{
return snprintf_ss(buf, len,
"assertion \"%s\" failed: file \"%s\", line %d%s%s%s\n",
failedexpr, file, line,
function ? ", function \"" : "",
function ? function : "",
function ? "\"" : "");
}
void
__assert13(const char *file, int line, const char *function,
const char *failedexpr)
{
char buf[1024];
int l = fmtassert(buf, sizeof(buf), file, line, function, failedexpr);
if (l < 0)
abort();
(void)write(STDERR_FILENO, buf, (size_t)l);
abort();
}
void
__assert(const char *file, int line, const char *failedexpr)
{
__assert13(file, line, NULL, failedexpr);
}
enum {
DIAGASSERT_ABORT = 1<<0,
DIAGASSERT_STDERR = 1<<1,
DIAGASSERT_SYSLOG = 1<<2
};
static int diagassert_flags = -1;
void
__diagassert13(const char *file, int line, const char *function,
const char *failedexpr)
{
char buf[1024];
if (diagassert_flags == -1) {
char *p;
diagassert_flags = DIAGASSERT_SYSLOG;
for (p = getenv("LIBC_DIAGASSERT"); p && *p; p++) {
switch (*p) {
case 'a':
diagassert_flags |= DIAGASSERT_ABORT;
break;
case 'A':
diagassert_flags &= ~DIAGASSERT_ABORT;
break;
case 'e':
diagassert_flags |= DIAGASSERT_STDERR;
break;
case 'E':
diagassert_flags &= ~DIAGASSERT_STDERR;
break;
case 'l':
diagassert_flags |= DIAGASSERT_SYSLOG;
break;
case 'L':
diagassert_flags &= ~DIAGASSERT_SYSLOG;
break;
}
}
}
fmtassert(buf, sizeof(buf), file, line, function, failedexpr);
if (diagassert_flags & DIAGASSERT_STDERR) {
char ebuf[1024];
int l = snprintf_ss(ebuf, sizeof(ebuf), "%s: %s\n",
getprogname(), buf);
if (l == -1)
abort();
(void)write(STDERR_FILENO, ebuf, (size_t)l);
}
if (diagassert_flags & DIAGASSERT_SYSLOG) {
struct syslog_data sdata = SYSLOG_DATA_INIT;
syslog_ss(LOG_DEBUG | LOG_USER, &sdata, "%s", buf);
}
if (diagassert_flags & DIAGASSERT_ABORT)
abort();
}
void
__diagassert(const char *file, int line, const char *failedexpr)
{
__diagassert13(file, line, NULL, failedexpr);
}