Annotation of embedaddon/sudo/common/fatal.c, revision 1.1.1.2
1.1 misho 1: /*
2: * Copyright (c) 2004-2005, 2010-2013 Todd C. Miller <Todd.Miller@courtesan.com>
3: *
4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
7: *
8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15: */
16:
17: #include <config.h>
18:
19: #include <sys/types.h>
20:
21: #include <errno.h>
22: #include <stdio.h>
23: #include <stdlib.h>
24: #include <string.h>
25: #ifdef HAVE_STDBOOL_H
26: # include <stdbool.h>
27: #else
28: # include "compat/stdbool.h"
29: #endif /* HAVE_STDBOOL_H */
30:
1.1.1.2 ! misho 31: #define DEFAULT_TEXT_DOMAIN "sudo"
! 32: #include "gettext.h" /* must be included before missing.h */
! 33:
1.1 misho 34: #include "missing.h"
35: #include "alloc.h"
36: #include "fatal.h"
1.1.1.2 ! misho 37: #include "queue.h"
1.1 misho 38: #include "sudo_plugin.h"
39:
1.1.1.2 ! misho 40: struct sudo_fatal_callback {
! 41: SLIST_ENTRY(sudo_fatal_callback) entries;
! 42: void (*func)(void);
! 43: };
! 44: SLIST_HEAD(sudo_fatal_callback_list, sudo_fatal_callback);
1.1 misho 45:
46: sigjmp_buf fatal_jmp;
47: static bool setjmp_enabled = false;
1.1.1.2 ! misho 48: static struct sudo_fatal_callback_list callbacks;
1.1 misho 49:
50: static void _warning(int, const char *, va_list);
51:
52: static void
53: do_cleanup(void)
54: {
55: struct sudo_fatal_callback *cb;
56:
57: /* Run callbacks, removing them from the list as we go. */
1.1.1.2 ! misho 58: while ((cb = SLIST_FIRST(&callbacks)) != NULL) {
! 59: SLIST_REMOVE_HEAD(&callbacks, entries);
1.1 misho 60: cb->func();
61: free(cb);
62: }
63: }
64:
65: void
1.1.1.2 ! misho 66: fatal_nodebug(const char *fmt, ...)
1.1 misho 67: {
68: va_list ap;
69:
70: va_start(ap, fmt);
71: _warning(1, fmt, ap);
72: va_end(ap);
73: do_cleanup();
74: if (setjmp_enabled)
75: siglongjmp(fatal_jmp, 1);
76: else
77: exit(EXIT_FAILURE);
78: }
79:
80: void
1.1.1.2 ! misho 81: fatalx_nodebug(const char *fmt, ...)
1.1 misho 82: {
83: va_list ap;
84:
85: va_start(ap, fmt);
86: _warning(0, fmt, ap);
87: va_end(ap);
88: do_cleanup();
89: if (setjmp_enabled)
90: siglongjmp(fatal_jmp, 1);
91: else
92: exit(EXIT_FAILURE);
93: }
94:
95: void
1.1.1.2 ! misho 96: vfatal_nodebug(const char *fmt, va_list ap)
1.1 misho 97: {
98: _warning(1, fmt, ap);
99: do_cleanup();
100: if (setjmp_enabled)
101: siglongjmp(fatal_jmp, 1);
102: else
103: exit(EXIT_FAILURE);
104: }
105:
106: void
1.1.1.2 ! misho 107: vfatalx_nodebug(const char *fmt, va_list ap)
1.1 misho 108: {
109: _warning(0, fmt, ap);
110: do_cleanup();
111: if (setjmp_enabled)
112: siglongjmp(fatal_jmp, 1);
113: else
114: exit(EXIT_FAILURE);
115: }
116:
117: void
1.1.1.2 ! misho 118: warning_nodebug(const char *fmt, ...)
1.1 misho 119: {
120: va_list ap;
121:
122: va_start(ap, fmt);
123: _warning(1, fmt, ap);
124: va_end(ap);
125: }
126:
127: void
1.1.1.2 ! misho 128: warningx_nodebug(const char *fmt, ...)
1.1 misho 129: {
130: va_list ap;
131: va_start(ap, fmt);
132: _warning(0, fmt, ap);
133: va_end(ap);
134: }
135:
136: void
1.1.1.2 ! misho 137: vwarning_nodebug(const char *fmt, va_list ap)
1.1 misho 138: {
139: _warning(1, fmt, ap);
140: }
141:
142: void
1.1.1.2 ! misho 143: vwarningx_nodebug(const char *fmt, va_list ap)
1.1 misho 144: {
145: _warning(0, fmt, ap);
146: }
147:
148: static void
149: _warning(int use_errno, const char *fmt, va_list ap)
150: {
151: int serrno = errno;
152: char *str;
153:
154: evasprintf(&str, fmt, ap);
155: if (use_errno) {
156: if (fmt != NULL) {
157: sudo_printf(SUDO_CONV_ERROR_MSG,
158: _("%s: %s: %s\n"), getprogname(), str, strerror(serrno));
159: } else {
160: sudo_printf(SUDO_CONV_ERROR_MSG,
161: _("%s: %s\n"), getprogname(), strerror(serrno));
162: }
163: } else {
164: sudo_printf(SUDO_CONV_ERROR_MSG,
165: _("%s: %s\n"), getprogname(), str ? str : "(null)");
166: }
167: efree(str);
168: errno = serrno;
169: }
170:
171: int
172: fatal_callback_register(void (*func)(void))
173: {
174: struct sudo_fatal_callback *cb;
175:
176: cb = malloc(sizeof(*cb));
177: if (cb == NULL)
178: return -1;
179: cb->func = func;
1.1.1.2 ! misho 180: SLIST_INSERT_HEAD(&callbacks, cb, entries);
1.1 misho 181:
182: return 0;
183: }
184:
185: void
186: fatal_disable_setjmp(void)
187: {
188: setjmp_enabled = false;
189: }
190:
191: void
192: fatal_enable_setjmp(void)
193: {
194: setjmp_enabled = true;
195: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>