Annotation of src/usr.bin/aucat/utils.c, Revision 1.2
1.2 ! mmcc 1: /* $OpenBSD: utils.c,v 1.1 2015/01/21 08:43:55 ratchov Exp $ */
1.1 ratchov 2: /*
3: * Copyright (c) 2003-2012 Alexandre Ratchov <alex@caoua.org>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17: /*
18: * log_xxx() routines are used to quickly store traces into a trace buffer.
19: * This allows trances to be collected during time sensitive operations without
20: * disturbing them. The buffer can be flushed on standard error later, when
21: * slow syscalls are no longer disruptive, e.g. at the end of the poll() loop.
22: */
23: #include <signal.h>
24: #include <stdlib.h>
25: #include <string.h>
26: #include <unistd.h>
27: #include <fcntl.h>
28: #include "utils.h"
29:
30: /*
31: * log buffer size
32: */
33: #define LOG_BUFSZ 8192
34:
35: /*
36: * store a character in the log
37: */
38: #define LOG_PUTC(c) do { \
39: if (log_used < LOG_BUFSZ) \
40: log_buf[log_used++] = (c); \
41: } while (0)
42:
43: char log_buf[LOG_BUFSZ]; /* buffer where traces are stored */
44: unsigned int log_used = 0; /* bytes used in the buffer */
45: unsigned int log_sync = 1; /* if true, flush after each '\n' */
46:
47: /*
48: * write the log buffer on stderr
49: */
50: void
51: log_flush(void)
52: {
53: if (log_used == 0)
54: return;
55: write(STDERR_FILENO, log_buf, log_used);
56: log_used = 0;
57: }
58:
59: /*
60: * store a string in the log
61: */
62: void
63: log_puts(char *msg)
64: {
65: char *p = msg;
66: int c;
67:
68: while ((c = *p++) != '\0') {
69: LOG_PUTC(c);
70: if (log_sync && c == '\n')
71: log_flush();
72: }
73: }
74:
75: /*
76: * store a hex in the log
77: */
78: void
79: log_putx(unsigned long num)
80: {
81: char dig[sizeof(num) * 2], *p = dig, c;
82: unsigned int ndig;
83:
84: if (num != 0) {
85: for (ndig = 0; num != 0; ndig++) {
86: *p++ = num & 0xf;
87: num >>= 4;
88: }
89: for (; ndig != 0; ndig--) {
90: c = *(--p);
91: c += (c < 10) ? '0' : 'a' - 10;
92: LOG_PUTC(c);
93: }
94: } else
95: LOG_PUTC('0');
96: }
97:
98: /*
99: * store a unsigned decimal in the log
100: */
101: void
102: log_putu(unsigned long num)
103: {
104: char dig[sizeof(num) * 3], *p = dig;
105: unsigned int ndig;
106:
107: if (num != 0) {
108: for (ndig = 0; num != 0; ndig++) {
109: *p++ = num % 10;
110: num /= 10;
111: }
112: for (; ndig != 0; ndig--)
113: LOG_PUTC(*(--p) + '0');
114: } else
115: LOG_PUTC('0');
116: }
117:
118: /*
119: * store a signed decimal in the log
120: */
121: void
122: log_puti(long num)
123: {
124: if (num < 0) {
125: LOG_PUTC('-');
126: num = -num;
127: }
128: log_putu(num);
129: }
130:
131: /*
132: * abort program execution after a fatal error
133: */
134: void
135: panic(void)
136: {
137: log_flush();
138: (void)kill(getpid(), SIGABRT);
139: _exit(1);
140: }
141:
142: /*
143: * allocate a (small) abount of memory, and abort if it fails
144: */
145: void *
146: xmalloc(size_t size)
147: {
148: void *p;
149:
150: p = malloc(size);
151: if (p == NULL) {
152: log_puts("failed to allocate ");
153: log_putx(size);
154: log_puts(" bytes\n");
155: panic();
156: }
157: return p;
158: }
159:
160: /*
161: * xmalloc-style strdup(3)
162: */
163: char *
164: xstrdup(char *s)
165: {
166: size_t size;
167: void *p;
168:
169: size = strlen(s) + 1;
170: p = xmalloc(size);
171: memcpy(p, s, size);
172: return p;
173: }