Create addr module.
[darkstat] / err.c
1 /* darkstat 3
2 * copyright (c) 2001-2009 Emil Mikulic.
3 *
4 * err.c: BSD-like err() and warn() functions
5 *
6 * Permission to use, copy, modify, and distribute this file for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include "darkstat.h"
20 #include "conv.h"
21 #include "err.h"
22 #include "pidfile.h"
23
24 #include <errno.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <syslog.h>
30 #include <unistd.h>
31 #include <unistd.h>
32
33 static void
34 to_syslog(const char *type, const int want_err,
35 const char *format, va_list va)
36 {
37 char buf[512];
38 size_t pos = 0;
39 int saved_errno = errno;
40
41 if (type != NULL) {
42 strlcpy(buf, type, sizeof(buf));
43 pos = strlen(buf);
44 }
45 vsnprintf(buf+pos, sizeof(buf)-pos, format, va);
46 if (want_err) {
47 strlcat(buf, ": ", sizeof(buf));
48 strlcat(buf, strerror(saved_errno), sizeof(buf));
49 }
50 syslog(LOG_DEBUG, "%s", buf);
51 }
52
53 void
54 err(const int code, const char *format, ...)
55 {
56 va_list va;
57
58 va_start(va, format);
59 if (want_syslog)
60 to_syslog("ERROR: ", 1, format, va);
61 else {
62 fprintf(stderr, "%5d: error: ", (int)getpid());
63 vfprintf(stderr, format, va);
64 fprintf(stderr, ": %s\n", strerror(errno));
65 }
66 va_end(va);
67 pidfile_unlink();
68 exit(code);
69 }
70
71 void
72 errx(const int code, const char *format, ...)
73 {
74 va_list va;
75
76 va_start(va, format);
77 if (want_syslog)
78 to_syslog("ERROR: ", 0, format, va);
79 else {
80 fprintf(stderr, "%5d: error: ", (int)getpid());
81 vfprintf(stderr, format, va);
82 fprintf(stderr, "\n");
83 }
84 va_end(va);
85 pidfile_unlink();
86 exit(code);
87 }
88
89 void
90 warn(const char *format, ...)
91 {
92 va_list va;
93
94 va_start(va, format);
95 if (want_syslog)
96 to_syslog("WARNING: ", 1, format, va);
97 else {
98 fprintf(stderr, "%5d: warning: ", (int)getpid());
99 vfprintf(stderr, format, va);
100 fprintf(stderr, ": %s\n", strerror(errno));
101 }
102 va_end(va);
103 }
104
105 void
106 warnx(const char *format, ...)
107 {
108 va_list va;
109
110 va_start(va, format);
111 if (want_syslog)
112 to_syslog("WARNING: ", 0, format, va);
113 else {
114 fprintf(stderr, "%5d: warning: ", (int)getpid());
115 vfprintf(stderr, format, va);
116 fprintf(stderr, "\n");
117 }
118 va_end(va);
119 }
120
121 /* We interlock verbosef() between processes by using a pipe with a single
122 * byte in it. This pipe must be initialized before the first fork() in order
123 * to work. Then, verbosef() will block on a read() until it is able to
124 * retrieve the byte. After doing its business, it will put a byte back into
125 * the pipe.
126 *
127 * This is completely silly and largely unnecessary.
128 */
129 static int inited = 0;
130 static int lockpipe[2];
131
132 static void unlock(void);
133
134 static void
135 initlock(void)
136 {
137 if (pipe(lockpipe) == -1)
138 err(1, "pipe(lockpipe)");
139 inited = 1;
140 unlock();
141 }
142
143 static void
144 lock(void)
145 {
146 char buf[1];
147
148 if (!inited) initlock();
149 if (read(lockpipe[0], buf, 1) != 1) {
150 fprintf(stderr, "lock failed!\n");
151 pidfile_unlink();
152 exit(1);
153 }
154 }
155
156 static void
157 unlock(void)
158 {
159 char c = 0;
160
161 if (write(lockpipe[1], &c, 1) != 1) {
162 fprintf(stderr, "unlock failed!\n");
163 pidfile_unlink();
164 exit(1);
165 }
166 }
167
168 int want_verbose = 0, want_syslog = 0;
169
170 void
171 verbosef(const char *format, ...)
172 {
173 va_list va;
174
175 if (!want_verbose) return;
176 va_start(va, format);
177 if (want_syslog)
178 to_syslog(NULL, 0, format, va);
179 else {
180 lock();
181 fprintf(stderr, "darkstat (%05d): ", (int)getpid());
182 vfprintf(stderr, format, va);
183 fprintf(stderr, "\n");
184 unlock();
185 }
186 va_end(va);
187 }
188
189 void
190 dverbosef(const char *format _unused_, ...)
191 {
192 /* disabled / do-nothing verbosef */
193 }
194
195 /* vim:set ts=3 sw=3 tw=78 expandtab: */