set handlers patch

Havoc Pennington hp at redhat.com
Tue Nov 14 22:11:47 PST 2006


Attached is an API patch (you'll notice the implementation is empty) to 
add dbus_set_log_handler() and dbus_set_bug_handler().

The primary purpose of dbus_set_log_handler() is to allow the bus daemon 
to use syslog() instead of printing to stderr.

The primary purpose of dbus_set_bug_handler() is to allow apps with 
special needs to hook into failed checks and control the behavior to the 
extent possible.

Havoc
-------------- next part --------------
Index: dbus/dbus-errors.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-errors.c,v
retrieving revision 1.32
diff -u -p -r1.32 dbus-errors.c
--- dbus/dbus-errors.c	21 Oct 2006 17:08:08 -0000	1.32
+++ dbus/dbus-errors.c	15 Nov 2006 06:03:53 -0000
@@ -145,7 +145,25 @@ message_from_error (const char *error)
  * warnings, exit on a failed assertion, or even crash in those cases
  * (in other words, incorrect use of the API results in undefined
  * behavior, possibly accompanied by helpful debugging output if
- * you're lucky).
+ * you're lucky). See dbus_set_bug_handler() for more details.
+ *
+ * Functions have a #DBusError parameter only if they can report
+ * multiple different errors that need to be distinguished.  Some
+ * functions can report zero errors (they always succeed), while
+ * others have only one possible error (usually "insufficient
+ * memory").  If a function has only one possible error it may simply
+ * return #FALSE or #NULL to indicate that the error occurred, and not
+ * bother with #DBusError. See the documentation for each specific
+ * function for more.
+ *
+ * #DBusError may be set from a message of type
+ * #DBUS_MESSAGE_TYPE_ERROR received from another application. In
+ * these cases, you should not make any assumptions about the
+ * content of error names and messages, other than those guaranteed
+ * by the D-Bus protocol (for example, the protocol guarantees
+ * valid UTF-8). 
+ * dbus_connection_send_with_reply_and_block() is one example
+ * of a function that gets its error from a remote application.
  * 
  * @{
  */
Index: dbus/dbus-misc.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-misc.c,v
retrieving revision 1.2
diff -u -p -r1.2 dbus-misc.c
--- dbus/dbus-misc.c	15 Nov 2006 03:07:59 -0000	1.2
+++ dbus/dbus-misc.c	15 Nov 2006 06:03:53 -0000
@@ -27,6 +27,28 @@
 #include "dbus-string.h"
 
 /**
+ * @defgroup DBusMiscInternals Miscellaneous internal API
+ * @ingroup DBusInternals
+ * @brief Miscellaneous API implementation details
+ *@{ 
+ */
+
+typedef struct {
+  DBusLogHandlerFunction func; /**< the handler */
+  void *data;                  /**< handler data */
+  DBusFreeFunction free_func;  /**< free handler data */
+} DBusLogHandler;
+
+
+static DBusLogHandler _dbus_log_handler_bug;
+static DBusLogHandler _dbus_log_handler_warning;
+static DBusLogHandler _dbus_log_handler_verbose;
+
+/** @} */ /* End of internals */
+
+
+
+/**
  * @defgroup DBusMisc Miscellaneous
  * @ingroup  DBus
  * @brief Miscellaneous API that doesn't cleanly fit anywhere else
@@ -35,6 +57,134 @@
  */
 
 /**
+ * Sets a handler function for printing messages.
+ * 
+ * libdbus can print several kinds of message, each kind has a log level.
+ * 
+ * Each log level may have a handler replacing the default dbus
+ * handler for that log level. The default handler prints the message
+ * to the console (stdout or stderr).
+ *
+ * See the documentation on each level in the #DBusLogLevel enum
+ * documentation.
+ *
+ * A typical use of this function is to use syslog() instead of
+ * printing to the console.
+ *
+ * @note When implementing this function, remember that the message passed
+ * to your log handler is <em>NOT</em> a format string. So for
+ * example, you want to write syslog("%s", message) rather than
+ * syslog(message).
+ *
+ * @since 1.2
+ * 
+ * @param level log level to set the function for
+ * @param func function to be invoked to handle log messages, or #NULL to restore the default
+ * @param func_data data to pass to the function
+ * @param free_data_func function used to free the data if a new log handler is set at the same level or dbus_shutdown() is invoked
+ * 
+ * 
+ */
+void
+dbus_set_log_handler (DBusLogLevel            level,
+                      DBusLogHandlerFunction  func,
+                      void                   *func_data,
+                      DBusFreeFunction        free_data_func)
+{
+  
+
+}
+
+/**
+ * Sets a function to be called when libdbus detects an application
+ * bug.
+ * 
+ * The bug handler function is called when libdbus detects that the
+ * application programmer is using libdbus in an undefined way. The
+ * most common bug detected by libdbus is that a passed-in pointer is
+ * #NULL when it is not allowed to be #NULL according to the
+ * documented ABI contract. However, there are a number of others bugs
+ * libdbus checks for.
+ *
+ * The bug handler can do anything you like, and then returns a value
+ * telling libdbus what further action to take. See the documentation
+ * for each value in the #DBusBugHandlingAction enum for more.
+ *
+ * Most applications should not set a bug handler, or at least should
+ * return #DBUS_BUG_ACTION_LEAVE_DEFAULT to use the default bug
+ * handling behavior.  For example, distributions may set
+ * DBUS_FATAL_WARNINGS=1 to make bugs fatal during a beta test cycle
+ * and then set DBUS_FATAL_WARNINGS=0 to make bugs nonfatal in
+ * production releases. Applications that don't honor this setting may
+ * be considered antisocial unless they are special in some way.
+ * 
+ * There are few semantic guarantees surrounding bug handling. libdbus
+ * often will not be able to recover gracefully after a bug is
+ * detected; you should think of a detected bug much as you would
+ * think of a segmentation fault or illegal memory access.
+ *
+ * If you continue after a bug is reported, most likely some expected
+ * function was not performed; this may cause a cascading effect of
+ * additional bugs or crashes, in libdbus or in your application.
+ *
+ * libdbus behavior after reporting a bug is completely undefined.
+ * Remember that memory may be corrupted, data structures may be
+ * inconsistent, or a function may have behaved unexpectedly.  If you
+ * ask libdbus to ignore a bug, your program may be able to continue,
+ * or it may not.
+ *
+ * Ignoring bugs is strongly discouraged in security-sensitive
+ * applications or daemons; you do not want a security-sensitive
+ * program to continue in a confused or unknown state.
+ * #DBUS_BUG_ACTION_FORCE_LOG_AND_ABORT is advisable in secure
+ * daemons. Of course, it's also advisable to avoid having bugs in
+ * these daemons in the first place, so be careful.
+ * 
+ * There are no guarantees that bugs will be detected; libdbus can be
+ * compiled with "checks" disabled, which will mean it does not check
+ * for application bugs. Also, no specific bug checks are guaranteed
+ * to exist, since there may be performance or other reasons to omit
+ * certain checks. The checks that exist may change over time. They
+ * are not considered part of the ABI contract.
+ *
+ * The behavior of #DBUS_BUG_ACTION_LEAVE_DEFAULT is not defined by the
+ * ABI contract. Right now it varies based on the DBUS_FATAL_WARNINGS
+ * environment variable but this is not guaranteed.
+ *
+ * If you ask libdbus to log the bug, it may call the log handler
+ * at level #DBUS_LOG_LEVEL_BUG multiple times to log a multi-line
+ * problem. So if you want to do something once per bug, do it
+ * in the bug handler, not the log handler.
+ *
+ * @note <em>libdbus bug checks will never be triggered for error conditions
+ * outside of the application author's control.</em> Recoverable
+ * errors are reported to the caller of the function as documented for
+ * that function. See #DBusError for some more details on recoverable
+ * error conditions.
+ *
+ * @note Again: any time the bug handler function is invoked, it is a bug
+ * that you can fix, and the bug most likely has serious or
+ * potentially serious consequences. This is a <em>bug</em> handler,
+ * not an error handler. In a correct application, the bug handler
+ * will never be used. That's why it's called the bug handler.
+ *
+ * @since 1.2
+ * 
+ * @param func function to be invoked to handle bugs, or #NULL to restore the default
+ * @param func_data data to pass to the function
+ * @param free_data_func function used to free the data if a new bug handler is set or dbus_shutdown() is invoked
+ * 
+ */
+void
+dbus_set_bug_handler (DBusBugHandlerFunction  func,
+                      void                   *func_data,
+                      DBusFreeFunction        free_data_func)
+{
+  
+
+}
+
+/**
  * Obtains the machine UUID of the machine this process is running on.
  *
  * The returned string must be freed with dbus_free().
Index: dbus/dbus-misc.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-misc.h,v
retrieving revision 1.2
diff -u -p -r1.2 dbus-misc.h
--- dbus/dbus-misc.h	15 Nov 2006 03:07:59 -0000	1.2
+++ dbus/dbus-misc.h	15 Nov 2006 06:03:53 -0000
@@ -29,6 +29,7 @@
 
 #include <dbus/dbus-types.h>
 #include <dbus/dbus-errors.h>
+#include <dbus/dbus-memory.h>
 
 DBUS_BEGIN_DECLS
 
@@ -37,8 +38,101 @@ DBUS_BEGIN_DECLS
  * @{
  */
 
-char*       dbus_get_local_machine_id              (void);
+/** Distinguishes kinds of log message. */
+typedef enum {
+  DBUS_LOG_LEVEL_BUG,     /**< Used to log bugs. Handler called only if the
+                           * #DBusBugHandlerFunction indicates that
+                           * the bug should be logged. Only called
+                           * if libdbus was compiled with "checks" enabled.
+                           * @since 1.2
+                           */
+  DBUS_LOG_LEVEL_WARNING, /**< Used to log warnings (there are very few of these,
+                           * they occur when a something goes horribly
+                           * wrong and it's not a defined recoverable
+                           * error returned by the API and it's not a
+                           * programming mistake on anyone's part).
+                           * @since 1.2
+                           */
+  DBUS_LOG_LEVEL_VERBOSE  /**< Used to log "debug spew" only if libdbus
+                           * was compiled with verbose mode available and
+                           * verbose mode is currently enabled via
+                           * environment variable or other configuration.
+                           * @since 1.2
+                           */
+} DBusLogLevel;
+
+/** Returned by the #DBusBugHandlerFunction to indicate what libdbus should do next. */
+typedef enum {
+  DBUS_BUG_ACTION_LEAVE_DEFAULT,         /**< Most bug handlers should
+                                          * return this value, which
+                                          * indicates that the default
+                                          * action should be taken;
+                                          * the default action may be
+                                          * controlled by environment
+                                          * variables, config files,
+                                          * or compile-time options.
+                                          * The default action is not
+                                          * guaranteed by the ABI
+                                          * contract, but right now is
+                                          * to log the bug and then
+                                          * optionally exit depending
+                                          * on the DBUS_FATAL_WARNINGS
+                                          * environment variable.
+                                          * @since 1.2
+                                          */
+  DBUS_BUG_ACTION_FORCE_LOG_AND_ABORT,   /**< Force libdbus to call
+                                          * the log handler at level
+                                          * #DBUS_LOG_LEVEL_BUG and
+                                          * then exit the program,
+                                          * regardless of environment
+                                          * variables or
+                                          * configuration. @since 1.2
+                                          */
+  DBUS_BUG_ACTION_FORCE_LOG_AND_IGNORE,  /**< Force libdbus to call
+                                          * the log handler at level
+                                          * #DBUS_LOG_LEVEL_BUG and
+                                          * then do nothing further,
+                                          * regardless of environment
+                                          * variables or
+                                          * configuration.
+                                          *
+                                          * Note that behavior of
+                                          * libdbus is undefined after
+                                          * the bug handler returns;
+                                          * it may well crash,
+                                          * immediately or at a later
+                                          * time. @since 1.2
+                                          */
+  DBUS_BUG_ACTION_FORCE_SILENTLY_IGNORE  /**< Force libdbus to do
+                                          * nothing, regardless of
+                                          * environment variables or
+                                          * configuration. Note that
+                                          * behavior of libdbus is
+                                          * undefined after the bug
+                                          * handler returns; it may
+                                          * well crash, immediately or
+                                          * at a later time. @since 1.2
+                                          */
+} DBusBugHandlingAction;
+
+
+/** Bug handler function, see dbus_set_bug_handler(). @since 1.2 */
+typedef DBusBugHandlingAction (* DBusBugHandlerFunction) (void       *data);
+
+/** Log handler function, see dbus_set_log_handler(). @since 1.2 */
+typedef void                  (* DBusLogHandlerFunction) (const char *message,
+                                                          void       *data);
+
+void dbus_set_log_handler (DBusLogLevel            level,
+                           DBusLogHandlerFunction  func,
+                           void                   *func_data,
+                           DBusFreeFunction        free_data_func);
+void dbus_set_bug_handler (DBusBugHandlerFunction  func,
+                           void                   *func_data,
+                           DBusFreeFunction        free_data_func);
 
+char*       dbus_get_local_machine_id              (void);
+                                  
 /** @} */
 
 DBUS_END_DECLS


More information about the dbus mailing list