PageRenderTime 52ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/contrib/cvs/src/error.c

https://bitbucket.org/freebsd/freebsd-head/
C | 255 lines | 184 code | 22 blank | 49 comment | 25 complexity | 0b7addf0442fbd32bffd3be9416859d2 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.0, LGPL-2.1, BSD-2-Clause, 0BSD, JSON, AGPL-1.0, GPL-2.0
  1. /* error.c -- error handler for noninteractive utilities
  2. Copyright (C) 1990-1992 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2, or (at your option)
  6. any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details. */
  11. /* David MacKenzie */
  12. /* Brian Berliner added support for CVS */
  13. #include "cvs.h"
  14. #include <stdio.h>
  15. /* If non-zero, error will use the CVS protocol to stdout to report error
  16. messages. This will only be set in the CVS server parent process;
  17. most other code is run via do_cvs_command, which forks off a child
  18. process and packages up its stderr in the protocol. */
  19. int error_use_protocol;
  20. #ifdef HAVE_VPRINTF
  21. #ifdef __STDC__
  22. #include <stdarg.h>
  23. #define VA_START(args, lastarg) va_start(args, lastarg)
  24. #else /* ! __STDC__ */
  25. #include <varargs.h>
  26. #define VA_START(args, lastarg) va_start(args)
  27. #endif /* __STDC__ */
  28. #else /* ! HAVE_VPRINTF */
  29. #ifdef HAVE_DOPRNT
  30. #define va_alist args
  31. #define va_dcl int args;
  32. #else /* ! HAVE_DOPRNT */
  33. #define va_alist a1, a2, a3, a4, a5, a6, a7, a8
  34. #define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
  35. #endif /* HAVE_DOPRNT */
  36. #endif /* HAVE_VPRINTF */
  37. #if STDC_HEADERS
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #else /* ! STDC_HEADERS */
  41. #ifdef __STDC__
  42. void exit(int status);
  43. #else /* ! __STDC__ */
  44. void exit ();
  45. #endif /* __STDC__ */
  46. #endif /* STDC_HEADERS */
  47. #ifndef strerror
  48. extern char *strerror ();
  49. #endif
  50. void
  51. error_exit PROTO ((void))
  52. {
  53. rcs_cleanup ();
  54. Lock_Cleanup ();
  55. #ifdef SERVER_SUPPORT
  56. if (server_active)
  57. server_cleanup (0);
  58. #endif
  59. #ifdef SYSTEM_CLEANUP
  60. /* Hook for OS-specific behavior, for example socket subsystems on
  61. NT and OS2 or dealing with windows and arguments on Mac. */
  62. SYSTEM_CLEANUP ();
  63. #endif
  64. exit (EXIT_FAILURE);
  65. }
  66. /* Print the program name and error message MESSAGE, which is a printf-style
  67. format string with optional args. This is a very limited printf subset:
  68. %s, %d, %c, %x and %% only (without anything between the % and the s,
  69. d, &c). Callers who want something fancier can use sprintf.
  70. If ERRNUM is nonzero, print its corresponding system error message.
  71. Exit with status EXIT_FAILURE if STATUS is nonzero. If MESSAGE is "",
  72. no need to print a message.
  73. I think this is largely cleaned up to the point where it does the right
  74. thing for the server, whether the normal server_active (child process)
  75. case or the error_use_protocol (parent process) case. The one exception
  76. is that STATUS nonzero for error_use_protocol probably doesn't work yet;
  77. in that case still need to use the pending_error machinery in server.c.
  78. error() does not molest errno; some code (e.g. Entries_Open) depends
  79. on being able to say something like:
  80. error (0, 0, "foo");
  81. error (0, errno, "bar");
  82. */
  83. /* VARARGS */
  84. void
  85. #if defined (__STDC__)
  86. error (int status, int errnum, const char *message, ...)
  87. #else
  88. error (status, errnum, message, va_alist)
  89. int status;
  90. int errnum;
  91. const char *message;
  92. va_dcl
  93. #endif
  94. {
  95. int save_errno = errno;
  96. if (message[0] != '\0')
  97. {
  98. va_list args;
  99. const char *p;
  100. char *q;
  101. char *str;
  102. int num;
  103. long lnum;
  104. unsigned int unum;
  105. unsigned long ulnum;
  106. int ch;
  107. char buf[100];
  108. cvs_outerr (program_name, 0);
  109. if (cvs_cmd_name && *cvs_cmd_name)
  110. {
  111. cvs_outerr (" ", 1);
  112. if (status != 0)
  113. cvs_outerr ("[", 1);
  114. cvs_outerr (cvs_cmd_name, 0);
  115. if (status != 0)
  116. cvs_outerr (" aborted]", 0);
  117. }
  118. cvs_outerr (": ", 2);
  119. VA_START (args, message);
  120. p = message;
  121. while ((q = strchr (p, '%')) != NULL)
  122. {
  123. static const char msg[] =
  124. "\ninternal error: bad % in error()\n";
  125. if (q - p > 0)
  126. cvs_outerr (p, q - p);
  127. switch (q[1])
  128. {
  129. case 's':
  130. str = va_arg (args, char *);
  131. cvs_outerr (str, strlen (str));
  132. break;
  133. case 'd':
  134. num = va_arg (args, int);
  135. sprintf (buf, "%d", num);
  136. cvs_outerr (buf, strlen (buf));
  137. break;
  138. case 'l':
  139. if (q[2] == 'd')
  140. {
  141. lnum = va_arg (args, long);
  142. sprintf (buf, "%ld", lnum);
  143. }
  144. else if (q[2] == 'u')
  145. {
  146. ulnum = va_arg (args, unsigned long);
  147. sprintf (buf, "%lu", ulnum);
  148. }
  149. else goto bad;
  150. cvs_outerr (buf, strlen (buf));
  151. q++;
  152. break;
  153. case 'x':
  154. unum = va_arg (args, unsigned int);
  155. sprintf (buf, "%x", unum);
  156. cvs_outerr (buf, strlen (buf));
  157. break;
  158. case 'c':
  159. ch = va_arg (args, int);
  160. buf[0] = ch;
  161. cvs_outerr (buf, 1);
  162. break;
  163. case '%':
  164. cvs_outerr ("%", 1);
  165. break;
  166. default:
  167. bad:
  168. cvs_outerr (msg, sizeof (msg) - 1);
  169. /* Don't just keep going, because q + 1 might point to the
  170. terminating '\0'. */
  171. goto out;
  172. }
  173. p = q + 2;
  174. }
  175. cvs_outerr (p, strlen (p));
  176. out:
  177. va_end (args);
  178. if (errnum != 0)
  179. {
  180. cvs_outerr (": ", 2);
  181. cvs_outerr (strerror (errnum), 0);
  182. }
  183. cvs_outerr ("\n", 1);
  184. }
  185. if (status)
  186. error_exit ();
  187. errno = save_errno;
  188. }
  189. /* Print the program name and error message MESSAGE, which is a printf-style
  190. format string with optional args to the file specified by FP.
  191. If ERRNUM is nonzero, print its corresponding system error message.
  192. Exit with status EXIT_FAILURE if STATUS is nonzero. */
  193. /* VARARGS */
  194. void
  195. #if defined (HAVE_VPRINTF) && defined (__STDC__)
  196. fperrmsg (FILE *fp, int status, int errnum, char *message, ...)
  197. #else
  198. fperrmsg (fp, status, errnum, message, va_alist)
  199. FILE *fp;
  200. int status;
  201. int errnum;
  202. char *message;
  203. va_dcl
  204. #endif
  205. {
  206. #ifdef HAVE_VPRINTF
  207. va_list args;
  208. #endif
  209. fprintf (fp, "%s: ", program_name);
  210. #ifdef HAVE_VPRINTF
  211. VA_START (args, message);
  212. vfprintf (fp, message, args);
  213. va_end (args);
  214. #else
  215. #ifdef HAVE_DOPRNT
  216. _doprnt (message, &args, fp);
  217. #else
  218. fprintf (fp, message, a1, a2, a3, a4, a5, a6, a7, a8);
  219. #endif
  220. #endif
  221. if (errnum)
  222. fprintf (fp, ": %s", strerror (errnum));
  223. putc ('\n', fp);
  224. fflush (fp);
  225. if (status)
  226. error_exit ();
  227. }