00001 /* 00002 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 00003 * The President and Fellows of Harvard College. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the University nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 */ 00029 00030 #include <stdio.h> 00031 #include <stdarg.h> 00032 #include <stdlib.h> 00033 #include <string.h> 00034 #include <unistd.h> 00035 #include <err.h> 00036 #include <errno.h> 00037 00038 /* 00039 * 4.4BSD error printing functions. 00040 */ 00041 00042 /* 00043 * This is initialized by crt0, though it actually lives in errno.c 00044 */ 00045 extern char **__argv; 00046 00047 /* 00048 * Routine to print error message text to stderr. 00049 */ 00050 static 00051 void 00052 __senderr(void *junk, const char *data, size_t len) 00053 { 00054 (void)junk; /* not needed or used */ 00055 00056 write(STDERR_FILENO, data, len); 00057 } 00058 00059 /* 00060 * Shortcut to call __senderr on a null-terminated string. 00061 * (__senderr is set up to be called by __vprintf.) 00062 */ 00063 static 00064 void 00065 __senderrstr(const char *str) 00066 { 00067 __senderr(NULL, str, strlen(str)); 00068 } 00069 00070 /* 00071 * Common routine for all the *err* and *warn* functions. 00072 */ 00073 static 00074 void 00075 __printerr(int use_errno, const char *fmt, va_list ap) 00076 { 00077 const char *errmsg; 00078 const char *prog; 00079 00080 /* 00081 * Get the error message for the current errno. 00082 * Do this early, before doing anything that might change the 00083 * value in errno. 00084 */ 00085 errmsg = strerror(errno); 00086 00087 /* 00088 * Look up the program name. 00089 * Strictly speaking we should pull off the rightmost 00090 * path component of argv[0] and use that as the program 00091 * name (this is how BSD err* prints) but it doesn't make 00092 * much difference. 00093 */ 00094 if (__argv!=NULL && __argv[0]!=NULL) { 00095 prog = __argv[0]; 00096 } 00097 else { 00098 prog = "(program name unknown)"; 00099 } 00100 00101 /* print the program name */ 00102 __senderrstr(prog); 00103 __senderrstr(": "); 00104 00105 /* process the printf format and args */ 00106 __vprintf(__senderr, NULL, fmt, ap); 00107 00108 /* if we're using errno, print the error string from above. */ 00109 if (use_errno) { 00110 __senderrstr(": "); 00111 __senderrstr(errmsg); 00112 } 00113 00114 /* and always add a newline. */ 00115 __senderrstr("\n"); 00116 } 00117 00118 /* 00119 * The va_list versions of the warn/err functions. 00120 */ 00121 00122 /* warn/vwarn: use errno, don't exit */ 00123 void 00124 vwarn(const char *fmt, va_list ap) 00125 { 00126 __printerr(1, fmt, ap); 00127 } 00128 00129 /* warnx/vwarnx: don't use errno, don't exit */ 00130 void 00131 vwarnx(const char *fmt, va_list ap) 00132 { 00133 __printerr(0, fmt, ap); 00134 } 00135 00136 /* err/verr: use errno, then exit */ 00137 void 00138 verr(int exitcode, const char *fmt, va_list ap) 00139 { 00140 __printerr(1, fmt, ap); 00141 exit(exitcode); 00142 } 00143 00144 /* errx/verrx: don't use errno, but do then exit */ 00145 void 00146 verrx(int exitcode, const char *fmt, va_list ap) 00147 { 00148 __printerr(0, fmt, ap); 00149 exit(exitcode); 00150 } 00151 00152 /* 00153 * The non-va_list versions of the warn/err functions. 00154 * Just hand off to the va_list versions. 00155 */ 00156 00157 void 00158 warn(const char *fmt, ...) 00159 { 00160 va_list ap; 00161 va_start(ap, fmt); 00162 vwarn(fmt, ap); 00163 va_end(ap); 00164 } 00165 00166 void 00167 warnx(const char *fmt, ...) 00168 { 00169 va_list ap; 00170 va_start(ap, fmt); 00171 vwarnx(fmt, ap); 00172 va_end(ap); 00173 } 00174 00175 void 00176 err(int exitcode, const char *fmt, ...) 00177 { 00178 va_list ap; 00179 va_start(ap, fmt); 00180 verr(exitcode, fmt, ap); 00181 va_end(ap); 00182 } 00183 00184 void 00185 errx(int exitcode, const char *fmt, ...) 00186 { 00187 va_list ap; 00188 va_start(ap, fmt); 00189 verrx(exitcode, fmt, ap); 00190 va_end(ap); 00191 }