xref: /illumos-gate/usr/src/lib/libc/port/gen/err.c (revision 6a634c9d)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5e3320f40Smarkfen  * Common Development and Distribution License (the "License").
6e3320f40Smarkfen  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
2323a1cceaSRoger A. Faulkner  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
267257d1b4Sraf #include "lint.h"
27a574db85Sraf #include "file64.h"
28a574db85Sraf #include "mtlib.h"
2923a1cceaSRoger A. Faulkner #include "thr_uberdata.h"
30d362b749Svk #include <sys/types.h>
31d362b749Svk #include <err.h>
327c478bd9Sstevel@tonic-gate #include <stdio.h>
337c478bd9Sstevel@tonic-gate #include <stdlib.h>
347c478bd9Sstevel@tonic-gate #include <stdarg.h>
357c478bd9Sstevel@tonic-gate #include <string.h>
367c478bd9Sstevel@tonic-gate #include <errno.h>
3723a1cceaSRoger A. Faulkner #include <dlfcn.h>
38a574db85Sraf #include "stdiom.h"
407c478bd9Sstevel@tonic-gate /* Function exit/warning functions and global variables. */
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 *
getprogname(void)4723a1cceaSRoger A. Faulkner getprogname(void)
4823a1cceaSRoger A. Faulkner {
4923a1cceaSRoger A. Faulkner 	return (__progname);
5023a1cceaSRoger A. Faulkner }
5123a1cceaSRoger A. Faulkner 
5223a1cceaSRoger A. Faulkner void
setprogname(const char * argv0)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
init_progname(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 }
847c478bd9Sstevel@tonic-gate /*
857c478bd9Sstevel@tonic-gate  * warncore() is the workhorse of these functions.  Everything else has
867c478bd9Sstevel@tonic-gate  * a warncore() component in it.
877c478bd9Sstevel@tonic-gate  */
88a574db85Sraf static rmutex_t *
warncore(FILE * fp,const char * fmt,va_list args)89e3320f40Smarkfen warncore(FILE *fp, const char *fmt, va_list args)
907c478bd9Sstevel@tonic-gate {
91a574db85Sraf 	rmutex_t *lk;
93a574db85Sraf 	FLOCKFILE(lk, fp);
9523a1cceaSRoger A. Faulkner 	if (__progname != NULL)
9623a1cceaSRoger A. Faulkner 		(void) fprintf(fp, "%s: ", __progname);
987c478bd9Sstevel@tonic-gate 	if (fmt != NULL) {
99e3320f40Smarkfen 		(void) vfprintf(fp, fmt, args);
1007c478bd9Sstevel@tonic-gate 	}
102a574db85Sraf 	return (lk);
1037c478bd9Sstevel@tonic-gate }
1057c478bd9Sstevel@tonic-gate /* Finish a warning with a newline and a flush of stderr. */
1067c478bd9Sstevel@tonic-gate static void
warnfinish(FILE * fp,rmutex_t * lk)107a574db85Sraf warnfinish(FILE *fp, rmutex_t *lk)
1087c478bd9Sstevel@tonic-gate {
109e3320f40Smarkfen 	(void) fputc('\n', fp);
110e3320f40Smarkfen 	(void) fflush(fp);
111a574db85Sraf 	FUNLOCKFILE(lk);
1127c478bd9Sstevel@tonic-gate }
1147c478bd9Sstevel@tonic-gate void
_vwarnxfp(FILE * fp,const char * fmt,va_list args)115d362b749Svk _vwarnxfp(FILE *fp, const char *fmt, va_list args)
1167c478bd9Sstevel@tonic-gate {
117a574db85Sraf 	rmutex_t *lk;
119a574db85Sraf 	lk = warncore(fp, fmt, args);
120a574db85Sraf 	warnfinish(fp, lk);
1217c478bd9Sstevel@tonic-gate }
1237c478bd9Sstevel@tonic-gate void
vwarnx(const char * fmt,va_list args)124d362b749Svk vwarnx(const char *fmt, va_list args)
125d362b749Svk {
126d362b749Svk 	_vwarnxfp(stderr, fmt, args);
127d362b749Svk }
129d362b749Svk void
_vwarnfp(FILE * fp,const char * fmt,va_list args)130d362b749Svk _vwarnfp(FILE *fp, const char *fmt, va_list args)
1317c478bd9Sstevel@tonic-gate {
1327c478bd9Sstevel@tonic-gate 	int tmperr = errno;	/* Capture errno now. */
133a574db85Sraf 	rmutex_t *lk;
135a574db85Sraf 	lk = warncore(fp, fmt, args);
136d362b749Svk 	if (fmt != NULL) {
137d362b749Svk 		(void) fputc(':', fp);
138d362b749Svk 		(void) fputc(' ', fp);
139d362b749Svk 	}
140e3320f40Smarkfen 	(void) fputs(strerror(tmperr), fp);
141a574db85Sraf 	warnfinish(fp, lk);
142e3320f40Smarkfen }
144e3320f40Smarkfen void
vwarn(const char * fmt,va_list args)145e3320f40Smarkfen vwarn(const char *fmt, va_list args)
146e3320f40Smarkfen {
147d362b749Svk 	_vwarnfp(stderr, fmt, args);
1487c478bd9Sstevel@tonic-gate }
1507c478bd9Sstevel@tonic-gate /* PRINTFLIKE1 */
1517c478bd9Sstevel@tonic-gate void
warnx(const char * fmt,...)1527c478bd9Sstevel@tonic-gate warnx(const char *fmt, ...)
1537c478bd9Sstevel@tonic-gate {
1547c478bd9Sstevel@tonic-gate 	va_list args;
1567c478bd9Sstevel@tonic-gate 	va_start(args, fmt);
1577c478bd9Sstevel@tonic-gate 	vwarnx(fmt, args);
1587c478bd9Sstevel@tonic-gate 	va_end(args);
1597c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate void
_warnfp(FILE * fp,const char * fmt,...)162d362b749Svk _warnfp(FILE *fp, const char *fmt, ...)
1637c478bd9Sstevel@tonic-gate {
1647c478bd9Sstevel@tonic-gate 	va_list args;
1667c478bd9Sstevel@tonic-gate 	va_start(args, fmt);
167d362b749Svk 	_vwarnfp(fp, fmt, args);
1687c478bd9Sstevel@tonic-gate 	va_end(args);
1697c478bd9Sstevel@tonic-gate }
171e3320f40Smarkfen void
_warnxfp(FILE * fp,const char * fmt,...)172d362b749Svk _warnxfp(FILE *fp, const char *fmt, ...)
173e3320f40Smarkfen {
174e3320f40Smarkfen 	va_list args;
176e3320f40Smarkfen 	va_start(args, fmt);
177d362b749Svk 	_vwarnxfp(fp, fmt, args);
178e3320f40Smarkfen 	va_end(args);
179e3320f40Smarkfen }
181d362b749Svk /* PRINTFLIKE1 */
182e3320f40Smarkfen void
warn(const char * fmt,...)183d362b749Svk warn(const char *fmt, ...)
184e3320f40Smarkfen {
185e3320f40Smarkfen 	va_list args;
187e3320f40Smarkfen 	va_start(args, fmt);
188d362b749Svk 	vwarn(fmt, args);
189e3320f40Smarkfen 	va_end(args);
190e3320f40Smarkfen }
1927c478bd9Sstevel@tonic-gate /* PRINTFLIKE2 */
1937c478bd9Sstevel@tonic-gate void
err(int status,const char * fmt,...)1947c478bd9Sstevel@tonic-gate err(int status, const char *fmt, ...)
1957c478bd9Sstevel@tonic-gate {
1967c478bd9Sstevel@tonic-gate 	va_list args;
1987c478bd9Sstevel@tonic-gate 	va_start(args, fmt);
1997c478bd9Sstevel@tonic-gate 	vwarn(fmt, args);
2007c478bd9Sstevel@tonic-gate 	va_end(args);
2017c478bd9Sstevel@tonic-gate 	exit(status);
2027c478bd9Sstevel@tonic-gate }
204d362b749Svk void
_errfp(FILE * fp,int status,const char * fmt,...)205d362b749Svk _errfp(FILE *fp, int status, const char *fmt, ...)
206d362b749Svk {
207d362b749Svk 	va_list args;
209d362b749Svk 	va_start(args, fmt);
210d362b749Svk 	_vwarnfp(fp, fmt, args);
211d362b749Svk 	va_end(args);
212d362b749Svk 	exit(status);
213d362b749Svk }
2157c478bd9Sstevel@tonic-gate void
verr(int status,const char * fmt,va_list args)2167c478bd9Sstevel@tonic-gate verr(int status, const char *fmt, va_list args)
2177c478bd9Sstevel@tonic-gate {
2187c478bd9Sstevel@tonic-gate 	vwarn(fmt, args);
2197c478bd9Sstevel@tonic-gate 	exit(status);
2207c478bd9Sstevel@tonic-gate }
222d362b749Svk void
_verrfp(FILE * fp,int status,const char * fmt,va_list args)223d362b749Svk _verrfp(FILE *fp, int status, const char *fmt, va_list args)
224d362b749Svk {
225d362b749Svk 	_vwarnfp(fp, fmt, args);
226d362b749Svk 	exit(status);
227d362b749Svk }
2297c478bd9Sstevel@tonic-gate /* PRINTFLIKE2 */
2307c478bd9Sstevel@tonic-gate void
errx(int status,const char * fmt,...)2317c478bd9Sstevel@tonic-gate errx(int status, const char *fmt, ...)
2327c478bd9Sstevel@tonic-gate {
2337c478bd9Sstevel@tonic-gate 	va_list args;
2357c478bd9Sstevel@tonic-gate 	va_start(args, fmt);
2367c478bd9Sstevel@tonic-gate 	vwarnx(fmt, args);
2377c478bd9Sstevel@tonic-gate 	va_end(args);
2387c478bd9Sstevel@tonic-gate 	exit(status);
2397c478bd9Sstevel@tonic-gate }
241d362b749Svk void
_errxfp(FILE * fp,int status,const char * fmt,...)242d362b749Svk _errxfp(FILE *fp, int status, const char *fmt, ...)
243d362b749Svk {
244d362b749Svk 	va_list args;
246d362b749Svk 	va_start(args, fmt);
247d362b749Svk 	_vwarnxfp(fp, fmt, args);
248d362b749Svk 	va_end(args);
249d362b749Svk 	exit(status);
250d362b749Svk }
2527c478bd9Sstevel@tonic-gate void
verrx(int status,const char * fmt,va_list args)2537c478bd9Sstevel@tonic-gate verrx(int status, const char *fmt, va_list args)
2547c478bd9Sstevel@tonic-gate {
2557c478bd9Sstevel@tonic-gate 	vwarnx(fmt, args);
2567c478bd9Sstevel@tonic-gate 	exit(status);
2577c478bd9Sstevel@tonic-gate }
259d362b749Svk void
_verrxfp(FILE * fp,int status,const char * fmt,va_list args)260d362b749Svk _verrxfp(FILE *fp, int status, const char *fmt, va_list args)
261d362b749Svk {
262d362b749Svk 	_vwarnxfp(fp, fmt, args);
263d362b749Svk 	exit(status);
264d362b749Svk }