err.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
  3. * The President and Fellows of Harvard College.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the University nor the names of its contributors
  14. * may be used to endorse or promote products derived from this software
  15. * without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. */
  29. #include <stdio.h>
  30. #include <stdarg.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <unistd.h>
  34. #include <err.h>
  35. #include <errno.h>
  36. /*
  37. * 4.4BSD error printing functions.
  38. */
  39. /*
  40. * This is initialized by crt0, though it actually lives in errno.c
  41. */
  42. extern char **__argv;
  43. /*
  44. * Routine to print error message text to stderr.
  45. */
  46. static
  47. void
  48. __senderr(void *junk, const char *data, size_t len)
  49. {
  50. (void)junk; /* not needed or used */
  51. write(STDERR_FILENO, data, len);
  52. }
  53. /*
  54. * Shortcut to call __senderr on a null-terminated string.
  55. * (__senderr is set up to be called by __vprintf.)
  56. */
  57. static
  58. void
  59. __senderrstr(const char *str)
  60. {
  61. __senderr(NULL, str, strlen(str));
  62. }
  63. /*
  64. * Common routine for all the *err* and *warn* functions.
  65. */
  66. static
  67. void
  68. __printerr(int use_errno, const char *fmt, va_list ap)
  69. {
  70. const char *errmsg;
  71. const char *prog;
  72. /*
  73. * Get the error message for the current errno.
  74. * Do this early, before doing anything that might change the
  75. * value in errno.
  76. */
  77. errmsg = strerror(errno);
  78. /*
  79. * Look up the program name.
  80. * Strictly speaking we should pull off the rightmost
  81. * path component of argv[0] and use that as the program
  82. * name (this is how BSD err* prints) but it doesn't make
  83. * much difference.
  84. */
  85. if (__argv!=NULL && __argv[0]!=NULL) {
  86. prog = __argv[0];
  87. }
  88. else {
  89. prog = "(program name unknown)";
  90. }
  91. /* print the program name */
  92. __senderrstr(prog);
  93. __senderrstr(": ");
  94. /* process the printf format and args */
  95. __vprintf(__senderr, NULL, fmt, ap);
  96. /* if we're using errno, print the error string from above. */
  97. if (use_errno) {
  98. __senderrstr(": ");
  99. __senderrstr(errmsg);
  100. }
  101. /* and always add a newline. */
  102. __senderrstr("\n");
  103. }
  104. /*
  105. * The va_list versions of the warn/err functions.
  106. */
  107. /* warn/vwarn: use errno, don't exit */
  108. void
  109. vwarn(const char *fmt, va_list ap)
  110. {
  111. __printerr(1, fmt, ap);
  112. }
  113. /* warnx/vwarnx: don't use errno, don't exit */
  114. void
  115. vwarnx(const char *fmt, va_list ap)
  116. {
  117. __printerr(0, fmt, ap);
  118. }
  119. /* err/verr: use errno, then exit */
  120. void
  121. verr(int exitcode, const char *fmt, va_list ap)
  122. {
  123. __printerr(1, fmt, ap);
  124. exit(exitcode);
  125. }
  126. /* errx/verrx: don't use errno, but do then exit */
  127. void
  128. verrx(int exitcode, const char *fmt, va_list ap)
  129. {
  130. __printerr(0, fmt, ap);
  131. exit(exitcode);
  132. }
  133. /*
  134. * The non-va_list versions of the warn/err functions.
  135. * Just hand off to the va_list versions.
  136. */
  137. void
  138. warn(const char *fmt, ...)
  139. {
  140. va_list ap;
  141. va_start(ap, fmt);
  142. vwarn(fmt, ap);
  143. va_end(ap);
  144. }
  145. void
  146. warnx(const char *fmt, ...)
  147. {
  148. va_list ap;
  149. va_start(ap, fmt);
  150. vwarnx(fmt, ap);
  151. va_end(ap);
  152. }
  153. void
  154. err(int exitcode, const char *fmt, ...)
  155. {
  156. va_list ap;
  157. va_start(ap, fmt);
  158. verr(exitcode, fmt, ap);
  159. va_end(ap);
  160. }
  161. void
  162. errx(int exitcode, const char *fmt, ...)
  163. {
  164. va_list ap;
  165. va_start(ap, fmt);
  166. verrx(exitcode, fmt, ap);
  167. va_end(ap);
  168. }