GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libc/string/strerror_r.c Lines: 8 39 20.5 %
Date: 2017-11-07 Branches: 4 22 18.2 %

Line Branch Exec Source
1
/* $OpenBSD: strerror_r.c,v 1.13 2016/10/19 16:26:16 bluhm Exp $ */
2
/* Public Domain <marc@snafu.org> */
3
4
#include <errno.h>
5
#include <limits.h>
6
#include <signal.h>
7
#include <string.h>
8
9
static size_t
10
__digits10(unsigned int num)
11
{
12
	size_t i = 0;
13
14
	do {
15
		num /= 10;
16
		i++;
17
	} while (num != 0);
18
19
	return i;
20
}
21
22
static int
23
__itoa(int num, int sign, char *buffer, size_t start, size_t end)
24
{
25
	size_t pos;
26
	unsigned int a;
27
	int neg;
28
29
	if (sign && num < 0) {
30
		a = -num;
31
		neg = 1;
32
	}
33
	else {
34
		a = num;
35
		neg = 0;
36
	}
37
38
	pos = start + __digits10(a);
39
	if (neg)
40
	    pos++;
41
42
	if (pos < end)
43
		buffer[pos] = '\0';
44
	else
45
		return ERANGE;
46
	pos--;
47
	do {
48
		buffer[pos] = (a % 10) + '0';
49
		pos--;
50
		a /= 10;
51
	} while (a != 0);
52
	if (neg)
53
		buffer[pos] = '-';
54
	return 0;
55
}
56
57
58
static int
59
__num2string(int num, int sign, int setid, char *buf, size_t buflen,
60
    const char * const list[], size_t max, const char *def)
61
{
62
	int ret = 0;
63
	size_t len;
64
65

2516172
	if (0 <= num && num < max) {
66
838724
		len = strlcpy(buf, list[num], buflen);
67
838724
		if (len >= buflen)
68
			ret = ERANGE;
69
	} else {
70
		len = strlcpy(buf, def, buflen);
71
		if (len >= buflen)
72
			ret = ERANGE;
73
		else {
74
			ret = __itoa(num, sign, buf, len, buflen);
75
			if (ret == 0)
76
				ret = EINVAL;
77
		}
78
	}
79
80
838724
	return ret;
81
}
82
83
#define	UPREFIX	"Unknown error: "
84
85
int
86
strerror_r(int errnum, char *strerrbuf, size_t buflen)
87
{
88
	int ret_errno;
89
90
838724
	ret_errno = __num2string(errnum, 1, 1, strerrbuf, buflen,
91
1677448
	    sys_errlist, sys_nerr, UPREFIX);
92
93
838724
	if (ret_errno)
94
		errno = ret_errno;
95
838724
	return (ret_errno);
96
}
97
DEF_WEAK(strerror_r);
98
99
#define USIGPREFIX "Unknown signal: "
100
101
char *
102
__strsignal(int num, char *buf)
103
{
104
	__num2string(num, 0, 2, buf, NL_TEXTMAX, sys_siglist, NSIG,
105
	    USIGPREFIX);
106
	return buf;
107
}