1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __SCCSID("@(#)err.c 8.1 (Berkeley) 6/4/93");
34 #include "namespace.h"
35 #include <err.h>
36 #include <errno.h>
37 #include <stdarg.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include "un-namespace.h"
42
43 #include "libc_private.h"
44
45 static FILE *err_file; /* file to use for error output */
46 static void (*err_exit)(int);
47
48 /*
49 * This is declared to take a `void *' so that the caller is not required
50 * to include <stdio.h> first. However, it is really a `FILE *', and the
51 * manual page documents it as such.
52 */
53 void
err_set_file(void * fp)54 err_set_file(void *fp)
55 {
56 if (fp)
57 err_file = fp;
58 else
59 err_file = stderr;
60 }
61
62 void
err_set_exit(void (* ef)(int))63 err_set_exit(void (*ef)(int))
64 {
65 err_exit = ef;
66 }
67
68 __weak_reference(_err, err);
69
70 void
_err(int eval,const char * fmt,...)71 _err(int eval, const char *fmt, ...)
72 {
73 va_list ap;
74 va_start(ap, fmt);
75 verrc(eval, errno, fmt, ap);
76 va_end(ap);
77 }
78
79 void
verr(int eval,const char * fmt,va_list ap)80 verr(int eval, const char *fmt, va_list ap)
81 {
82 verrc(eval, errno, fmt, ap);
83 }
84
85 void
errc(int eval,int code,const char * fmt,...)86 errc(int eval, int code, const char *fmt, ...)
87 {
88 va_list ap;
89 va_start(ap, fmt);
90 verrc(eval, code, fmt, ap);
91 va_end(ap);
92 }
93
94 void
verrc(int eval,int code,const char * fmt,va_list ap)95 verrc(int eval, int code, const char *fmt, va_list ap)
96 {
97 if (err_file == NULL)
98 err_set_file(NULL);
99 fprintf(err_file, "%s: ", _getprogname());
100 if (fmt != NULL) {
101 vfprintf(err_file, fmt, ap);
102 fprintf(err_file, ": ");
103 }
104 fprintf(err_file, "%s\n", strerror(code));
105 if (err_exit)
106 err_exit(eval);
107 exit(eval);
108 }
109
110 void
errx(int eval,const char * fmt,...)111 errx(int eval, const char *fmt, ...)
112 {
113 va_list ap;
114 va_start(ap, fmt);
115 verrx(eval, fmt, ap);
116 va_end(ap);
117 }
118
119 void
verrx(int eval,const char * fmt,va_list ap)120 verrx(int eval, const char *fmt, va_list ap)
121 {
122 if (err_file == NULL)
123 err_set_file(NULL);
124 fprintf(err_file, "%s: ", _getprogname());
125 if (fmt != NULL)
126 vfprintf(err_file, fmt, ap);
127 fprintf(err_file, "\n");
128 if (err_exit)
129 err_exit(eval);
130 exit(eval);
131 }
132
133 __weak_reference(_warn, warn);
134
135 void
_warn(const char * fmt,...)136 _warn(const char *fmt, ...)
137 {
138 va_list ap;
139 va_start(ap, fmt);
140 vwarnc(errno, fmt, ap);
141 va_end(ap);
142 }
143
144 void
vwarn(const char * fmt,va_list ap)145 vwarn(const char *fmt, va_list ap)
146 {
147 vwarnc(errno, fmt, ap);
148 }
149
150 void
warnc(int code,const char * fmt,...)151 warnc(int code, const char *fmt, ...)
152 {
153 va_list ap;
154 va_start(ap, fmt);
155 vwarnc(code, fmt, ap);
156 va_end(ap);
157 }
158
159 void
vwarnc(int code,const char * fmt,va_list ap)160 vwarnc(int code, const char *fmt, va_list ap)
161 {
162 int saved_errno;
163
164 saved_errno = errno;
165 if (err_file == NULL)
166 err_set_file(NULL);
167 fprintf(err_file, "%s: ", _getprogname());
168 if (fmt != NULL) {
169 vfprintf(err_file, fmt, ap);
170 fprintf(err_file, ": ");
171 }
172 fprintf(err_file, "%s\n", strerror(code));
173 errno = saved_errno;
174 }
175
176 void
warnx(const char * fmt,...)177 warnx(const char *fmt, ...)
178 {
179 va_list ap;
180 va_start(ap, fmt);
181 vwarnx(fmt, ap);
182 va_end(ap);
183 }
184
185 void
vwarnx(const char * fmt,va_list ap)186 vwarnx(const char *fmt, va_list ap)
187 {
188 int saved_errno;
189
190 saved_errno = errno;
191 if (err_file == NULL)
192 err_set_file(NULL);
193 fprintf(err_file, "%s: ", _getprogname());
194 if (fmt != NULL)
195 vfprintf(err_file, fmt, ap);
196 fprintf(err_file, "\n");
197 errno = saved_errno;
198 }
199