New audio subsystem.
[jog] / err.c
CommitLineData
2ec1e693 1/* -*-c-*-
2 *
e9060e7e 3 * $Id: err.c,v 1.2 2002/02/02 19:16:46 mdw Exp $
2ec1e693 4 *
5 * Error reporting
6 *
7 * (c) 2001 Mark Wooding
8 */
9
10/*----- Licensing notice --------------------------------------------------*
11 *
12 * This file is part of Jog: Programming for a jogging machine.
13 *
14 * Jog is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * Jog is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Jog; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29/*----- Revision history --------------------------------------------------*
30 *
31 * $Log: err.c,v $
e9060e7e 32 * Revision 1.2 2002/02/02 19:16:46 mdw
33 * New audio subsystem.
34 *
2ec1e693 35 * Revision 1.1 2002/01/25 19:34:45 mdw
36 * Initial revision
37 *
38 */
39
40/*----- Header files ------------------------------------------------------*/
41
42#ifdef HAVE_CONFIG_H
43# include "config.h"
44#endif
45
46#include <errno.h>
47#include <stdarg.h>
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <time.h>
52
53#include <mLib/exc.h>
54#include <mLib/quis.h>
55
e9060e7e 56#include "auerr.h"
2ec1e693 57#include "err.h"
58
59/*----- Static variables --------------------------------------------------*/
60
61static FILE *logfp = 0;
62static unsigned flags = 0;
63
64#define f_thread 1u
65
66/*----- Main code ---------------------------------------------------------*/
67
68/* --- @err_abort@ --- *
69 *
70 * Arguments: @int reason@ = abort reason code
71 * @unsigned long err@ = abort error code
72 * @const char *msg@ = error message
73 *
74 * Returns: Doesn't.
75 *
76 * Use: Reports a fatal error.
77 */
78
79void err_abortv(int reason, unsigned long err, const char *msg, va_list *ap)
80{
81 fprintf(stderr, "%s: fatal error (code %d-%lu): ", QUIS, reason, err);
82 vfprintf(stderr, msg, *ap);
83 putc('\n', stderr);
e9060e7e 84 auerr_abort(reason, err);
2ec1e693 85 abort();
86}
87
88void err_abort(int reason, unsigned long err, const char *msg, ...)
89{
90 va_list ap;
91
92 va_start(ap, msg);
93 err_abortv(reason, err, msg, &ap);
94 va_end(ap);
95}
96
97/* --- @err_init@ --- *
98 *
99 * Arguments: ---
100 *
101 * Returns: ---
102 *
103 * Use: Attempts to initialize the logging system. It is a
104 * catastrophic failure if logging can't start up.
105 */
106
107static void err_exc(exc_extype ex, exc_exval v)
108{
109 switch (ex) {
110 case EXC_NOMEM:
111 err_report(ERR_EXC, 0, ex, "out of memory");
112 break;
113 default:
114 err_report(ERR_EXC, 0, ex, "uncaught mLib exception");
115 break;
116 }
117 exit(EXIT_FAILURE);
118}
119
120void err_init(void)
121{
122 const char *lf;
123
124 lf = getenv("JOG_LOGFILE");
125 if (!lf)
126 logfp = stderr;
127 else if ((logfp = fopen(lf, "w")) == 0) {
128 err_abort(ERRABORT_LOGOPEN, errno,
129 "couldn't open logfile `%s': %s", lf, strerror(errno));
130 }
131 exc_uncaught(err_exc);
132}
133
134/* --- @err_report@ --- *
135 *
136 * Arguments: @int ctx@ = context code
137 * @int reason@ = reason code
138 * @unsigned long err@ = system error code
139 * @const char *msg@ = textual message to log
140 *
141 * Returns: ---
142 *
143 * Use: Reports an error. Doesn't abort anything unless something
144 * really serious happens.
145 */
146
147void err_reportv(int ctx, int reason, unsigned long err,
148 const char *msg, va_list *ap)
149{
150 char buf[256];
151 time_t t;
152 struct tm *tm;
153
154 if (ctx && !(flags & f_thread)) {
155 unsigned f = flags;
156 flags |= f_thread;
e9060e7e 157 auerr(ctx, reason, err);
2ec1e693 158 flags = f;
159 }
160 t = time(0);
161 tm = localtime(&t);
162 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm);
163 if (fputs(buf, logfp) == EOF ||
164 fprintf(stderr, " %s: ", QUIS) == EOF ||
165 vfprintf(logfp, msg, *ap) == EOF ||
166 (ctx && (fprintf(logfp, " (error %d", ctx) == EOF ||
167 (reason && fprintf(logfp, "-%d", reason) == EOF) ||
168 (err && fprintf(logfp, ":%lu", err) == EOF) ||
169 putc(')', logfp) == EOF)) ||
170 putc('\n', logfp) == EOF ||
171 fflush(logfp) == EOF) {
172 err_abort(ERRABORT_LOGWRITE, errno,
173 "error writing logfile: %s", strerror(errno));
174 }
175}
176
177void err_report(int ctx, int reason, unsigned long err, const char *msg, ...)
178{
179 va_list ap;
180
181 va_start(ap, msg);
182 err_reportv(ctx, reason, err, msg, &ap);
183 va_end(ap);
184}
185
186/* --- @err_log@ --- *
187 *
188 * Arguments: @const char *msg@ = textual message to log
189 *
190 * Returns: ---
191 *
192 * Use: Logs a message.
193 */
194
195void err_logv(const char *msg, va_list *ap)
196{
197 err_reportv(0, 0, 0, msg, ap);
198}
199
200void err_log(const char *msg, ...)
201{
202 va_list ap;
203
204 va_start(ap, msg);
205 err_reportv(0, 0, 0, msg, &ap);
206 va_end(ap);
207}
208
209/*----- That's all, folks -------------------------------------------------*/