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>