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