From ee4cc41fafaac0a2d76c1c791f6d43a6b6d937a7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 16 Aug 2005 01:29:28 +0000 Subject: * start implementing error handling in avahi-client * doxygen document timeval.h * add two more AVAHI_GCC_SENTINELs git-svn-id: file:///home/lennart/svn/public/avahi/trunk@350 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-client/browser.c | 18 +++--- avahi-client/client-test.c | 13 +++- avahi-client/client.c | 147 ++++++++++++++++++++++++++++++--------------- avahi-client/client.h | 16 ++--- avahi-client/entrygroup.c | 4 +- avahi-client/internal.h | 13 ++-- 6 files changed, 134 insertions(+), 77 deletions(-) (limited to 'avahi-client') diff --git a/avahi-client/browser.c b/avahi-client/browser.c index 01608d0..dfc70f1 100644 --- a/avahi-client/browser.c +++ b/avahi-client/browser.c @@ -40,7 +40,7 @@ /* AvahiDomainBrowser */ -AvahiDomainBrowser* avahi_domain_browser_new (AvahiClient *client, AvahiIfIndex interface, AvahiProtocol protocol, const char *domain, AvahiDomainBrowserType btype, AvahiDomainBrowserCallback callback, void *user_data) +AvahiDomainBrowser* avahi_domain_browser_new (AvahiClient *client, AvahiIfIndex interface, AvahiProtocol protocol, const char *domain, AvahiDomainBrowserType btype, AvahiDomainBrowserCallback callback, void *userdata) { AvahiDomainBrowser *tmp = NULL; DBusMessage *message = NULL, *reply; @@ -72,7 +72,7 @@ AvahiDomainBrowser* avahi_domain_browser_new (AvahiClient *client, AvahiIfIndex tmp = avahi_new (AvahiDomainBrowser, 1); tmp->client = client; tmp->callback = callback; - tmp->user_data = user_data; + tmp->userdata = userdata; tmp->path = strdup (path); AVAHI_LLIST_PREPEND(AvahiDomainBrowser, domain_browsers, client->domain_browsers, tmp); @@ -150,7 +150,7 @@ avahi_domain_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusMe if (dbus_error_is_set (&error)) goto out; - db->callback (db, interface, protocol, event, domain, db->user_data); + db->callback (db, interface, protocol, event, domain, db->userdata); return DBUS_HANDLER_RESULT_HANDLED; @@ -160,7 +160,7 @@ out: } /* AvahiServiceTypeBrowser */ -AvahiServiceTypeBrowser* avahi_service_type_browser_new (AvahiClient *client, AvahiIfIndex interface, AvahiProtocol protocol, const char *domain, AvahiServiceTypeBrowserCallback callback, void *user_data) +AvahiServiceTypeBrowser* avahi_service_type_browser_new (AvahiClient *client, AvahiIfIndex interface, AvahiProtocol protocol, const char *domain, AvahiServiceTypeBrowserCallback callback, void *userdata) { AvahiServiceTypeBrowser *tmp = NULL; DBusMessage *message = NULL, *reply; @@ -194,7 +194,7 @@ AvahiServiceTypeBrowser* avahi_service_type_browser_new (AvahiClient *client, Av tmp = avahi_new(AvahiServiceTypeBrowser, 1); tmp->client = client; tmp->callback = callback; - tmp->user_data = user_data; + tmp->userdata = userdata; tmp->path = strdup (path); AVAHI_LLIST_PREPEND(AvahiServiceTypeBrowser, service_type_browsers, client->service_type_browsers, tmp); @@ -276,7 +276,7 @@ avahi_service_type_browser_event (AvahiClient *client, AvahiBrowserEvent event, if (dbus_error_is_set (&error)) goto out; - db->callback (db, interface, protocol, event, type, domain, db->user_data); + db->callback (db, interface, protocol, event, type, domain, db->userdata); return DBUS_HANDLER_RESULT_HANDLED; @@ -287,7 +287,7 @@ out: /* AvahiServiceBrowser */ -AvahiServiceBrowser* avahi_service_browser_new (AvahiClient *client, AvahiIfIndex interface, AvahiProtocol protocol, const char *type, const char *domain, AvahiServiceBrowserCallback callback, void *user_data) +AvahiServiceBrowser* avahi_service_browser_new (AvahiClient *client, AvahiIfIndex interface, AvahiProtocol protocol, const char *type, const char *domain, AvahiServiceBrowserCallback callback, void *userdata) { AvahiServiceBrowser *tmp = NULL; DBusMessage *message = NULL, *reply; @@ -324,7 +324,7 @@ AvahiServiceBrowser* avahi_service_browser_new (AvahiClient *client, AvahiIfInde tmp = avahi_new(AvahiServiceBrowser, 1); tmp->client = client; tmp->callback = callback; - tmp->user_data = user_data; + tmp->userdata = userdata; tmp->path = strdup (path); AVAHI_LLIST_PREPEND(AvahiServiceBrowser, service_browsers, client->service_browsers, tmp); @@ -407,7 +407,7 @@ avahi_service_browser_event (AvahiClient *client, AvahiBrowserEvent event, DBusM if (dbus_error_is_set (&error)) goto out; - db->callback (db, interface, protocol, event, name, type, domain, db->user_data); + db->callback (db, interface, protocol, event, name, type, domain, db->userdata); return DBUS_HANDLER_RESULT_HANDLED; diff --git a/avahi-client/client-test.c b/avahi-client/client-test.c index 11bc4f2..f8f81af 100644 --- a/avahi-client/client-test.c +++ b/avahi-client/client-test.c @@ -87,12 +87,16 @@ main (int argc, char *argv[]) AvahiServiceTypeBrowser *st; AvahiSimplePoll *simple_poll; char *ret; + int error; struct timeval tv; simple_poll = avahi_simple_poll_new(); poll_api = avahi_simple_poll_get(simple_poll); - avahi = avahi_client_new(poll_api, avahi_client_callback, "omghai2u"); + if (!(avahi = avahi_client_new(poll_api, avahi_client_callback, "omghai2u", &error))) { + fprintf(stderr, "Client failed: %s\n", avahi_strerror(error)); + goto fail; + } assert (avahi != NULL); @@ -155,10 +159,13 @@ main (int argc, char *argv[]) if (avahi_simple_poll_iterate(simple_poll, -1) != 0) break; +fail: - avahi_simple_poll_free(simple_poll); + if (simple_poll) + avahi_simple_poll_free(simple_poll); - avahi_free (avahi); + if (avahi) + avahi_free (avahi); return 0; } diff --git a/avahi-client/client.c b/avahi-client/client.c index fcb4921..e99956a 100644 --- a/avahi-client/client.c +++ b/avahi-client/client.c @@ -43,20 +43,23 @@ int avahi_client_set_errno (AvahiClient *client, int error) { - if (client == NULL) return error; + assert(client); client->error = error; return error; } -static -void avahi_client_state_change (AvahiClient *client, int state) -{ - if (client == NULL || client->callback == NULL) +static void avahi_client_set_state (AvahiClient *client, AvahiServerState state) { + assert(state); + + if (client->state == state) return; - client->callback (client, state, client->user_data); + client->state = state; + + if (client->callback) + client->callback (client, state, client->userdata); } static void @@ -80,7 +83,7 @@ avahi_client_state_request_callback (DBusPendingCall *call, void *data) if (dbus_error_is_set (&error)) return; - avahi_client_state_change (client, state); + avahi_client_set_state (client, state); } else if (type == DBUS_MESSAGE_TYPE_ERROR) { dbus_set_error_from_message (&error, reply); } @@ -94,6 +97,10 @@ avahi_client_schedule_state_request (AvahiClient *client) DBusMessage *message; DBusPendingCall *pcall; + /*** Lennart says that this can't happen this way since it will + * never be called if no main loop is used. This call has to + * happen synchronously */ + if (client == NULL) return; message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "GetState"); @@ -128,9 +135,9 @@ filter_func (DBusConnection *bus, DBusMessage *message, void *data) if (strcmp (name, AVAHI_DBUS_NAME) == 0) { if (old == NULL && new != NULL) { - avahi_client_state_change (client, AVAHI_CLIENT_RECONNECTED); + avahi_client_set_state (client, AVAHI_CLIENT_RECONNECTED); } else if (old != NULL && new == NULL) { - avahi_client_state_change (client, AVAHI_CLIENT_DISCONNECTED); + avahi_client_set_state (client, AVAHI_CLIENT_DISCONNECTED); /* XXX: we really need to expire all entry groups */ } } @@ -153,8 +160,6 @@ filter_func (DBusConnection *bus, DBusMessage *message, void *data) if (group != NULL) { int state; - DBusError error; - dbus_error_init (&error); dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &state, DBUS_TYPE_INVALID); if (dbus_error_is_set (&error)) goto out; @@ -181,74 +186,116 @@ out: return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } +static int translate_dbus_error(const DBusError *error) { + assert(error); + + /*** FIXME! Some more eloquent error translation should happen here */ + + return AVAHI_ERR_DBUS_ERROR; +} + AvahiClient * -avahi_client_new (const AvahiPoll *poll_api, AvahiClientCallback callback, void *user_data) +avahi_client_new (const AvahiPoll *poll_api, AvahiClientCallback callback, void *userdata, int *ret_error) { - AvahiClient *tmp = NULL; + AvahiClient *client = NULL; DBusError error; dbus_error_init (&error); - if (!(tmp = avahi_new(AvahiClient, 1))) + if (!(client = avahi_new(AvahiClient, 1))) { + if (ret_error) + *ret_error = AVAHI_ERR_NO_MEMORY; goto fail; + } - AVAHI_LLIST_HEAD_INIT(AvahiEntryGroup, tmp->groups); - AVAHI_LLIST_HEAD_INIT(AvahiDomainBrowser, tmp->domain_browsers); - AVAHI_LLIST_HEAD_INIT(AvahiServiceBrowser, tmp->service_browsers); - AVAHI_LLIST_HEAD_INIT(AvahiServiceTypeBrowser, tmp->service_type_browsers); - - tmp->poll_api = poll_api; - tmp->bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + client->poll_api = poll_api; + client->error = AVAHI_OK; + client->callback = callback; + client->userdata = userdata; + client->state = AVAHI_SERVER_INVALID; + + AVAHI_LLIST_HEAD_INIT(AvahiEntryGroup, client->groups); + AVAHI_LLIST_HEAD_INIT(AvahiDomainBrowser, client->domain_browsers); + AVAHI_LLIST_HEAD_INIT(AvahiServiceBrowser, client->service_browsers); + AVAHI_LLIST_HEAD_INIT(AvahiServiceTypeBrowser, client->service_type_browsers); + client->bus = dbus_bus_get(DBUS_BUS_SYSTEM, &error); if (dbus_error_is_set (&error)) { + if (ret_error) + *ret_error = translate_dbus_error(&error); goto fail; } -/* dbus_connection_setup_with_g_main (tmp->bus, NULL); */ -/* dbus_connection_set_exit_on_disconnect (tmp->bus, FALSE); */ - - if (avahi_dbus_connection_glue(tmp->bus, poll_api) < 0) + if (avahi_dbus_connection_glue(client->bus, poll_api) < 0) { + if (ret_error) + *ret_error = AVAHI_ERR_NO_MEMORY; /* Not optimal */ goto fail; + } - if (!dbus_connection_add_filter (tmp->bus, filter_func, tmp, NULL)) - { + if (!dbus_connection_add_filter (client->bus, filter_func, client, NULL)) { + if (ret_error) + *ret_error = AVAHI_ERR_NO_MEMORY; goto fail; } + + dbus_bus_add_match( + client->bus, + "type='signal', " + "interface='" AVAHI_DBUS_INTERFACE_SERVER "', " + "sender='" AVAHI_DBUS_NAME "', " + "path='" AVAHI_DBUS_PATH_SERVER "'", + &error); - dbus_bus_add_match (tmp->bus, - "type='signal', " - "interface='" AVAHI_DBUS_INTERFACE_SERVER "', " - "sender='" AVAHI_DBUS_NAME "', " - "path='" AVAHI_DBUS_PATH_SERVER "'", - &error); - - if (dbus_error_is_set (&error)) - { + if (dbus_error_is_set (&error)) { + if (ret_error) + *ret_error = translate_dbus_error(&error); goto fail; } - dbus_bus_add_match (tmp->bus, - "type='signal', " - "interface='" DBUS_INTERFACE_DBUS "', " - "sender='" DBUS_SERVICE_DBUS "', " - "path='" DBUS_PATH_DBUS "'", - &error); + dbus_bus_add_match ( + client->bus, + "type='signal', " + "interface='" DBUS_INTERFACE_DBUS "', " + "sender='" DBUS_SERVICE_DBUS "', " + "path='" DBUS_PATH_DBUS "'", + &error); - if (dbus_error_is_set (&error)) - { + if (dbus_error_is_set (&error)) { + if (ret_error) + *ret_error = translate_dbus_error(&error); goto fail; } - tmp->callback = callback; - tmp->user_data = user_data; + if (!(dbus_bus_name_has_owner(client->bus, AVAHI_DBUS_NAME, &error))) { - avahi_client_schedule_state_request (tmp); + if (dbus_error_is_set (&error)) { + if (ret_error) + *ret_error = translate_dbus_error(&error); + goto fail; + } + + if (ret_error) + *ret_error = AVAHI_ERR_NO_DAEMON; + goto fail; + } + + /* This can't happen asynchronously, since it is not guaranteed that a main loop is used */ + + /*client_get_server_state (client);*/ - avahi_client_set_errno (tmp, AVAHI_OK); - return tmp; + return client; fail: - avahi_free (tmp); + + if (client) { + + if (client->bus) { + dbus_connection_disconnect(client->bus); + dbus_connection_unref(client->bus); + } + + avahi_free(client); + } if (dbus_error_is_set(&error)) dbus_error_free(&error); diff --git a/avahi-client/client.h b/avahi-client/client.h index de6f207..99f27dd 100644 --- a/avahi-client/client.h +++ b/avahi-client/client.h @@ -59,16 +59,16 @@ typedef void (*AvahiClientCallback) (AvahiClient *s, AvahiClientState state, voi typedef void (*AvahiEntryGroupCallback) (AvahiEntryGroup *g, AvahiEntryGroupState state, void* userdata); /** The function prototype for the callback of an AvahiDomainBrowser */ -typedef void (*AvahiDomainBrowserCallback) (AvahiDomainBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *domain, void *user_data); +typedef void (*AvahiDomainBrowserCallback) (AvahiDomainBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *domain, void *userdata); /** The function prototype for the callback of an AvahiServiceBrowser */ -typedef void (*AvahiServiceBrowserCallback) (AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, void *user_data); +typedef void (*AvahiServiceBrowserCallback) (AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, void *userdata); /** The function prototype for the callback of an AvahiServiceTypeBrowser */ -typedef void (*AvahiServiceTypeBrowserCallback) (AvahiServiceTypeBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *type, const char *domain, void *user_data); +typedef void (*AvahiServiceTypeBrowserCallback) (AvahiServiceTypeBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *type, const char *domain, void *userdata); /** Creates a new client instance */ -AvahiClient* avahi_client_new (const AvahiPoll *poll_api, AvahiClientCallback callback, void *user_data); +AvahiClient* avahi_client_new (const AvahiPoll *poll_api, AvahiClientCallback callback, void *userdata, int *error); /** Get the version of the server */ char* avahi_client_get_version_string (AvahiClient*); @@ -83,7 +83,7 @@ char* avahi_client_get_domain_name (AvahiClient*); char* avahi_client_get_host_name_fqdn (AvahiClient*); /** Create a new AvahiEntryGroup object */ -AvahiEntryGroup* avahi_entry_group_new (AvahiClient*, AvahiEntryGroupCallback callback, void *user_data); +AvahiEntryGroup* avahi_entry_group_new (AvahiClient*, AvahiEntryGroupCallback callback, void *userdata); /** Clean up and free an AvahiEntryGroup object */ int avahi_entry_group_free (AvahiEntryGroup *); @@ -128,7 +128,7 @@ AvahiDomainBrowser* avahi_domain_browser_new (AvahiClient *client, const char *domain, AvahiDomainBrowserType btype, AvahiDomainBrowserCallback callback, - void *user_data); + void *userdata); /** Get the D-Bus path of an AvahiDomainBrowser object, for debugging purposes only. */ const char* avahi_domain_browser_path (AvahiDomainBrowser *); @@ -143,7 +143,7 @@ AvahiServiceTypeBrowser* avahi_service_type_browser_new ( AvahiProtocol protocol, const char *domain, AvahiServiceTypeBrowserCallback callback, - void *user_data); + void *userdata); /** Get the D-Bus path of an AvahiServiceTypeBrowser object, for debugging purposes only. */ const char* avahi_service_type_browser_path (AvahiServiceTypeBrowser *); @@ -159,7 +159,7 @@ AvahiServiceBrowser* avahi_service_browser_new ( const char *type, const char *domain, AvahiServiceBrowserCallback callback, - void *user_data); + void *userdata); /** Get the D-Bus path of an AvahiServiceBrowser object, for debugging purposes only. */ const char* avahi_service_browser_path (AvahiServiceBrowser *); diff --git a/avahi-client/entrygroup.c b/avahi-client/entrygroup.c index 6335755..dbd1a4e 100644 --- a/avahi-client/entrygroup.c +++ b/avahi-client/entrygroup.c @@ -43,7 +43,7 @@ void avahi_entry_group_state_change (AvahiEntryGroup *group, int state) if (group == NULL || group->callback == NULL) return; - group->callback (group, state, group->user_data); + group->callback (group, state, group->userdata); } AvahiEntryGroup* @@ -93,7 +93,7 @@ avahi_entry_group_new (AvahiClient *client, AvahiEntryGroupCallback callback, vo tmp->path = avahi_strdup (path); tmp->callback = callback; - tmp->user_data = user_data; + tmp->userdata = user_data; AVAHI_LLIST_PREPEND(AvahiEntryGroup, groups, client->groups, tmp); diff --git a/avahi-client/internal.h b/avahi-client/internal.h index 6058e20..4aaca39 100644 --- a/avahi-client/internal.h +++ b/avahi-client/internal.h @@ -30,8 +30,11 @@ struct _AvahiClient const AvahiPoll *poll_api; DBusConnection *bus; int error; + AvahiServerState state; + AvahiClientCallback callback; - void *user_data; + void *userdata; + AVAHI_LLIST_HEAD(AvahiEntryGroup, groups); AVAHI_LLIST_HEAD(AvahiDomainBrowser, domain_browsers); AVAHI_LLIST_HEAD(AvahiServiceBrowser, service_browsers); @@ -42,7 +45,7 @@ struct _AvahiEntryGroup { char *path; AvahiClient *client; AvahiEntryGroupCallback callback; - void *user_data; + void *userdata; AVAHI_LLIST_FIELDS(AvahiEntryGroup, groups); }; @@ -50,7 +53,7 @@ struct _AvahiDomainBrowser { char *path; AvahiClient *client; AvahiDomainBrowserCallback callback; - void *user_data; + void *userdata; AVAHI_LLIST_FIELDS(AvahiDomainBrowser, domain_browsers); }; @@ -58,7 +61,7 @@ struct _AvahiServiceBrowser { char *path; AvahiClient *client; AvahiServiceBrowserCallback callback; - void *user_data; + void *userdata; AVAHI_LLIST_FIELDS(AvahiServiceBrowser, service_browsers); }; @@ -66,7 +69,7 @@ struct _AvahiServiceTypeBrowser { char *path; AvahiClient *client; AvahiServiceTypeBrowserCallback callback; - void *user_data; + void *userdata; AVAHI_LLIST_FIELDS(AvahiServiceTypeBrowser, service_type_browsers); }; -- cgit