Annotation of embedaddon/sudo/common/fatal.c, revision 1.1.1.1

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: 
                     31: #include "missing.h"
                     32: #include "alloc.h"
                     33: #include "fatal.h"
                     34: #include "sudo_plugin.h"
                     35: 
                     36: #define DEFAULT_TEXT_DOMAIN    "sudo"
                     37: #include "gettext.h"
                     38: 
                     39: sigjmp_buf fatal_jmp;
                     40: static bool setjmp_enabled = false;
                     41: static struct sudo_fatal_callback {
                     42:     void (*func)(void);
                     43:     struct sudo_fatal_callback *next;
                     44: } *callbacks;
                     45: 
                     46: static void _warning(int, const char *, va_list);
                     47: 
                     48: static void
                     49: do_cleanup(void)
                     50: {
                     51:     struct sudo_fatal_callback *cb;
                     52: 
                     53:     /* Run callbacks, removing them from the list as we go. */
                     54:     while ((cb = callbacks) != NULL) {
                     55:        callbacks = cb->next;
                     56:        cb->func();
                     57:        free(cb);
                     58:     }
                     59: }
                     60: 
                     61: void
                     62: fatal2(const char *fmt, ...)
                     63: {
                     64:     va_list ap;
                     65: 
                     66:     va_start(ap, fmt);
                     67:     _warning(1, fmt, ap);
                     68:     va_end(ap);
                     69:     do_cleanup();
                     70:     if (setjmp_enabled)
                     71:        siglongjmp(fatal_jmp, 1);
                     72:     else
                     73:        exit(EXIT_FAILURE);
                     74: }
                     75: 
                     76: void
                     77: fatalx2(const char *fmt, ...)
                     78: {
                     79:     va_list ap;
                     80: 
                     81:     va_start(ap, fmt);
                     82:     _warning(0, fmt, ap);
                     83:     va_end(ap);
                     84:     do_cleanup();
                     85:     if (setjmp_enabled)
                     86:        siglongjmp(fatal_jmp, 1);
                     87:     else
                     88:        exit(EXIT_FAILURE);
                     89: }
                     90: 
                     91: void
                     92: vfatal2(const char *fmt, va_list ap)
                     93: {
                     94:     _warning(1, fmt, ap);
                     95:     do_cleanup();
                     96:     if (setjmp_enabled)
                     97:        siglongjmp(fatal_jmp, 1);
                     98:     else
                     99:        exit(EXIT_FAILURE);
                    100: }
                    101: 
                    102: void
                    103: vfatalx2(const char *fmt, va_list ap)
                    104: {
                    105:     _warning(0, fmt, ap);
                    106:     do_cleanup();
                    107:     if (setjmp_enabled)
                    108:        siglongjmp(fatal_jmp, 1);
                    109:     else
                    110:        exit(EXIT_FAILURE);
                    111: }
                    112: 
                    113: void
                    114: warning2(const char *fmt, ...)
                    115: {
                    116:     va_list ap;
                    117: 
                    118:     va_start(ap, fmt);
                    119:     _warning(1, fmt, ap);
                    120:     va_end(ap);
                    121: }
                    122: 
                    123: void
                    124: warningx2(const char *fmt, ...)
                    125: {
                    126:     va_list ap;
                    127:     va_start(ap, fmt);
                    128:     _warning(0, fmt, ap);
                    129:     va_end(ap);
                    130: }
                    131: 
                    132: void
                    133: vwarning2(const char *fmt, va_list ap)
                    134: {
                    135:     _warning(1, fmt, ap);
                    136: }
                    137: 
                    138: void
                    139: vwarningx2(const char *fmt, va_list ap)
                    140: {
                    141:     _warning(0, fmt, ap);
                    142: }
                    143: 
                    144: static void
                    145: _warning(int use_errno, const char *fmt, va_list ap)
                    146: {
                    147:     int serrno = errno;
                    148:     char *str;
                    149: 
                    150:     evasprintf(&str, fmt, ap);
                    151:     if (use_errno) {
                    152:        if (fmt != NULL) {
                    153:            sudo_printf(SUDO_CONV_ERROR_MSG,
                    154:                _("%s: %s: %s\n"), getprogname(), str, strerror(serrno));
                    155:        } else {
                    156:            sudo_printf(SUDO_CONV_ERROR_MSG,
                    157:                _("%s: %s\n"), getprogname(), strerror(serrno));
                    158:        }
                    159:     } else {
                    160:        sudo_printf(SUDO_CONV_ERROR_MSG,
                    161:            _("%s: %s\n"), getprogname(), str ? str : "(null)");
                    162:     }
                    163:     efree(str);
                    164:     errno = serrno;
                    165: }
                    166: 
                    167: int
                    168: fatal_callback_register(void (*func)(void))
                    169: {
                    170:     struct sudo_fatal_callback *cb;
                    171: 
                    172:     cb = malloc(sizeof(*cb));
                    173:     if (cb == NULL)
                    174:        return -1;
                    175:     cb->func = func;
                    176:     cb->next = callbacks;
                    177:     callbacks = cb;
                    178: 
                    179:     return 0;
                    180: }
                    181: 
                    182: void
                    183: fatal_disable_setjmp(void)
                    184: {
                    185:     setjmp_enabled = false;
                    186: }
                    187: 
                    188: void
                    189: fatal_enable_setjmp(void)
                    190: {
                    191:     setjmp_enabled = true;
                    192: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>