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