xref: /onnv-gate/usr/src/lib/libc/port/gen/err.c (revision 13133:83213fd85699)
14891Svk199839 /*
24891Svk199839  * CDDL HEADER START
34891Svk199839  *
44891Svk199839  * The contents of this file are subject to the terms of the
54891Svk199839  * Common Development and Distribution License (the "License").
64891Svk199839  * You may not use this file except in compliance with the License.
74891Svk199839  *
84891Svk199839  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94891Svk199839  * or http://www.opensolaris.org/os/licensing.
104891Svk199839  * See the License for the specific language governing permissions
114891Svk199839  * and limitations under the License.
124891Svk199839  *
134891Svk199839  * When distributing Covered Code, include this CDDL HEADER in each
144891Svk199839  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154891Svk199839  * If applicable, add the following below this CDDL HEADER, with the
164891Svk199839  * fields enclosed by brackets "[]" replaced with your own identifying
174891Svk199839  * information: Portions Copyright [yyyy] [name of copyright owner]
184891Svk199839  *
194891Svk199839  * CDDL HEADER END
204891Svk199839  */
215891Sraf 
224891Svk199839 /*
2313093SRoger.Faulkner@Oracle.COM  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
244891Svk199839  */
254891Svk199839 
266812Sraf #include "lint.h"
275891Sraf #include "file64.h"
285891Sraf #include "mtlib.h"
2913093SRoger.Faulkner@Oracle.COM #include "thr_uberdata.h"
304891Svk199839 #include <sys/types.h>
314891Svk199839 #include <err.h>
324891Svk199839 #include <stdio.h>
334891Svk199839 #include <stdlib.h>
344891Svk199839 #include <stdarg.h>
354891Svk199839 #include <string.h>
364891Svk199839 #include <errno.h>
3713093SRoger.Faulkner@Oracle.COM #include <dlfcn.h>
385891Sraf #include "stdiom.h"
394891Svk199839 
404891Svk199839 /* Function exit/warning functions and global variables. */
414891Svk199839 
4213093SRoger.Faulkner@Oracle.COM const char *__progname;		/* GNU/Linux/BSD compatibility */
4313093SRoger.Faulkner@Oracle.COM 
4413093SRoger.Faulkner@Oracle.COM #define	PROGNAMESIZE	128	/* buffer size for __progname */
4513093SRoger.Faulkner@Oracle.COM 
4613093SRoger.Faulkner@Oracle.COM const char *
getprogname(void)4713093SRoger.Faulkner@Oracle.COM getprogname(void)
4813093SRoger.Faulkner@Oracle.COM {
4913093SRoger.Faulkner@Oracle.COM 	return (__progname);
5013093SRoger.Faulkner@Oracle.COM }
5113093SRoger.Faulkner@Oracle.COM 
5213093SRoger.Faulkner@Oracle.COM void
setprogname(const char * argv0)5313093SRoger.Faulkner@Oracle.COM setprogname(const char *argv0)
5413093SRoger.Faulkner@Oracle.COM {
5513093SRoger.Faulkner@Oracle.COM 	uberdata_t *udp = curthread->ul_uberdata;
5613093SRoger.Faulkner@Oracle.COM 	const char *progname;
5713093SRoger.Faulkner@Oracle.COM 
5813093SRoger.Faulkner@Oracle.COM 	if ((progname = strrchr(argv0, '/')) == NULL)
5913093SRoger.Faulkner@Oracle.COM 		progname = argv0;
6013093SRoger.Faulkner@Oracle.COM 	else
6113093SRoger.Faulkner@Oracle.COM 		progname++;
6213093SRoger.Faulkner@Oracle.COM 
6313093SRoger.Faulkner@Oracle.COM 	if (udp->progname == NULL)
6413093SRoger.Faulkner@Oracle.COM 		udp->progname = lmalloc(PROGNAMESIZE);
6513093SRoger.Faulkner@Oracle.COM 	(void) strlcpy(udp->progname, progname, PROGNAMESIZE);
6613093SRoger.Faulkner@Oracle.COM 	__progname = udp->progname;
6713093SRoger.Faulkner@Oracle.COM }
6813093SRoger.Faulkner@Oracle.COM 
6913093SRoger.Faulkner@Oracle.COM /* called only from libc_init() */
7013093SRoger.Faulkner@Oracle.COM void
init_progname(void)7113093SRoger.Faulkner@Oracle.COM init_progname(void)
7213093SRoger.Faulkner@Oracle.COM {
7313093SRoger.Faulkner@Oracle.COM 	Dl_argsinfo_t args;
7413093SRoger.Faulkner@Oracle.COM 	const char *argv0;
7513093SRoger.Faulkner@Oracle.COM 
76*13133SRoger.Faulkner@Oracle.COM 	if (dlinfo(RTLD_SELF, RTLD_DI_ARGSINFO, &args) < 0 ||
77*13133SRoger.Faulkner@Oracle.COM 	    args.dla_argc <= 0 ||
78*13133SRoger.Faulkner@Oracle.COM 	    (argv0 = args.dla_argv[0]) == NULL)
7913093SRoger.Faulkner@Oracle.COM 		argv0 = "UNKNOWN";
80*13133SRoger.Faulkner@Oracle.COM 
8113093SRoger.Faulkner@Oracle.COM 	setprogname(argv0);
8213093SRoger.Faulkner@Oracle.COM }
834891Svk199839 
844891Svk199839 /*
854891Svk199839  * warncore() is the workhorse of these functions.  Everything else has
864891Svk199839  * a warncore() component in it.
874891Svk199839  */
885891Sraf static rmutex_t *
warncore(FILE * fp,const char * fmt,va_list args)894891Svk199839 warncore(FILE *fp, const char *fmt, va_list args)
904891Svk199839 {
915891Sraf 	rmutex_t *lk;
925490Svk199839 
935891Sraf 	FLOCKFILE(lk, fp);
945891Sraf 
9513093SRoger.Faulkner@Oracle.COM 	if (__progname != NULL)
9613093SRoger.Faulkner@Oracle.COM 		(void) fprintf(fp, "%s: ", __progname);
974891Svk199839 
984891Svk199839 	if (fmt != NULL) {
994891Svk199839 		(void) vfprintf(fp, fmt, args);
1004891Svk199839 	}
1015891Sraf 
1025891Sraf 	return (lk);
1034891Svk199839 }
1044891Svk199839 
1054891Svk199839 /* Finish a warning with a newline and a flush of stderr. */
1064891Svk199839 static void
warnfinish(FILE * fp,rmutex_t * lk)1075891Sraf warnfinish(FILE *fp, rmutex_t *lk)
1084891Svk199839 {
1094891Svk199839 	(void) fputc('\n', fp);
1104891Svk199839 	(void) fflush(fp);
1115891Sraf 	FUNLOCKFILE(lk);
1124891Svk199839 }
1134891Svk199839 
1144891Svk199839 void
_vwarnxfp(FILE * fp,const char * fmt,va_list args)1154891Svk199839 _vwarnxfp(FILE *fp, const char *fmt, va_list args)
1164891Svk199839 {
1175891Sraf 	rmutex_t *lk;
1185891Sraf 
1195891Sraf 	lk = warncore(fp, fmt, args);
1205891Sraf 	warnfinish(fp, lk);
1214891Svk199839 }
1224891Svk199839 
1234891Svk199839 void
vwarnx(const char * fmt,va_list args)1244891Svk199839 vwarnx(const char *fmt, va_list args)
1254891Svk199839 {
1264891Svk199839 	_vwarnxfp(stderr, fmt, args);
1274891Svk199839 }
1284891Svk199839 
1294891Svk199839 void
_vwarnfp(FILE * fp,const char * fmt,va_list args)1304891Svk199839 _vwarnfp(FILE *fp, const char *fmt, va_list args)
1314891Svk199839 {
1324891Svk199839 	int tmperr = errno;	/* Capture errno now. */
1335891Sraf 	rmutex_t *lk;
1344891Svk199839 
1355891Sraf 	lk = warncore(fp, fmt, args);
1364891Svk199839 	if (fmt != NULL) {
1374891Svk199839 		(void) fputc(':', fp);
1384891Svk199839 		(void) fputc(' ', fp);
1394891Svk199839 	}
1404891Svk199839 	(void) fputs(strerror(tmperr), fp);
1415891Sraf 	warnfinish(fp, lk);
1424891Svk199839 }
1434891Svk199839 
1444891Svk199839 void
vwarn(const char * fmt,va_list args)1454891Svk199839 vwarn(const char *fmt, va_list args)
1464891Svk199839 {
1474891Svk199839 	_vwarnfp(stderr, fmt, args);
1484891Svk199839 }
1494891Svk199839 
1504891Svk199839 /* PRINTFLIKE1 */
1514891Svk199839 void
warnx(const char * fmt,...)1524891Svk199839 warnx(const char *fmt, ...)
1534891Svk199839 {
1544891Svk199839 	va_list args;
1554891Svk199839 
1564891Svk199839 	va_start(args, fmt);
1574891Svk199839 	vwarnx(fmt, args);
1584891Svk199839 	va_end(args);
1594891Svk199839 }
1604891Svk199839 
1614891Svk199839 void
_warnfp(FILE * fp,const char * fmt,...)1624891Svk199839 _warnfp(FILE *fp, const char *fmt, ...)
1634891Svk199839 {
1644891Svk199839 	va_list args;
1654891Svk199839 
1664891Svk199839 	va_start(args, fmt);
1674891Svk199839 	_vwarnfp(fp, fmt, args);
1684891Svk199839 	va_end(args);
1694891Svk199839 }
1704891Svk199839 
1714891Svk199839 void
_warnxfp(FILE * fp,const char * fmt,...)1724891Svk199839 _warnxfp(FILE *fp, const char *fmt, ...)
1734891Svk199839 {
1744891Svk199839 	va_list args;
1754891Svk199839 
1764891Svk199839 	va_start(args, fmt);
1774891Svk199839 	_vwarnxfp(fp, fmt, args);
1784891Svk199839 	va_end(args);
1794891Svk199839 }
1804891Svk199839 
1814891Svk199839 /* PRINTFLIKE1 */
1824891Svk199839 void
warn(const char * fmt,...)1834891Svk199839 warn(const char *fmt, ...)
1844891Svk199839 {
1854891Svk199839 	va_list args;
1864891Svk199839 
1874891Svk199839 	va_start(args, fmt);
1884891Svk199839 	vwarn(fmt, args);
1894891Svk199839 	va_end(args);
1904891Svk199839 }
1914891Svk199839 
1924891Svk199839 /* PRINTFLIKE2 */
1934891Svk199839 void
err(int status,const char * fmt,...)1944891Svk199839 err(int status, const char *fmt, ...)
1954891Svk199839 {
1964891Svk199839 	va_list args;
1974891Svk199839 
1984891Svk199839 	va_start(args, fmt);
1994891Svk199839 	vwarn(fmt, args);
2004891Svk199839 	va_end(args);
2014891Svk199839 	exit(status);
2024891Svk199839 }
2034891Svk199839 
2044891Svk199839 void
_errfp(FILE * fp,int status,const char * fmt,...)2054891Svk199839 _errfp(FILE *fp, int status, const char *fmt, ...)
2064891Svk199839 {
2074891Svk199839 	va_list args;
2084891Svk199839 
2094891Svk199839 	va_start(args, fmt);
2104891Svk199839 	_vwarnfp(fp, fmt, args);
2114891Svk199839 	va_end(args);
2124891Svk199839 	exit(status);
2134891Svk199839 }
2144891Svk199839 
2154891Svk199839 void
verr(int status,const char * fmt,va_list args)2164891Svk199839 verr(int status, const char *fmt, va_list args)
2174891Svk199839 {
2184891Svk199839 	vwarn(fmt, args);
2194891Svk199839 	exit(status);
2204891Svk199839 }
2214891Svk199839 
2224891Svk199839 void
_verrfp(FILE * fp,int status,const char * fmt,va_list args)2234891Svk199839 _verrfp(FILE *fp, int status, const char *fmt, va_list args)
2244891Svk199839 {
2254891Svk199839 	_vwarnfp(fp, fmt, args);
2264891Svk199839 	exit(status);
2274891Svk199839 }
2284891Svk199839 
2294891Svk199839 /* PRINTFLIKE2 */
2304891Svk199839 void
errx(int status,const char * fmt,...)2314891Svk199839 errx(int status, const char *fmt, ...)
2324891Svk199839 {
2334891Svk199839 	va_list args;
2344891Svk199839 
2354891Svk199839 	va_start(args, fmt);
2364891Svk199839 	vwarnx(fmt, args);
2374891Svk199839 	va_end(args);
2384891Svk199839 	exit(status);
2394891Svk199839 }
2404891Svk199839 
2414891Svk199839 void
_errxfp(FILE * fp,int status,const char * fmt,...)2424891Svk199839 _errxfp(FILE *fp, int status, const char *fmt, ...)
2434891Svk199839 {
2444891Svk199839 	va_list args;
2454891Svk199839 
2464891Svk199839 	va_start(args, fmt);
2474891Svk199839 	_vwarnxfp(fp, fmt, args);
2484891Svk199839 	va_end(args);
2494891Svk199839 	exit(status);
2504891Svk199839 }
2514891Svk199839 
2524891Svk199839 void
verrx(int status,const char * fmt,va_list args)2534891Svk199839 verrx(int status, const char *fmt, va_list args)
2544891Svk199839 {
2554891Svk199839 	vwarnx(fmt, args);
2564891Svk199839 	exit(status);
2574891Svk199839 }
2584891Svk199839 
2594891Svk199839 void
_verrxfp(FILE * fp,int status,const char * fmt,va_list args)2604891Svk199839 _verrxfp(FILE *fp, int status, const char *fmt, va_list args)
2614891Svk199839 {
2624891Svk199839 	_vwarnxfp(fp, fmt, args);
2634891Svk199839 	exit(status);
2644891Svk199839 }
265