Annotation of embedaddon/sudo/common/error.c, revision 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 "error.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>