-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy patherr.c
157 lines (133 loc) · 3.36 KB
/
err.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/* Copyright © 2021 Arista Networks, Inc. All rights reserved.
*
* Use of this source code is governed by the MIT license that can be found
* in the LICENSE file.
*/
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdnoreturn.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include "errutil.h"
/* The err(3) function family is generally not prepared to deal with error
handling after the tty has been changed to raw mode. They do not call
atexit handlers and the line endings are not configurable.
To address this, we reimplement most of these functions here, so that
they still behave correctly in our use-cases. */
void (*err_exit)(int) = exit;
const char *err_line_ending = "\n";
int err_flags = 0;
/* Parse the BST_VERBOSITY environment variable to determine the requested
verbosity. Higher numbers are associated with more verbosity, with 9
being the most verbose and 0 being the least verbose. The default
verbosity level is 1. */
static int parsedverbosity(void)
{
char *pszVerbosity = getenv("BST_VERBOSITY");
if (pszVerbosity == NULL) {
return 1;
}
char *endPtr;
int iVerbosity = strtol(pszVerbosity, &endPtr, 10);
if (*endPtr != '\0') {
err(2, "un-parsable value of BST_VERBOSITY\n");
}
return iVerbosity;
}
void init_logverbosity(void)
{
int iVerbosity = parsedverbosity();
if (iVerbosity >= 1) {
err_flags |= ERR_VERBOSE;
}
}
/* fdprintf and vfdprintf are fork-safe versions of fprintf and vfprintf. */
static void vfdprintf(int fd, const char *fmt, va_list vl)
{
char buf[BUFSIZ];
int written = vsnprintf(buf, sizeof (buf), fmt, vl);
buf[sizeof (buf) - 1] = '\0';
if ((size_t) written >= sizeof (buf)) {
written = sizeof (buf);
}
write(fd, buf, (size_t) written);
}
static void fdprintf(int fd, const char *fmt, ...)
{
va_list vl;
va_start(vl, fmt);
vfdprintf(fd, fmt, vl);
va_end(vl);
}
extern const char *__progname;
static void vwarnsyslog(int errcode, const char *fmt, va_list vl)
{
static const char suffix[] = ": %m";
char newfmt[BUFSIZ];
char *tail = stpncpy(newfmt, fmt, sizeof (newfmt) - sizeof (suffix));
if (errcode != 0) {
stpncpy(tail, suffix, sizeof (suffix));
}
vsyslog(LOG_ERR, fmt, vl);
}
static void vwarn(const char *fmt, va_list vl)
{
if (err_flags & ERR_USE_SYSLOG) {
vwarnsyslog(errno, fmt, vl);
return;
}
fdprintf(STDERR_FILENO, "%s: ", __progname);
vfdprintf(STDERR_FILENO, fmt, vl);
fdprintf(STDERR_FILENO, ": %s%s", strerror(errno), err_line_ending);
}
static void vwarnx(const char *fmt, va_list vl)
{
if (err_flags & ERR_USE_SYSLOG) {
vwarnsyslog(0, fmt, vl);
return;
}
fdprintf(STDERR_FILENO, "%s: ", __progname);
vfdprintf(STDERR_FILENO, fmt, vl);
write(STDERR_FILENO, err_line_ending, strlen(err_line_ending));
}
void warn(const char *fmt, ...)
{
if (!(err_flags & ERR_VERBOSE)) {
return;
}
va_list vl;
va_start(vl, fmt);
vwarn(fmt, vl);
va_end(vl);
}
void warnx(const char *fmt, ...)
{
if (!(err_flags & ERR_VERBOSE)) {
return;
}
va_list vl;
va_start(vl, fmt);
vwarnx(fmt, vl);
va_end(vl);
}
noreturn void err(int eval, const char *fmt, ...)
{
va_list vl;
va_start(vl, fmt);
vwarn(fmt, vl);
va_end(vl);
err_exit(eval);
__builtin_unreachable();
}
noreturn void errx(int eval, const char *fmt, ...)
{
va_list vl;
va_start(vl, fmt);
vwarnx(fmt, vl);
va_end(vl);
err_exit(eval);
__builtin_unreachable();
}