2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#include "lint.h"
2N/A#include "file64.h"
2N/A#include "mtlib.h"
2N/A#include "thr_uberdata.h"
2N/A#include <sys/types.h>
2N/A#include <err.h>
2N/A#include <stdio.h>
2N/A#include <stdlib.h>
2N/A#include <stdarg.h>
2N/A#include <string.h>
2N/A#include <errno.h>
2N/A#include <dlfcn.h>
2N/A#include "stdiom.h"
2N/A
2N/A/* Function exit/warning functions and global variables. */
2N/A
2N/Aconst char *__progname; /* GNU/Linux/BSD compatibility */
2N/A
2N/A#define PROGNAMESIZE 128 /* buffer size for __progname */
2N/A
2N/Aconst char *
2N/Agetprogname(void)
2N/A{
2N/A return (__progname);
2N/A}
2N/A
2N/Avoid
2N/Asetprogname(const char *argv0)
2N/A{
2N/A uberdata_t *udp = curthread->ul_uberdata;
2N/A const char *progname;
2N/A
2N/A if ((progname = strrchr(argv0, '/')) == NULL)
2N/A progname = argv0;
2N/A else
2N/A progname++;
2N/A
2N/A if (udp->progname == NULL)
2N/A udp->progname = lmalloc(PROGNAMESIZE);
2N/A (void) strlcpy(udp->progname, progname, PROGNAMESIZE);
2N/A __progname = udp->progname;
2N/A}
2N/A
2N/A/* called only from libc_init() */
2N/Avoid
2N/Ainit_progname(void)
2N/A{
2N/A Dl_argsinfo_t args;
2N/A const char *argv0;
2N/A
2N/A if (dlinfo(RTLD_SELF, RTLD_DI_ARGSINFO, &args) < 0 ||
2N/A args.dla_argc <= 0 ||
2N/A (argv0 = args.dla_argv[0]) == NULL)
2N/A argv0 = "UNKNOWN";
2N/A
2N/A setprogname(argv0);
2N/A}
2N/A
2N/A/*
2N/A * warncore() is the workhorse of these functions. Everything else has
2N/A * a warncore() component in it.
2N/A */
2N/Astatic rmutex_t *
2N/Awarncore(FILE *fp, const char *fmt, va_list args)
2N/A{
2N/A rmutex_t *lk;
2N/A
2N/A FLOCKFILE(lk, fp);
2N/A
2N/A if (__progname != NULL)
2N/A (void) fprintf(fp, "%s: ", __progname);
2N/A
2N/A if (fmt != NULL) {
2N/A (void) vfprintf(fp, fmt, args);
2N/A }
2N/A
2N/A return (lk);
2N/A}
2N/A
2N/A/* Finish a warning with a newline and a flush of stderr. */
2N/Astatic void
2N/Awarnfinish(FILE *fp, rmutex_t *lk)
2N/A{
2N/A (void) fputc('\n', fp);
2N/A (void) fflush(fp);
2N/A FUNLOCKFILE(lk);
2N/A}
2N/A
2N/Avoid
2N/A_vwarnxfp(FILE *fp, const char *fmt, va_list args)
2N/A{
2N/A rmutex_t *lk;
2N/A
2N/A lk = warncore(fp, fmt, args);
2N/A warnfinish(fp, lk);
2N/A}
2N/A
2N/Avoid
2N/Avwarnx(const char *fmt, va_list args)
2N/A{
2N/A _vwarnxfp(stderr, fmt, args);
2N/A}
2N/A
2N/Avoid
2N/A_vwarnfp(FILE *fp, const char *fmt, va_list args)
2N/A{
2N/A int tmperr = errno; /* Capture errno now. */
2N/A rmutex_t *lk;
2N/A
2N/A lk = warncore(fp, fmt, args);
2N/A if (fmt != NULL) {
2N/A (void) fputc(':', fp);
2N/A (void) fputc(' ', fp);
2N/A }
2N/A (void) fputs(strerror(tmperr), fp);
2N/A warnfinish(fp, lk);
2N/A}
2N/A
2N/Avoid
2N/Avwarn(const char *fmt, va_list args)
2N/A{
2N/A _vwarnfp(stderr, fmt, args);
2N/A}
2N/A
2N/A/* PRINTFLIKE1 */
2N/Avoid
2N/Awarnx(const char *fmt, ...)
2N/A{
2N/A va_list args;
2N/A
2N/A va_start(args, fmt);
2N/A vwarnx(fmt, args);
2N/A va_end(args);
2N/A}
2N/A
2N/Avoid
2N/A_warnfp(FILE *fp, const char *fmt, ...)
2N/A{
2N/A va_list args;
2N/A
2N/A va_start(args, fmt);
2N/A _vwarnfp(fp, fmt, args);
2N/A va_end(args);
2N/A}
2N/A
2N/Avoid
2N/A_warnxfp(FILE *fp, const char *fmt, ...)
2N/A{
2N/A va_list args;
2N/A
2N/A va_start(args, fmt);
2N/A _vwarnxfp(fp, fmt, args);
2N/A va_end(args);
2N/A}
2N/A
2N/A/* PRINTFLIKE1 */
2N/Avoid
2N/Awarn(const char *fmt, ...)
2N/A{
2N/A va_list args;
2N/A
2N/A va_start(args, fmt);
2N/A vwarn(fmt, args);
2N/A va_end(args);
2N/A}
2N/A
2N/A/* PRINTFLIKE2 */
2N/Avoid
2N/Aerr(int status, const char *fmt, ...)
2N/A{
2N/A va_list args;
2N/A
2N/A va_start(args, fmt);
2N/A vwarn(fmt, args);
2N/A va_end(args);
2N/A exit(status);
2N/A}
2N/A
2N/Avoid
2N/A_errfp(FILE *fp, int status, const char *fmt, ...)
2N/A{
2N/A va_list args;
2N/A
2N/A va_start(args, fmt);
2N/A _vwarnfp(fp, fmt, args);
2N/A va_end(args);
2N/A exit(status);
2N/A}
2N/A
2N/Avoid
2N/Averr(int status, const char *fmt, va_list args)
2N/A{
2N/A vwarn(fmt, args);
2N/A exit(status);
2N/A}
2N/A
2N/Avoid
2N/A_verrfp(FILE *fp, int status, const char *fmt, va_list args)
2N/A{
2N/A _vwarnfp(fp, fmt, args);
2N/A exit(status);
2N/A}
2N/A
2N/A/* PRINTFLIKE2 */
2N/Avoid
2N/Aerrx(int status, const char *fmt, ...)
2N/A{
2N/A va_list args;
2N/A
2N/A va_start(args, fmt);
2N/A vwarnx(fmt, args);
2N/A va_end(args);
2N/A exit(status);
2N/A}
2N/A
2N/Avoid
2N/A_errxfp(FILE *fp, int status, const char *fmt, ...)
2N/A{
2N/A va_list args;
2N/A
2N/A va_start(args, fmt);
2N/A _vwarnxfp(fp, fmt, args);
2N/A va_end(args);
2N/A exit(status);
2N/A}
2N/A
2N/Avoid
2N/Averrx(int status, const char *fmt, va_list args)
2N/A{
2N/A vwarnx(fmt, args);
2N/A exit(status);
2N/A}
2N/A
2N/Avoid
2N/A_verrxfp(FILE *fp, int status, const char *fmt, va_list args)
2N/A{
2N/A _vwarnxfp(fp, fmt, args);
2N/A exit(status);
2N/A}