Annotation of src/usr.bin/aucat/utils.c, Revision 1.4
1.4 ! ratchov 1: /* $OpenBSD: utils.c,v 1.3 2016/01/10 11:06:44 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 "utils.h"
28:
29: /*
30: * log buffer size
31: */
32: #define LOG_BUFSZ 8192
33:
34: /*
35: * store a character in the log
36: */
37: #define LOG_PUTC(c) do { \
38: if (log_used < LOG_BUFSZ) \
39: log_buf[log_used++] = (c); \
40: } while (0)
41:
42: char log_buf[LOG_BUFSZ]; /* buffer where traces are stored */
43: unsigned int log_used = 0; /* bytes used in the buffer */
44: unsigned int log_sync = 1; /* if true, flush after each '\n' */
45:
46: /*
47: * write the log buffer on stderr
48: */
49: void
50: log_flush(void)
51: {
52: if (log_used == 0)
53: return;
54: write(STDERR_FILENO, log_buf, log_used);
55: log_used = 0;
56: }
57:
58: /*
59: * store a string in the log
60: */
61: void
62: log_puts(char *msg)
63: {
64: char *p = msg;
65: int c;
66:
67: while ((c = *p++) != '\0') {
68: LOG_PUTC(c);
69: if (log_sync && c == '\n')
70: log_flush();
71: }
72: }
73:
74: /*
75: * store a hex in the log
76: */
77: void
78: log_putx(unsigned long num)
79: {
80: char dig[sizeof(num) * 2], *p = dig, c;
81: unsigned int ndig;
82:
83: if (num != 0) {
84: for (ndig = 0; num != 0; ndig++) {
85: *p++ = num & 0xf;
86: num >>= 4;
87: }
88: for (; ndig != 0; ndig--) {
89: c = *(--p);
90: c += (c < 10) ? '0' : 'a' - 10;
91: LOG_PUTC(c);
92: }
1.3 ratchov 93: } else
1.1 ratchov 94: LOG_PUTC('0');
95: }
96:
97: /*
98: * store a unsigned decimal in the log
99: */
100: void
101: log_putu(unsigned long num)
102: {
103: char dig[sizeof(num) * 3], *p = dig;
104: unsigned int ndig;
105:
106: if (num != 0) {
107: for (ndig = 0; num != 0; ndig++) {
108: *p++ = num % 10;
109: num /= 10;
110: }
111: for (; ndig != 0; ndig--)
112: LOG_PUTC(*(--p) + '0');
113: } else
114: LOG_PUTC('0');
115: }
116:
117: /*
118: * store a signed decimal in the log
119: */
120: void
121: log_puti(long num)
122: {
123: if (num < 0) {
124: LOG_PUTC('-');
125: num = -num;
126: }
127: log_putu(num);
128: }
129:
130: /*
131: * abort program execution after a fatal error
132: */
133: void
134: panic(void)
135: {
136: log_flush();
137: (void)kill(getpid(), SIGABRT);
138: _exit(1);
139: }
140:
141: /*
142: * allocate a (small) abount of memory, and abort if it fails
143: */
144: void *
145: xmalloc(size_t size)
146: {
147: void *p;
1.3 ratchov 148:
1.1 ratchov 149: p = malloc(size);
150: if (p == NULL) {
151: log_puts("failed to allocate ");
152: log_putx(size);
153: log_puts(" bytes\n");
154: panic();
155: }
156: return p;
157: }
158:
159: /*
160: * xmalloc-style strdup(3)
161: */
162: char *
163: xstrdup(char *s)
164: {
165: size_t size;
166: void *p;
167:
168: size = strlen(s) + 1;
169: p = xmalloc(size);
170: memcpy(p, s, size);
171: return p;
172: }