Make backtrace function lookup to work for functions in the executable itself
[ladish.git] / dbus / method.c
blob1001661a77daad5306d56f8f915359ad2ae286c3
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2008, 2009 Nedko Arnaudov <nedko@arnaudov.name>
6 * Copyright (C) 2008 Juuso Alasuutari <juuso.alasuutari@gmail.com>
8 **************************************************************************
9 * This file contains D-Bus methods helpers
10 **************************************************************************
12 * Licensed under the Academic Free License version 2.1
14 * LADI Session Handler is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * LADI Session Handler is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
26 * or write to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
30 #include "../common.h"
31 #include "../common/safety.h"
32 #include "helpers.h"
33 #include "method.h"
36 * Construct a void method return.
38 * The operation can only fail due to lack of memory, in which case
39 * there's no sense in trying to construct an error return. Instead,
40 * call_ptr->reply will be set to NULL and handled in send_method_return().
42 void
43 method_return_new_void(struct dbus_method_call * call_ptr)
45 if (!(call_ptr->reply = dbus_message_new_method_return(call_ptr->message))) {
46 log_error("Ran out of memory trying to construct method return");
51 * Construct a method return which holds a single argument or, if
52 * the type parameter is DBUS_TYPE_INVALID, no arguments at all
53 * (a void message).
55 * The operation can only fail due to lack of memory, in which case
56 * there's no sense in trying to construct an error return. Instead,
57 * call_ptr->reply will be set to NULL and handled in send_method_return().
59 void
60 method_return_new_single(struct dbus_method_call * call_ptr,
61 int type,
62 const void *arg)
64 if (!call_ptr || !arg) {
65 log_error("Invalid arguments");
66 return;
69 call_ptr->reply = dbus_message_new_method_return(call_ptr->message);
71 if (!call_ptr->reply)
72 goto fail_no_mem;
74 /* Void method return requested by caller. */
75 // TODO: do we really need this?
76 if (type == DBUS_TYPE_INVALID)
77 return;
79 /* Prevent crash on NULL input string. */
80 if (type == DBUS_TYPE_STRING && !(*((const char **) arg)))
81 *((const char **) arg) = "";
83 DBusMessageIter iter;
85 dbus_message_iter_init_append(call_ptr->reply, &iter);
87 if (dbus_message_iter_append_basic(&iter, type, arg))
88 return;
90 dbus_message_unref(call_ptr->reply);
91 call_ptr->reply = NULL;
93 fail_no_mem:
94 log_error("Ran out of memory trying to construct method return");
97 void
98 method_return_new_valist(struct dbus_method_call * call_ptr,
99 int type,
100 ...)
102 if (!call_ptr) {
103 log_error("Call pointer is NULL");
104 return;
107 if (type == DBUS_TYPE_INVALID) {
108 log_error("No argument(s) supplied");
109 return;
112 va_list argp;
114 call_ptr->reply = dbus_message_new_method_return(call_ptr->message);
115 if (!call_ptr->reply)
116 goto fail_no_mem;
118 va_start(argp, type);
120 if (dbus_message_append_args_valist(call_ptr->reply, type, argp)) {
121 va_end(argp);
122 return;
125 va_end(argp);
127 dbus_message_unref(call_ptr->reply);
128 call_ptr->reply = NULL;
130 fail_no_mem:
131 log_error("Ran out of memory trying to construct method return");
135 * Send a method return.
137 * If call_ptr->reply is NULL, i.e. a previous attempt to construct
138 * a return has failed, attempt to send a void return.
140 void
141 method_return_send(struct dbus_method_call * call_ptr)
143 if (call_ptr->reply) {
144 retry_send:
145 if (!dbus_connection_send(call_ptr->connection, call_ptr->reply, NULL))
146 log_error("Ran out of memory trying to queue "
147 "method return");
148 else
149 dbus_connection_flush(call_ptr->connection);
151 dbus_message_unref(call_ptr->reply);
152 call_ptr->reply = NULL;
153 } else {
154 log_debug("Message was NULL, trying to construct a void return");
156 if ((call_ptr->reply = dbus_message_new_method_return(call_ptr->message))) {
157 log_debug("Constructed a void return, trying to queue it");
158 goto retry_send;
159 } else {
160 log_error("Failed to construct method return!");
165 bool
166 method_return_verify(DBusMessage *msg,
167 const char **str)
169 if (!msg || dbus_message_get_type(msg) != DBUS_MESSAGE_TYPE_ERROR)
170 return true;
172 const char *ptr;
174 if (!dbus_message_get_args(msg, &g_dbus_error,
175 DBUS_TYPE_STRING, &ptr,
176 DBUS_TYPE_INVALID)) {
177 log_error("Cannot read description from D-Bus error message: %s ",
178 g_dbus_error.message);
179 dbus_error_free(&g_dbus_error);
180 ptr = NULL;
183 if (str)
184 *str = ptr;
186 return false;