xref: /titanic_51/usr/src/lib/libc/port/gen/err.c (revision 315e695527b211489a44386ec695c6ccd3af4e6e)
1d362b749Svk199839 /*
2d362b749Svk199839  * CDDL HEADER START
3d362b749Svk199839  *
4d362b749Svk199839  * The contents of this file are subject to the terms of the
5d362b749Svk199839  * Common Development and Distribution License (the "License").
6d362b749Svk199839  * You may not use this file except in compliance with the License.
7d362b749Svk199839  *
8d362b749Svk199839  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d362b749Svk199839  * or http://www.opensolaris.org/os/licensing.
10d362b749Svk199839  * See the License for the specific language governing permissions
11d362b749Svk199839  * and limitations under the License.
12d362b749Svk199839  *
13d362b749Svk199839  * When distributing Covered Code, include this CDDL HEADER in each
14d362b749Svk199839  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d362b749Svk199839  * If applicable, add the following below this CDDL HEADER, with the
16d362b749Svk199839  * fields enclosed by brackets "[]" replaced with your own identifying
17d362b749Svk199839  * information: Portions Copyright [yyyy] [name of copyright owner]
18d362b749Svk199839  *
19d362b749Svk199839  * CDDL HEADER END
20d362b749Svk199839  */
21a574db85Sraf 
22d362b749Svk199839 /*
2323a1cceaSRoger A. Faulkner  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24d362b749Svk199839  */
25d362b749Svk199839 
267257d1b4Sraf #include "lint.h"
27a574db85Sraf #include "file64.h"
28a574db85Sraf #include "mtlib.h"
2923a1cceaSRoger A. Faulkner #include "thr_uberdata.h"
30d362b749Svk199839 #include <sys/types.h>
31d362b749Svk199839 #include <err.h>
32d362b749Svk199839 #include <stdio.h>
33d362b749Svk199839 #include <stdlib.h>
34d362b749Svk199839 #include <stdarg.h>
35d362b749Svk199839 #include <string.h>
36d362b749Svk199839 #include <errno.h>
3723a1cceaSRoger A. Faulkner #include <dlfcn.h>
38a574db85Sraf #include "stdiom.h"
39d362b749Svk199839 
40d362b749Svk199839 /* Function exit/warning functions and global variables. */
41d362b749Svk199839 
4223a1cceaSRoger A. Faulkner const char *__progname;		/* GNU/Linux/BSD compatibility */
4323a1cceaSRoger A. Faulkner 
4423a1cceaSRoger A. Faulkner #define	PROGNAMESIZE	128	/* buffer size for __progname */
4523a1cceaSRoger A. Faulkner 
4623a1cceaSRoger A. Faulkner const char *
4723a1cceaSRoger A. Faulkner getprogname(void)
4823a1cceaSRoger A. Faulkner {
4923a1cceaSRoger A. Faulkner 	return (__progname);
5023a1cceaSRoger A. Faulkner }
5123a1cceaSRoger A. Faulkner 
5223a1cceaSRoger A. Faulkner void
5323a1cceaSRoger A. Faulkner setprogname(const char *argv0)
5423a1cceaSRoger A. Faulkner {
5523a1cceaSRoger A. Faulkner 	uberdata_t *udp = curthread->ul_uberdata;
5623a1cceaSRoger A. Faulkner 	const char *progname;
5723a1cceaSRoger A. Faulkner 
5823a1cceaSRoger A. Faulkner 	if ((progname = strrchr(argv0, '/')) == NULL)
5923a1cceaSRoger A. Faulkner 		progname = argv0;
6023a1cceaSRoger A. Faulkner 	else
6123a1cceaSRoger A. Faulkner 		progname++;
6223a1cceaSRoger A. Faulkner 
6323a1cceaSRoger A. Faulkner 	if (udp->progname == NULL)
6423a1cceaSRoger A. Faulkner 		udp->progname = lmalloc(PROGNAMESIZE);
6523a1cceaSRoger A. Faulkner 	(void) strlcpy(udp->progname, progname, PROGNAMESIZE);
6623a1cceaSRoger A. Faulkner 	__progname = udp->progname;
6723a1cceaSRoger A. Faulkner }
6823a1cceaSRoger A. Faulkner 
6923a1cceaSRoger A. Faulkner /* called only from libc_init() */
7023a1cceaSRoger A. Faulkner void
7123a1cceaSRoger A. Faulkner init_progname(void)
7223a1cceaSRoger A. Faulkner {
7323a1cceaSRoger A. Faulkner 	Dl_argsinfo_t args;
7423a1cceaSRoger A. Faulkner 	const char *argv0;
7523a1cceaSRoger A. Faulkner 
76*315e6955SRoger A. Faulkner 	if (dlinfo(RTLD_SELF, RTLD_DI_ARGSINFO, &args) < 0 ||
77*315e6955SRoger A. Faulkner 	    args.dla_argc <= 0 ||
78*315e6955SRoger A. Faulkner 	    (argv0 = args.dla_argv[0]) == NULL)
7923a1cceaSRoger A. Faulkner 		argv0 = "UNKNOWN";
80*315e6955SRoger A. Faulkner 
8123a1cceaSRoger A. Faulkner 	setprogname(argv0);
8223a1cceaSRoger A. Faulkner }
83d362b749Svk199839 
84d362b749Svk199839 /*
85d362b749Svk199839  * warncore() is the workhorse of these functions.  Everything else has
86d362b749Svk199839  * a warncore() component in it.
87d362b749Svk199839  */
88a574db85Sraf static rmutex_t *
89d362b749Svk199839 warncore(FILE *fp, const char *fmt, va_list args)
90d362b749Svk199839 {
91a574db85Sraf 	rmutex_t *lk;
92f7b942dfSvk199839 
93a574db85Sraf 	FLOCKFILE(lk, fp);
94a574db85Sraf 
9523a1cceaSRoger A. Faulkner 	if (__progname != NULL)
9623a1cceaSRoger A. Faulkner 		(void) fprintf(fp, "%s: ", __progname);
97d362b749Svk199839 
98d362b749Svk199839 	if (fmt != NULL) {
99d362b749Svk199839 		(void) vfprintf(fp, fmt, args);
100d362b749Svk199839 	}
101a574db85Sraf 
102a574db85Sraf 	return (lk);
103d362b749Svk199839 }
104d362b749Svk199839 
105d362b749Svk199839 /* Finish a warning with a newline and a flush of stderr. */
106d362b749Svk199839 static void
107a574db85Sraf warnfinish(FILE *fp, rmutex_t *lk)
108d362b749Svk199839 {
109d362b749Svk199839 	(void) fputc('\n', fp);
110d362b749Svk199839 	(void) fflush(fp);
111a574db85Sraf 	FUNLOCKFILE(lk);
112d362b749Svk199839 }
113d362b749Svk199839 
114d362b749Svk199839 void
115d362b749Svk199839 _vwarnxfp(FILE *fp, const char *fmt, va_list args)
116d362b749Svk199839 {
117a574db85Sraf 	rmutex_t *lk;
118a574db85Sraf 
119a574db85Sraf 	lk = warncore(fp, fmt, args);
120a574db85Sraf 	warnfinish(fp, lk);
121d362b749Svk199839 }
122d362b749Svk199839 
123d362b749Svk199839 void
124d362b749Svk199839 vwarnx(const char *fmt, va_list args)
125d362b749Svk199839 {
126d362b749Svk199839 	_vwarnxfp(stderr, fmt, args);
127d362b749Svk199839 }
128d362b749Svk199839 
129d362b749Svk199839 void
130d362b749Svk199839 _vwarnfp(FILE *fp, const char *fmt, va_list args)
131d362b749Svk199839 {
132d362b749Svk199839 	int tmperr = errno;	/* Capture errno now. */
133a574db85Sraf 	rmutex_t *lk;
134d362b749Svk199839 
135a574db85Sraf 	lk = warncore(fp, fmt, args);
136d362b749Svk199839 	if (fmt != NULL) {
137d362b749Svk199839 		(void) fputc(':', fp);
138d362b749Svk199839 		(void) fputc(' ', fp);
139d362b749Svk199839 	}
140d362b749Svk199839 	(void) fputs(strerror(tmperr), fp);
141a574db85Sraf 	warnfinish(fp, lk);
142d362b749Svk199839 }
143d362b749Svk199839 
144d362b749Svk199839 void
145d362b749Svk199839 vwarn(const char *fmt, va_list args)
146d362b749Svk199839 {
147d362b749Svk199839 	_vwarnfp(stderr, fmt, args);
148d362b749Svk199839 }
149d362b749Svk199839 
150d362b749Svk199839 /* PRINTFLIKE1 */
151d362b749Svk199839 void
152d362b749Svk199839 warnx(const char *fmt, ...)
153d362b749Svk199839 {
154d362b749Svk199839 	va_list args;
155d362b749Svk199839 
156d362b749Svk199839 	va_start(args, fmt);
157d362b749Svk199839 	vwarnx(fmt, args);
158d362b749Svk199839 	va_end(args);
159d362b749Svk199839 }
160d362b749Svk199839 
161d362b749Svk199839 void
162d362b749Svk199839 _warnfp(FILE *fp, const char *fmt, ...)
163d362b749Svk199839 {
164d362b749Svk199839 	va_list args;
165d362b749Svk199839 
166d362b749Svk199839 	va_start(args, fmt);
167d362b749Svk199839 	_vwarnfp(fp, fmt, args);
168d362b749Svk199839 	va_end(args);
169d362b749Svk199839 }
170d362b749Svk199839 
171d362b749Svk199839 void
172d362b749Svk199839 _warnxfp(FILE *fp, const char *fmt, ...)
173d362b749Svk199839 {
174d362b749Svk199839 	va_list args;
175d362b749Svk199839 
176d362b749Svk199839 	va_start(args, fmt);
177d362b749Svk199839 	_vwarnxfp(fp, fmt, args);
178d362b749Svk199839 	va_end(args);
179d362b749Svk199839 }
180d362b749Svk199839 
181d362b749Svk199839 /* PRINTFLIKE1 */
182d362b749Svk199839 void
183d362b749Svk199839 warn(const char *fmt, ...)
184d362b749Svk199839 {
185d362b749Svk199839 	va_list args;
186d362b749Svk199839 
187d362b749Svk199839 	va_start(args, fmt);
188d362b749Svk199839 	vwarn(fmt, args);
189d362b749Svk199839 	va_end(args);
190d362b749Svk199839 }
191d362b749Svk199839 
192d362b749Svk199839 /* PRINTFLIKE2 */
193d362b749Svk199839 void
194d362b749Svk199839 err(int status, const char *fmt, ...)
195d362b749Svk199839 {
196d362b749Svk199839 	va_list args;
197d362b749Svk199839 
198d362b749Svk199839 	va_start(args, fmt);
199d362b749Svk199839 	vwarn(fmt, args);
200d362b749Svk199839 	va_end(args);
201d362b749Svk199839 	exit(status);
202d362b749Svk199839 }
203d362b749Svk199839 
204d362b749Svk199839 void
205d362b749Svk199839 _errfp(FILE *fp, int status, const char *fmt, ...)
206d362b749Svk199839 {
207d362b749Svk199839 	va_list args;
208d362b749Svk199839 
209d362b749Svk199839 	va_start(args, fmt);
210d362b749Svk199839 	_vwarnfp(fp, fmt, args);
211d362b749Svk199839 	va_end(args);
212d362b749Svk199839 	exit(status);
213d362b749Svk199839 }
214d362b749Svk199839 
215d362b749Svk199839 void
216d362b749Svk199839 verr(int status, const char *fmt, va_list args)
217d362b749Svk199839 {
218d362b749Svk199839 	vwarn(fmt, args);
219d362b749Svk199839 	exit(status);
220d362b749Svk199839 }
221d362b749Svk199839 
222d362b749Svk199839 void
223d362b749Svk199839 _verrfp(FILE *fp, int status, const char *fmt, va_list args)
224d362b749Svk199839 {
225d362b749Svk199839 	_vwarnfp(fp, fmt, args);
226d362b749Svk199839 	exit(status);
227d362b749Svk199839 }
228d362b749Svk199839 
229d362b749Svk199839 /* PRINTFLIKE2 */
230d362b749Svk199839 void
231d362b749Svk199839 errx(int status, const char *fmt, ...)
232d362b749Svk199839 {
233d362b749Svk199839 	va_list args;
234d362b749Svk199839 
235d362b749Svk199839 	va_start(args, fmt);
236d362b749Svk199839 	vwarnx(fmt, args);
237d362b749Svk199839 	va_end(args);
238d362b749Svk199839 	exit(status);
239d362b749Svk199839 }
240d362b749Svk199839 
241d362b749Svk199839 void
242d362b749Svk199839 _errxfp(FILE *fp, int status, const char *fmt, ...)
243d362b749Svk199839 {
244d362b749Svk199839 	va_list args;
245d362b749Svk199839 
246d362b749Svk199839 	va_start(args, fmt);
247d362b749Svk199839 	_vwarnxfp(fp, fmt, args);
248d362b749Svk199839 	va_end(args);
249d362b749Svk199839 	exit(status);
250d362b749Svk199839 }
251d362b749Svk199839 
252d362b749Svk199839 void
253d362b749Svk199839 verrx(int status, const char *fmt, va_list args)
254d362b749Svk199839 {
255d362b749Svk199839 	vwarnx(fmt, args);
256d362b749Svk199839 	exit(status);
257d362b749Svk199839 }
258d362b749Svk199839 
259d362b749Svk199839 void
260d362b749Svk199839 _verrxfp(FILE *fp, int status, const char *fmt, va_list args)
261d362b749Svk199839 {
262d362b749Svk199839 	_vwarnxfp(fp, fmt, args);
263d362b749Svk199839 	exit(status);
264d362b749Svk199839 }
265