File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / common / fatal.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 14 07:56:33 2013 UTC (10 years, 8 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_8p0, v1_8_8, HEAD
v 1.8.8

    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>