X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dbus%2Fdbus-errors.c;h=a0571a50e07d5828e00350e2c23887a6f661deb1;hb=459c9ff1543cfe1f8008af02ce5edcb3942d69de;hp=7e3aa69b81eeb310367f2dfd5b7ea93f7e0a5b80;hpb=ce4fd314c6be9bfee16a172d5ca34e5097d309fc;p=platform%2Fupstream%2Fdbus.git diff --git a/dbus/dbus-errors.c b/dbus/dbus-errors.c index 7e3aa69..a0571a5 100644 --- a/dbus/dbus-errors.c +++ b/dbus/dbus-errors.c @@ -1,10 +1,10 @@ -/* -*- mode: C; c-file-style: "gnu" -*- */ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ /* dbus-errors.c Error reporting * - * Copyright (C) 2002 Red Hat Inc. + * Copyright (C) 2002, 2004 Red Hat Inc. * Copyright (C) 2003 CodeFactory AB * - * Licensed under the Academic Free License version 1.2 + * Licensed under the Academic Free License version 2.1 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,43 +18,56 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ + +#include #include "dbus-errors.h" #include "dbus-internals.h" +#include "dbus-string.h" +#include "dbus-protocol.h" #include -#include #include /** - * @defgroup DBusErrors Error reporting - * @ingroup DBus - * @brief Error reporting + * @defgroup DBusErrorInternals Error reporting internals + * @ingroup DBusInternals + * @brief Error reporting internals + * @{ + */ + +/** + * @def DBUS_ERROR_INIT * - * Types and functions related to reporting errors. + * Expands to a suitable initializer for a DBusError on the stack. + * Declaring a DBusError with: * + * @code + * DBusError error = DBUS_ERROR_INIT; + * + * do_things_with (&error); + * @endcode * - * In essence D-BUS error reporting works as follows: + * is a more concise form of: * * @code - * DBusResultCode result = DBUS_RESULT_SUCCESS; - * dbus_some_function (arg1, arg2, &result); - * if (result != DBUS_RESULT_SUCCESS) - * printf ("an error occurred\n"); - * @endcode + * DBusError error; * - * @todo add docs with DBusError - * - * @{ + * dbus_error_init (&error); + * do_things_with (&error); + * @endcode */ +/** + * Internals of DBusError + */ typedef struct { - const char *name; /**< error name */ + char *name; /**< error name */ char *message; /**< error message */ - unsigned int const_message : 1; /** Message is not owned by DBusError */ + unsigned int const_message : 1; /**< Message is not owned by DBusError */ unsigned int dummy2 : 1; /**< placeholder */ unsigned int dummy3 : 1; /**< placeholder */ @@ -65,6 +78,8 @@ typedef struct } DBusRealError; +_DBUS_STATIC_ASSERT (sizeof (DBusRealError) == sizeof (DBusError)); + /** * Returns a longer message describing an error name. * If the error name is unknown, returns the name @@ -93,7 +108,7 @@ message_from_error (const char *error) else if (strcmp (error, DBUS_ERROR_AUTH_FAILED) == 0) return "Could not authenticate to server"; else if (strcmp (error, DBUS_ERROR_NO_SERVER) == 0) - return "No server"; + return "No server available at address"; else if (strcmp (error, DBUS_ERROR_TIMEOUT) == 0) return "Connection timed out"; else if (strcmp (error, DBUS_ERROR_NO_NETWORK) == 0) @@ -103,19 +118,69 @@ message_from_error (const char *error) else if (strcmp (error, DBUS_ERROR_DISCONNECTED) == 0) return "Disconnected."; else if (strcmp (error, DBUS_ERROR_INVALID_ARGS) == 0) - return "Invalid argumemts."; + return "Invalid arguments."; else if (strcmp (error, DBUS_ERROR_NO_REPLY) == 0) return "Did not get a reply message."; else if (strcmp (error, DBUS_ERROR_FILE_NOT_FOUND) == 0) return "File doesn't exist."; + else if (strcmp (error, DBUS_ERROR_OBJECT_PATH_IN_USE) == 0) + return "Object path already in use"; else return error; } +/** @} */ /* End of internals */ + +/** + * @defgroup DBusErrors Error reporting + * @ingroup DBus + * @brief Error reporting + * + * Types and functions related to reporting errors. + * + * + * In essence D-Bus error reporting works as follows: + * + * @code + * DBusError error; + * dbus_error_init (&error); + * dbus_some_function (arg1, arg2, &error); + * if (dbus_error_is_set (&error)) + * { + * fprintf (stderr, "an error occurred: %s\n", error.message); + * dbus_error_free (&error); + * } + * @endcode + * + * By convention, all functions allow #NULL instead of a DBusError*, + * so callers who don't care about the error can ignore it. + * + * There are some rules. An error passed to a D-Bus function must + * always be unset; you can't pass in an error that's already set. If + * a function has a return code indicating whether an error occurred, + * and also a #DBusError parameter, then the error will always be set + * if and only if the return code indicates an error occurred. i.e. + * the return code and the error are never going to disagree. + * + * An error only needs to be freed if it's been set, not if + * it's merely been initialized. + * + * You can check the specific error that occurred using + * dbus_error_has_name(). + * + * Errors will not be set for programming errors, such as passing + * invalid arguments to the libdbus API. Instead, libdbus will print + * 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). + * + * @{ + */ + /** - * Initializes a DBusError structure. Does not allocate - * any memory; the error only needs to be freed - * if it is set at some point. + * Initializes a DBusError structure. Does not allocate any memory; + * the error only needs to be freed if it is set at some point. * * @param error the DBusError. */ @@ -124,7 +189,7 @@ dbus_error_init (DBusError *error) { DBusRealError *real; - _dbus_assert (error != NULL); + _dbus_return_if_fail (error != NULL); _dbus_assert (sizeof (DBusError) == sizeof (DBusRealError)); @@ -147,20 +212,30 @@ dbus_error_free (DBusError *error) { DBusRealError *real; + _dbus_return_if_fail (error != NULL); + real = (DBusRealError *)error; if (!real->const_message) - dbus_free (real->message); + { + dbus_free (real->name); + dbus_free (real->message); + } dbus_error_init (error); } /** - * Assigns an error name and message to a DBusError. - * Does nothing if error is #NULL. The message may - * be NULL only if the error is DBUS_ERROR_NO_MEMORY. + * Assigns an error name and message to a DBusError. Does nothing if + * error is #NULL. The message may be #NULL, which means a default + * message will be deduced from the name. The default message will be + * totally useless, though, so using a #NULL message is not recommended. * - * @param error the error. + * Because this function does not copy the error name or message, you + * must ensure the name and message are global data that won't be + * freed. You probably want dbus_set_error() instead, in most cases. + * + * @param error the error or #NULL * @param name the error name (not copied!!!) * @param message the error message (not copied!!!) */ @@ -171,20 +246,21 @@ dbus_set_error_const (DBusError *error, { DBusRealError *real; + _dbus_return_if_error_is_set (error); + _dbus_return_if_fail (name != NULL); + if (error == NULL) return; - /* it's a bug to pile up errors */ _dbus_assert (error->name == NULL); _dbus_assert (error->message == NULL); - _dbus_assert (name != NULL); if (message == NULL) message = message_from_error (name); real = (DBusRealError *)error; - real->name = name; + real->name = (char*) name; real->message = (char *)message; real->const_message = TRUE; } @@ -195,7 +271,7 @@ dbus_set_error_const (DBusError *error, * src is reinitialized to an empty error. dest may not * contain an existing error. If the destination is * #NULL, just frees and reinits the source error. - * + * * @param src the source error * @param dest the destination error or #NULL */ @@ -203,7 +279,7 @@ void dbus_move_error (DBusError *src, DBusError *dest) { - _dbus_assert (!dbus_error_is_set (dest)); + _dbus_return_if_error_is_set (dest); if (dest) { @@ -226,8 +302,9 @@ dbus_bool_t dbus_error_has_name (const DBusError *error, const char *name) { - _dbus_assert (error != NULL); - _dbus_assert (name != NULL); + _dbus_return_val_if_fail (error != NULL, FALSE); + _dbus_return_val_if_fail (name != NULL, FALSE); + _dbus_assert ((error->name != NULL && error->message != NULL) || (error->name == NULL && error->message == NULL)); @@ -251,7 +328,7 @@ dbus_error_has_name (const DBusError *error, dbus_bool_t dbus_error_is_set (const DBusError *error) { - _dbus_assert (error != NULL); + _dbus_return_val_if_fail (error != NULL, FALSE); _dbus_assert ((error->name != NULL && error->message != NULL) || (error->name == NULL && error->message == NULL)); return error->name != NULL; @@ -261,16 +338,16 @@ dbus_error_is_set (const DBusError *error) * Assigns an error name and message to a DBusError. * Does nothing if error is #NULL. * - * The format may be NULL only if the error is DBUS_ERROR_NO_MEMORY. + * The format may be #NULL, which means a (pretty much useless) + * default message will be deduced from the name. This is not a good + * idea, just go ahead and provide a useful error message. It won't + * hurt you. * * If no memory can be allocated for the error message, * an out-of-memory error message will be set instead. * - * @todo stdio.h shouldn't be included in this file, - * should write _dbus_string_append_printf instead - * - * @param error the error. - * @param name the error name (not copied!!!) + * @param error the error.or #NULL + * @param name the error name * @param format printf-style format string. */ void @@ -280,44 +357,65 @@ dbus_set_error (DBusError *error, ...) { DBusRealError *real; + DBusString str; va_list args; - int message_length; - char *message; - char c; - + if (error == NULL) return; /* it's a bug to pile up errors */ + _dbus_return_if_error_is_set (error); + _dbus_return_if_fail (name != NULL); + _dbus_assert (error->name == NULL); _dbus_assert (error->message == NULL); - _dbus_assert (name != NULL); - if (format == NULL) - format = message_from_error (name); - - va_start (args, format); - /* Measure the message length */ - message_length = vsnprintf (&c, 1, format, args) + 1; - va_end (args); - - message = dbus_malloc (message_length); + if (!_dbus_string_init (&str)) + goto nomem; - if (!message) + if (format == NULL) { - dbus_set_error_const (error, DBUS_ERROR_NO_MEMORY, NULL); - return; + if (!_dbus_string_append (&str, + message_from_error (name))) + { + _dbus_string_free (&str); + goto nomem; + } + } + else + { + va_start (args, format); + if (!_dbus_string_append_printf_valist (&str, format, args)) + { + _dbus_string_free (&str); + va_end (args); + goto nomem; + } + va_end (args); } - - va_start (args, format); - vsprintf (message, format, args); - va_end (args); real = (DBusRealError *)error; + + if (!_dbus_string_steal_data (&str, &real->message)) + { + _dbus_string_free (&str); + goto nomem; + } + _dbus_string_free (&str); - real->name = name; - real->message = message; + real->name = _dbus_strdup (name); + if (real->name == NULL) + { + dbus_free (real->message); + real->message = NULL; + goto nomem; + } real->const_message = FALSE; + + return; + + nomem: + _DBUS_SET_OOM (error); } -/** @} */ +/** @} */ /* End public API */