1290001Sglebius/*
2290001Sglebius * Copyright (C) 2004, 2005, 2007, 2009  Internet Systems Consortium, Inc. ("ISC")
3290001Sglebius * Copyright (C) 2001  Internet Software Consortium.
4290001Sglebius *
5290001Sglebius * Permission to use, copy, modify, and/or distribute this software for any
6290001Sglebius * purpose with or without fee is hereby granted, provided that the above
7290001Sglebius * copyright notice and this permission notice appear in all copies.
8290001Sglebius *
9290001Sglebius * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10290001Sglebius * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11290001Sglebius * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12290001Sglebius * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13290001Sglebius * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14290001Sglebius * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15290001Sglebius * PERFORMANCE OF THIS SOFTWARE.
16290001Sglebius */
17290001Sglebius
18290001Sglebius/* $Id: strerror.c,v 1.10 2009/02/16 23:48:04 tbox Exp $ */
19290001Sglebius
20290001Sglebius/*! \file */
21290001Sglebius
22290001Sglebius#include <config.h>
23290001Sglebius
24290001Sglebius#include <stdio.h>
25290001Sglebius#include <string.h>
26290001Sglebius
27290001Sglebius#include <isc/mutex.h>
28290001Sglebius#include <isc/once.h>
29290001Sglebius#include <isc/print.h>
30290001Sglebius#include <isc/strerror.h>
31290001Sglebius#include <isc/util.h>
32290001Sglebius
33290001Sglebius#include "l_stdlib.h"		/* NTP local change */
34290001Sglebius
35290001Sglebius#ifdef HAVE_STRERROR
36290001Sglebius/*%
37290001Sglebius * We need to do this this way for profiled locks.
38290001Sglebius */
39290001Sglebiusstatic isc_mutex_t isc_strerror_lock;
40290001Sglebiusstatic void init_lock(void) {
41290001Sglebius	RUNTIME_CHECK(isc_mutex_init(&isc_strerror_lock) == ISC_R_SUCCESS);
42290001Sglebius}
43290001Sglebius#else
44290001Sglebiusextern const char * const sys_errlist[];
45290001Sglebiusextern const int sys_nerr;
46290001Sglebius#endif
47290001Sglebius
48290001Sglebiusvoid
49290001Sglebiusisc__strerror(int num, char *buf, size_t size) {
50290001Sglebius#ifdef HAVE_STRERROR
51290001Sglebius	char *msg;
52290001Sglebius	unsigned int unum = (unsigned int)num;
53290001Sglebius	static isc_once_t once = ISC_ONCE_INIT;
54290001Sglebius
55290001Sglebius	REQUIRE(buf != NULL);
56290001Sglebius
57290001Sglebius	RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS);
58290001Sglebius
59290001Sglebius	LOCK(&isc_strerror_lock);
60290001Sglebius	msg = strerror(num);
61290001Sglebius	if (msg != NULL)
62290001Sglebius		snprintf(buf, size, "%s", msg);
63290001Sglebius	else
64290001Sglebius		snprintf(buf, size, "Unknown error: %u", unum);
65290001Sglebius	UNLOCK(&isc_strerror_lock);
66290001Sglebius#else
67290001Sglebius	unsigned int unum = (unsigned int)num;
68290001Sglebius
69290001Sglebius	REQUIRE(buf != NULL);
70290001Sglebius
71290001Sglebius	if (num >= 0 && num < sys_nerr)
72290001Sglebius		snprintf(buf, size, "%s", sys_errlist[num]);
73290001Sglebius	else
74290001Sglebius		snprintf(buf, size, "Unknown error: %u", unum);
75290001Sglebius#endif
76290001Sglebius}
77