4 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
26 #include "shared/log.h"
27 #include "dbus-system.h"
30 #define DBUS_REPLY_TIMEOUT (10000)
32 static GBusType g_default_bus_type = G_BUS_TYPE_SYSTEM;
33 pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
35 void dbus_handle_set_default_bus_type(GBusType bus_type)
37 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION)
40 pthread_mutex_lock(&g_mutex);
41 g_default_bus_type = bus_type;
42 pthread_mutex_unlock(&g_mutex);
45 GBusType dbus_handle_get_default_bus_type(void)
49 pthread_mutex_lock(&g_mutex);
50 type = g_default_bus_type;
51 pthread_mutex_unlock(&g_mutex);
61 /* basic information */
63 GDBusConnection *conn;
66 GList *list_names; /* dbus_name */
67 GList *list_object; /* dbus_object_handle_s */
68 pthread_mutex_t mutex;
71 /* path + interfaces */
73 dbus_handle_s *dh; /* dbus handle */
74 const char *path; /* object path */
75 GList *list_ifaces; /* dbus_interface_s */
76 } dbus_object_handle_s;
79 dbus_object_handle_s *oh; /* object handle */
80 const char *name; /* interface name */
81 GList *list_methods; /* const dbus_method_s */
86 #define get_dh_from_oh(oh) ((dbus_object_handle_s*)oh)->dh
88 /* global shared bus : system, session */
89 static dbus_handle_s g_dh[2];
91 static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type);
93 dbus_handle_s * _dbus_handle_get_default_connection(void)
95 return _dbus_handle_get_connection(dbus_handle_get_default_bus_type());
98 #define dbus_handle_lock(handle) do {\
100 pthread_mutex_lock(&((handle)->mutex));\
103 #define dbus_handle_unlock(handle) do {\
105 pthread_mutex_unlock(&(handle)->mutex);\
108 #define dcl_dbus_handle() dbus_handle_s *dh = (dbus_handle_s *)handle;
109 #define dcl_dbus_handle_null_check() dbus_handle_s *dh = (dbus_handle_s *)handle;\
111 _E("dbus handle is null\n");\
115 dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path);
116 dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name);
117 dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name);
119 dbus_interface_s *_iface_u_to_s(const dbus_interface_u *iface_u)
121 dbus_interface_s *iface = NULL;
123 if (!iface_u || !iface_u->methods) {
128 iface = (dbus_interface_s *)calloc(1, sizeof(dbus_interface_s));
130 _E("failed to calloc");
134 iface->name = iface_u->name;
135 iface->modified = TRUE;
137 for (int i = 0 ; i < iface_u->nr_methods; ++i) {
138 //_D("attached %s:%p", iface_u->methods[i].member, iface_u->methods[i].func);
139 iface->list_methods = g_list_prepend(iface->list_methods, (void*)(iface_u->methods + i));
145 static GDBusConnection * _get_bus(GBusType bus_type)
147 GDBusConnection *conn = NULL;
150 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
151 _E("Wrong bus_type %d", bus_type);
155 conn = g_bus_get_sync(bus_type, NULL, &err);
157 _E("failed to get bus:type:%d, %s\n", bus_type, err->message);
165 static GDBusConnection * _get_bus_private(GBusType bus_type)
168 GDBusConnection *conn = NULL;
169 const char * address;
171 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
172 _E("Wrong bus_type %d", bus_type);
176 address = g_dbus_address_get_for_bus_sync(bus_type, NULL, &err);
177 if (!address || err) {
178 _E("failed to get bus address\n");
183 conn = g_dbus_connection_new_for_address_sync(address,
184 (GDBusConnectionFlags) (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
185 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION),
186 NULL, /* GDBusAuthObserver */
190 _E("failed to get private bus\n");
199 static dbus_handle_s *_dbus_handle_get_connection(GBusType bus_type)
201 int ibus = bus_type - 1;
202 dbus_handle_s *dh = NULL;
204 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
205 _E("Unknown bus type %d", bus_type);
210 dbus_handle_lock(dh);
213 dh->conn = _get_bus(bus_type);
215 dbus_handle_unlock(dh);
219 dh->bus_type = bus_type;
222 dbus_handle_unlock(dh);
228 static dbus_handle_s *_dbus_handle_get_connection_private(GBusType bus_type)
232 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
233 _E("Unknown bus type %d", bus_type);
237 dh = (dbus_handle_s *)calloc(1, sizeof(dbus_handle_s));
239 _E("failed to allocate memory for dbus handle");
243 dbus_handle_lock(dh);
246 dh->conn = _get_bus_private(bus_type);
247 dh->bus_type = bus_type;
252 dbus_handle_unlock(dh);
257 dbus_handle_unlock(dh);
263 dbus_handle_h dbus_handle_get_connection(GBusType bus_type, gboolean priv)
265 dbus_handle_s *dh = NULL;
268 if (bus_type != G_BUS_TYPE_SYSTEM && bus_type != G_BUS_TYPE_SESSION) {
269 _E("Wrong bus_type %d\n", bus_type);
273 for (i = 0 ; i < 3; ++i) {
276 dh = _dbus_handle_get_connection_private(bus_type);
279 dh = _dbus_handle_get_connection(bus_type);
289 static void _dbus_handle_add_bus_name(dbus_handle_s *handle, const char *name, guint id)
291 dbus_name *dn = NULL;
294 if (!handle || !name || !id)
297 dn = (dbus_name*)calloc(1, sizeof(dbus_name));
299 _E("failed to calloc");
305 // todo : delete lock ?
306 locked = pthread_mutex_trylock(&handle->mutex);
307 if (locked != 0 && locked != EBUSY) {
308 _E("failed to lock %d\n", locked);
312 handle->list_names = g_list_prepend(handle->list_names, dn);
314 // todo : delete lock ?
316 dbus_handle_unlock(handle);
319 static gint _compare_dbus_name(gconstpointer a, gconstpointer b)
321 const char *bus_name = ((dbus_name *)a)->bus_name;
324 return strcmp(bus_name, (const char *)b);
327 dbus_name * _dbus_handle_lookup_dbus_name(GList *list_name, const char *bus_name)
329 if (!list_name || !bus_name)
332 GList *item = g_list_find_custom(list_name, bus_name, _compare_dbus_name);
336 return (dbus_name *)item->data;
339 #define dh_to_ds(x) ((dbus_handle_s*)x)
341 /* remove dbus_name from dbus handle */
342 static void _dbus_handle_remove_bus_name(dbus_handle_s *handle, const char *bus_name)
345 dbus_name *dn = NULL;
348 _E("wrong bus_name is null");
352 dh = _dbus_handle_get_default_connection();
354 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
359 dbus_handle_lock(dh);
360 dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name);
362 _E("failed to find dbus name %s", bus_name);
365 dh->list_names = g_list_remove(dh->list_names, dn);
368 dbus_handle_unlock(dh);
371 //extern void booting_done(void);
373 /* default handler */
374 static void _name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
376 dbus_handle_s *dh = (dbus_handle_s *)user_data;
381 _E("%s:%d:dbus handle is null\n", __func__, __LINE__);
385 // todo: add bus name?
386 //dh->bus_name = name;
389 /* default handler */
390 static void _name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
392 _E("%s:%d:%s\n", __func__, __LINE__, name);
393 dbus_handle_s *dh = (dbus_handle_s *)user_data;
395 _E("%s:%d:dbus handle is null\n", __func__, __LINE__);
398 _dbus_handle_remove_bus_name(dh, name);
401 int dbus_handle_request_bus_name(dbus_handle_h handle,
402 const char *bus_name,
403 GBusNameAcquiredCallback acquired_handler,
404 GBusNameLostCallback lost_handler)
411 _E("bus_name is NULL");
415 /* get shared connection */
417 dh = _dbus_handle_get_default_connection();
419 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
424 dbus_handle_lock(dh);
426 _E("failed to register name: connection is null\n");
430 /* todo : search name on connection */
431 item = g_list_find_custom(dh->list_names, bus_name, _compare_dbus_name);
433 id = ((dbus_name*)(item->data))->id;
434 _E("name already exist:%u", id);
438 id = g_bus_own_name_on_connection(dh->conn,
440 G_BUS_NAME_OWNER_FLAGS_NONE,
441 acquired_handler ? acquired_handler : _name_acquired,
442 lost_handler ? lost_handler : _name_lost,
446 _E("failed to own name:%s\n", bus_name);
450 _dbus_handle_add_bus_name(dh, bus_name, id);
453 dbus_handle_unlock(dh);
457 /* !! _name_lost handler callback is disabled by g_bus_unown_name : ubuntu */
458 int dbus_handle_release_bus_name(dbus_handle_h handle, const char *bus_name)
461 dbus_name *dn = NULL;
464 _E("Wrong bus name");
469 dh = _dbus_handle_get_default_connection();
471 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
476 dn = _dbus_handle_lookup_dbus_name(dh->list_names, bus_name);
478 _E("failed to find bus_name %s on dbus handle", bus_name);
482 _E("unown name %d", dn->id);
483 /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */
484 g_bus_unown_name(dn->id);
486 dbus_handle_lock(dh);
487 dh->list_names = g_list_remove(dh->list_names, dn);
489 dbus_handle_unlock(dh);
494 int dbus_handle_free_connection(dbus_handle_h handle)
497 dbus_handle_s *pdh = NULL;
502 dh = _dbus_handle_get_default_connection();
504 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
510 _E("connection is NULL");
516 /* disable dbus handler */
517 dbus_handle_lock(dh);
524 /* flush everything */
525 if (!g_dbus_connection_flush_sync(pdh->conn, NULL, &err)) {
526 _E("failed to flush %s\n", err->message);
531 _D("list_names %u", g_list_length(pdh->list_names));
533 /* unown every well-knwon name */
534 if (pdh->list_names) {
535 dbus_name *dn = NULL;
536 for (item = g_list_first(pdh->list_names); item != NULL; item = g_list_next(item)) {
537 dn = (dbus_name *)item->data;
541 /* _name_lost handler is disabled by g_bus_unown_name : ubuntu */
542 _D("unown name id : %u", dn->id);
543 g_bus_unown_name(dn->id);
546 g_list_free(pdh->list_names);
547 pdh->list_names = NULL;
550 _D("list_object %u", g_list_length(pdh->list_object));
552 /* unregister every object */
553 if (pdh->list_object) {
554 dbus_object_handle_s * oh = NULL;
555 //g_list_foreach(pdh->list_object, [] (gpointer data, gpointer user_data) {}, NULL);
556 for (item = g_list_first(pdh->list_object); item != NULL; item = g_list_next(item)) {
557 oh = (dbus_object_handle_s *)item->data;
558 if (!oh || !oh->list_ifaces)
561 _D("delete object path %s", oh->path);
563 /* unregister every interface, method handles */
564 for (GList *iface = g_list_first(oh->list_ifaces); iface != NULL; iface = g_list_next(iface)) {
565 dbus_interface_s *ih = (dbus_interface_s *)iface->data;
569 _D("delete object iface %s", ih->name);
572 g_dbus_connection_unregister_object(pdh->conn, ih->reg_id);
577 /* close connection */
579 _E("close private connection\n");
581 if (!g_dbus_connection_close_sync(pdh->conn, NULL, &err)) {
582 _E("Error closing connection %s\n", err->message);
588 /* _free_func_object callback free the data */
589 //assert(g_list_length(pdh->list_names) == 0);
590 //assert(g_list_length(pdh->list_object) == 0);
592 g_object_unref(pdh->conn);
594 dbus_handle_unlock(dh);
604 #define buf_cal_free_space(size, nwrite) ((size - nwrite - 1) > 0 ? (size - nwrite - 1) : 0)
605 #define buf_block_size 8192
607 #define buf_check_space_realloc(buf, nwrite, buf_len) do {\
608 if ((nwrite >= buf_len - 1024)) {\
609 if (buf_len >= buf_block_size * 10) {\
610 _E("buf is too big to allocate. %d", buf_len);\
612 _E("buf_check_space_realloc");\
614 buf_len += buf_block_size;\
615 tmp = (char *)realloc(buf, buf_len);\
617 _E("failed to realloc");\
624 /* cal index of end of brace */
625 static int _check_brace(const char * expr)
636 if (expr[0] != '(' && expr[0] != '{')
639 for (int i = 0 ; i < len; ++i) {
641 if (expr[i] == '(' || expr[i] == '{') {
642 qu[qucnt++] = expr[i];
643 if (qucnt >= sizeof(qu)) {
644 _E("queue is too large. %s", expr);
650 if (expr[i] == ')' || expr[i] == '}') {
658 if (expr[i] == ')') {
663 } else if (expr[i] == '}') {
683 static int _get_xml_from_interfaces(char **xml, const dbus_interface_s *interfaces)
688 const dbus_method_s *pmethod;
689 int buf_len = buf_block_size;
692 _E("interfaces is null");
696 // todo : check dbus naming rule for interface name. ?
697 if (!interfaces->name) {
698 _E("wrong interface name");
701 if (!interfaces->list_methods) {
706 buf = (char *)malloc(buf_len);
708 _E("buf is null. not enough memory\n");
712 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "<node>""\n""\t""<interface name='%s'>""\n", interfaces->name);
715 for (GList *item = g_list_first(interfaces->list_methods); item != NULL; item = g_list_next(item)) {
716 pmethod = (const dbus_method_s *)item->data;
720 /* check free space of buf */
721 buf_check_space_realloc(buf, nwrite, buf_len);
723 if (pmethod->signature_in == NULL && pmethod->signature_out == NULL) {
724 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'/>""\n", pmethod->member);
728 /* <method name='###'> */
729 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""<method name='%s'>""\n", pmethod->member);
732 len_args = pmethod->signature_in ? strlen(pmethod->signature_in) : 0;
733 for (int m = 0; m < len_args; ++m) {
735 // array a(), as, ay ?
736 if (pmethod->signature_in[m] == 'a') {
738 ei = _check_brace(pmethod->signature_in + m + 1);
740 char tmp[128] = {0,};
741 strncpy(tmp, pmethod->signature_in + m, ei + 1);
742 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%s' name='arg%d' direction='in'/>""\n", tmp, m);
746 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c%c' name='arg%d' direction='in'/>""\n", pmethod->signature_in[m], pmethod->signature_in[m+1], m);
751 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c' name='arg%d' direction='in'/>""\n", pmethod->signature_in[m], m);
755 len_args = pmethod->signature_out ? strlen(pmethod->signature_out) : 0;
756 for (int m = 0; m < len_args; ++m) {
758 // todo: container type
759 if (pmethod->signature_out[m] == 'a') {
761 ei = _check_brace(pmethod->signature_out + m + 1);
763 char tmp[128] = {0,};
764 strncpy(tmp, pmethod->signature_out + m, ei + 1);
765 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%s' name='arg%d' direction='out'/>""\n", tmp, m);
769 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c%c' name='arg%d' direction='out'/>""\n", pmethod->signature_out[m], pmethod->signature_out[m+1], m);
774 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t\t""<arg type='%c' name='arg%d' direction='out'/>""\n", pmethod->signature_out[m], m);
778 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t\t""</method>""\n");
781 nwrite += snprintf(buf + nwrite, buf_cal_free_space(buf_len, nwrite), "\t""</interface>""\n""</node>""");
785 /* todo: delete log */
790 _E("%s", buf + nwrite - 512);
795 static gint _compare_dbus_object(gconstpointer a, gconstpointer b)
797 dbus_object_handle_s * pa = (dbus_object_handle_s *)a;
798 if (!pa->path || !((const char*)b))
800 return strcmp(pa->path, (const char*)b);
803 static gint _compare_dbus_interface(gconstpointer a, gconstpointer b)
805 dbus_interface_s * pa = (dbus_interface_s *)a;
806 if (!pa->name || !((const char*)b))
808 return strcmp(pa->name, (const char*)b);
811 static gint _compare_dbus_interface_by_id(gconstpointer a, gconstpointer b)
813 dbus_interface_s * pa = (dbus_interface_s *)a;
814 if (!pa->reg_id || !((guint*)b))
816 return !(pa->reg_id == *((guint*)b));
819 static gint _compare_dbus_method(gconstpointer a, gconstpointer b)
821 dbus_method_s *pa = (dbus_method_s*)a;
822 if (!pa->member || !((const char*)b))
824 return strcmp(pa->member, (const char*)b);
827 dbus_object_handle_s * _dbus_handle_lookup_object(GList *list_obj, const char *obj_path)
829 if (!list_obj || !obj_path)
832 GList *item = g_list_find_custom(list_obj, obj_path, _compare_dbus_object);
836 return (dbus_object_handle_s *)item->data;
839 dbus_interface_s * _dbus_handle_lookup_interface(GList *list_iface, const char *iface_name)
841 if (!list_iface || !iface_name)
844 GList *item = g_list_find_custom(list_iface, iface_name, _compare_dbus_interface);
848 return (dbus_interface_s *)item->data;
851 dbus_interface_s * _dbus_handle_lookup_interface_by_id(GList *list_iface, guint id)
853 if (!list_iface || !id)
856 GList *item = g_list_find_custom(list_iface, &id, _compare_dbus_interface_by_id);
860 return (dbus_interface_s *)item->data;
863 dbus_method_s * _dbus_handle_lookup_method(GList *list_methods, const char *method_name)
865 if (!list_methods || !method_name)
868 GList *item = g_list_find_custom(list_methods, method_name, _compare_dbus_method);
872 return (dbus_method_s *)item->data;
875 static void _free_func_object(gpointer data)
877 dbus_interface_s *ih = (dbus_interface_s *)data;
878 dbus_object_handle_s *oh = NULL;
881 _E("interface handle is null");
882 assert(0); // something wrong
886 _E("unregister interface %s", ih->name);
888 /* just free list, not data(static dbus_method_s) */
889 g_list_free(ih->list_methods);
893 _E("object handle is null");
894 assert(0); // something wrong
898 /* remove ih from list_ifaces */
899 oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
901 /* interface_s is copy of interface_u */
904 /* remove oh from list_object */
905 if (!oh->list_ifaces) {
906 oh->dh->list_object = g_list_remove(oh->dh->list_object, oh);
911 static int _dbus_handle_attach_object(dbus_handle_s *dh, const char *obj_path, dbus_interface_s *iface)
913 dbus_object_handle_s *oh = NULL;
915 if (!dh || !obj_path || !iface) {
916 _E("failed to attache object. wrong parameter");
920 /* find object handle */
922 oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
925 oh = (dbus_object_handle_s*)calloc(1, sizeof(dbus_object_handle_s));
927 _E("failed to calloc");
934 dh->list_object = g_list_prepend(dh->list_object, oh);
938 /* attach interface */
939 oh->list_ifaces = g_list_prepend(oh->list_ifaces, iface);
947 libgio verify path and interface of incoming message.
948 --> just check method name.
950 # parameters - member of invocation struct
951 every parameters of this function are member of GDBusMethodInvocation *invocation.
952 There are no reason to using g_dbus_method_invocation_get_* apis to get inforamtion from message.
953 just use params - sender, path, iface, name and param.
956 # user defined handler #
958 1. synchronous handling
961 return g_variant_new("(i)", ret);
964 2) without return value
966 return dbus_handle_new_g_variant_tuple(); // g_variant_new_tuple(NULL, 0)
969 2. asynchronous handling
970 handler MUST call 'g_dbus_method_invocation_return_value' itself. otherwise, LEAK !!
976 # if handler return NULL, assume asynchronous handling. do nothing.
982 g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", ret));
984 2) without return value
985 g_dbus_method_invocation_return_value(invocation, NULL);
990 static void _method_call_handler(GDBusConnection *conn,
996 GDBusMethodInvocation *invocation,
999 dbus_interface_s *iface_s = (dbus_interface_s *)user_data;
1000 const dbus_method_s *methods;
1001 GVariant *result = NULL;
1004 methods = _dbus_handle_lookup_method(iface_s->list_methods, name);
1006 result = methods->func(conn, sender, path, iface, name, param, invocation, get_dh_from_oh(iface_s->oh));
1008 /* async, maybe they will reply...maybe.. */
1015 g_dbus_method_invocation_return_value(invocation, result);
1018 static GDBusInterfaceVTable path_vtable = {_method_call_handler};
1022 before register object, attach object into dbus handle
1023 _dbus_handle_attach_object()
1025 static int _dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, dbus_interface_s *iface)
1031 GDBusNodeInfo * nodeinfo = NULL;
1032 GDBusInterfaceInfo *ifaceinfo = NULL;
1034 if (!obj_path || !iface) {
1035 _E("wrong parameter\n");
1039 dh = _dbus_handle_get_default_connection();
1041 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1046 _E("connection is null\n");
1050 ret = _get_xml_from_interfaces(&buf, iface);
1052 _E("failed to make xml format");
1056 /* todo: delete this */
1058 if (strlen(buf) <= 512) {
1061 _E("%s", buf + strlen(buf) - 512);
1065 nodeinfo = g_dbus_node_info_new_for_xml(buf, &err);
1066 if (!nodeinfo || err) {
1067 _E("failed to make introspection data:err:%s:xml:%s\n", err->message, buf);
1072 ifaceinfo = g_dbus_node_info_lookup_interface(nodeinfo, iface->name);
1074 _E("failed to g_dbus_node_info_lookup_interface");
1080 path own single interface
1081 if interface is already registered, then failed.
1082 g_dbus_connection_register_object ref(ifaceinfo) now, unref if object is unregistered
1084 ret = g_dbus_connection_register_object(dh->conn,
1092 _E("failed to register object:err:%s:\n", err->message);
1097 iface->reg_id = ret;
1098 iface->modified = FALSE;
1101 /* todo: detach object */
1102 //_dbus_handle_detach_object(dh, obj_path, iface);
1103 /* attach interface before register object */
1104 /*ret = _dbus_handle_detach_object(dh, obj_path, iface);
1106 _E("failed to attach object");
1111 g_dbus_node_info_unref(nodeinfo);
1121 register same interface at once
1123 if interface is constructed by multiple methods,
1124 also it is not possible to make methods struct at once,
1126 use dbus_handle_add_dbus_object(), dbus_handle_register_dbus_object_all().
1130 int dbus_handle_register_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
1134 dbus_interface_s *iface = NULL;
1136 if (!obj_path || !iface_u) {
1137 _E("wrong parameter\n");
1141 dh = _dbus_handle_get_default_connection();
1143 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1148 _E("connection is null\n");
1152 /* check registered interface */
1153 if (dh->list_object) {
1154 dbus_object_handle_s *oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
1156 dbus_interface_s *ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name);
1158 _E("path %s, interface %s already registered", obj_path, iface_u->name);
1164 iface = _iface_u_to_s(iface_u);
1166 _E("failed to _iface_u_to_s");
1170 /* attach interface before register object */
1171 ret = _dbus_handle_attach_object(dh, obj_path, iface);
1173 _E("failed to attach object");
1177 ret = _dbus_handle_register_dbus_object(dh, obj_path, iface);
1179 _E("failed to register dbus object%d", ret);
1186 int dbus_handle_unregister_dbus_object(dbus_handle_h handle, const char *obj_path)
1189 dbus_object_handle_s *oh = NULL;
1196 dh = _dbus_handle_get_default_connection();
1198 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1202 if (!dh->list_object) {
1203 _E("list_object is empty");
1207 oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
1209 _E("no object with name %s", obj_path);
1213 /* unregister every interface of object*/
1214 for (GList *item = g_list_first(oh->list_ifaces); item != NULL; item = g_list_next(item)) {
1215 dbus_interface_s *ih = item->data;
1217 _E("this is error");
1221 /* remove ih from list_ifaces */
1223 item = g_list_previous(item);
1225 /* remove and free link */
1226 oh->list_ifaces = g_list_remove(oh->list_ifaces, ih);
1228 /* free list_methods */
1229 g_list_free(ih->list_methods);
1236 /* unregister object by id */
1237 ret = g_dbus_connection_unregister_object(dh->conn, ih->reg_id);
1239 _E("failed to unregister object %s, interface %s, regid %d", oh->path, ih->name, ih->reg_id);
1246 add object temporarily.
1247 dbus_handle_register_dbus_object_all register every objects on connection.
1249 return registered method count
1251 int dbus_handle_add_dbus_object(dbus_handle_h handle, const char *obj_path, const dbus_interface_u *iface_u)
1254 dbus_object_handle_s *oh = NULL;
1255 dbus_interface_s *ih = NULL;
1258 if (!obj_path || !iface_u) {
1259 _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
1262 if (iface_u && (!iface_u->name || !iface_u->methods)) {
1263 _E("wrong parameter path %s, iface_u %p\n", obj_path, iface_u);
1267 cnt = iface_u->nr_methods;
1270 dh = _dbus_handle_get_default_connection();
1272 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1278 _E("failed to register method. connection is null\n");
1282 /* if there are no object list, just add */
1283 if (!dh->list_object) {
1284 if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1285 _E("failed to attach object");
1291 oh = _dbus_handle_lookup_object(dh->list_object, obj_path);
1292 /* if there are no matched object, just add */
1294 if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1295 _E("failed to attach object");
1301 /* this is an error, interface must have one or more item ? */
1302 if (!oh->list_ifaces) {
1303 _E("error. list_ifaces is null\n");
1308 ih = _dbus_handle_lookup_interface(oh->list_ifaces, iface_u->name);
1309 /* if there are no matched interface, just add */
1311 if (_dbus_handle_attach_object(dh, obj_path, _iface_u_to_s(iface_u))) {
1312 _E("failed to attach object");
1319 1. unregister interface
1320 2. update interface and methods
1321 3. register interface
1324 _E("interface already registered, ignore new interface");
1328 /* attach new methods */
1330 for (int i = 0; i < iface_u->nr_methods; ++i) {
1331 GList *item = g_list_find_custom(g_list_first(ih->list_methods), iface_u->methods[i].member, _compare_dbus_method);
1333 //_D("attached %s", iface_u->methods[i].member);
1334 ih->list_methods = g_list_prepend(ih->list_methods, (void*)(iface_u->methods + i));
1340 ih->modified = TRUE;
1343 /*todo: delete debugging log */
1344 //if (dh && dh->list_object)
1345 // _D("obj list len %d", g_list_length(dh->list_object));
1346 //if (oh && oh->list_ifaces)
1347 // _D("iface list len %d", g_list_length(oh->list_ifaces));
1348 //if (ih && ih->list_methods)
1349 // _D("method list len %d", g_list_length(ih->list_methods));
1354 int dbus_handle_register_dbus_object_all(dbus_handle_h handle)
1357 dbus_object_handle_s *oh = NULL;
1358 dbus_interface_s *ih = NULL;
1362 dh = _dbus_handle_get_default_connection();
1364 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1369 _E("connection is null\n");
1373 if (!dh->list_object) {
1374 _E("obj list is empty");
1378 /*if (dh && dh->list_object)
1379 _D("obj list len %d", g_list_length(dh->list_object));*/
1381 for (GList *item = g_list_first(dh->list_object); item != NULL; item = g_list_next(item)) {
1382 oh = (dbus_object_handle_s *)item->data;
1385 _E("something wrong");
1388 if (!oh->list_ifaces) {
1389 _E("path %s: list_ifaces are null", oh->path);
1393 //_D("iface list len %d", g_list_length(oh->list_ifaces));
1395 for (GList *li = g_list_first(oh->list_ifaces); li != NULL; li = g_list_next(li)) {
1396 ih = (dbus_interface_s *)li->data;
1398 /* if there are no modification, goto next */
1402 /* todo: if already registered interface, unregister first */
1404 /*_E("interface %s:", ih->name);
1405 if (ih && ih->list_methods)
1406 _D("method list len %d", g_list_length(ih->list_methods));*/
1408 ret = _dbus_handle_register_dbus_object(dh, oh->path, ih);
1410 _E("failed to register dbus object%d", ret);
1417 // todo: delete all updates
1422 guint subscribe_dbus_signal(dbus_handle_h handle, const char *path,
1423 const char *iface, const char *name,
1424 GDBusSignalCallback cb, void *data,
1425 destroy_notified free_func)
1430 dh = _dbus_handle_get_default_connection();
1432 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1438 _E("connection is null. check bus status");
1441 return g_dbus_connection_signal_subscribe(dh->conn, NULL, iface, name, path, NULL, G_DBUS_SIGNAL_FLAGS_NONE, cb, data, free_func);
1444 void unsubscribe_dbus_signal(dbus_handle_h handle, guint id)
1448 dh = _dbus_handle_get_default_connection();
1450 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1456 _E("connection is null. check bus status");
1460 g_dbus_connection_signal_unsubscribe(dh->conn, id);
1463 static void _signal_reply_sync_cb(GDBusConnection *conn,
1464 const gchar *sender,
1471 sig_ctx *ctx = data;
1473 _E("user data is null");
1477 ctx->param = g_variant_ref(param);
1478 ctx->quit_reason = CTX_QUIT_NORMAL;
1480 if (ctx->timeout_src) {
1481 g_source_destroy(ctx->timeout_src);
1482 ctx->timeout_src = NULL;
1484 g_main_loop_quit(ctx->loop);
1487 sig_ctx *dbus_handle_new_signal_ctx(void)
1491 ctx = (sig_ctx *)malloc(sizeof(sig_ctx));
1493 _E("failed to alloc mem");
1499 ctx->context = g_main_context_new();
1500 if (!ctx->context) {
1501 _E("failed to alloc context");
1505 ctx->loop = g_main_loop_new(ctx->context, FALSE);
1507 _E("failed to alloc main loop");
1508 g_main_context_unref(ctx->context);
1512 ctx->timeout_src = NULL;
1514 ctx->quit_reason = CTX_QUIT_UNKNOWN;
1515 ctx->user_data = NULL;
1520 void dbus_handle_free_signal_ctx(sig_ctx *ctx)
1526 g_variant_unref(ctx->param);
1530 unsubscribe_dbus_signal(NULL, ctx->sig_id);
1533 if (ctx->timeout_src) {
1534 g_source_destroy(ctx->timeout_src);
1535 ctx->timeout_src = NULL;
1538 g_main_context_pop_thread_default(ctx->context);
1539 g_main_context_unref(ctx->context);
1540 ctx->context = NULL;
1543 g_main_loop_unref(ctx->loop);
1549 static gboolean _cb_ctx_timeout(gpointer user_data)
1551 sig_ctx *ctx = user_data;
1554 _E("user_data is null");
1558 ctx->quit_reason = CTX_QUIT_TIMEOUT;
1559 /* if cb return FALSE, source will be destroyed */
1560 ctx->timeout_src = NULL;
1562 unsubscribe_dbus_signal(NULL, ctx->sig_id);
1565 g_main_loop_quit(ctx->loop);
1570 #define CTX_MAX_TIMEOUT 25000
1572 int dbus_handle_signal_ctx_add_timeout(sig_ctx *ctx, int timeout_msec)
1574 GSource *src = NULL;
1578 if (timeout_msec < -1)
1581 if (timeout_msec == -1 || timeout_msec >= CTX_MAX_TIMEOUT)
1582 timeout_msec = CTX_MAX_TIMEOUT;
1584 src = g_timeout_source_new(timeout_msec);
1588 g_source_set_callback(src, _cb_ctx_timeout, ctx, NULL);
1589 g_source_attach(src, ctx->context);
1590 g_source_unref(src);
1592 ctx->timeout_src = src;
1597 guint subscribe_dbus_signal_ctx(dbus_handle_h handle, sig_ctx *ctx,
1598 const char *sender, const char *path,
1599 const char *iface, const char *name,
1600 GDBusSignalCallback _cb)
1605 _E("wrong param ctx is null");
1610 dh = _dbus_handle_get_default_connection();
1612 _E("failed to get default connection, bustype:%d",
1613 (int)dbus_handle_get_default_bus_type());
1619 _E("connection is null. check bus status");
1624 _cb = _signal_reply_sync_cb;
1626 /* change context before subscribe */
1627 g_main_context_push_thread_default(ctx->context);
1629 ctx->sig_id = g_dbus_connection_signal_subscribe(dh->conn,
1630 sender, iface, name, path, NULL,
1631 G_DBUS_SIGNAL_FLAGS_NONE, _cb,
1635 _E("failed to subscribe signal");
1640 int dbus_handle_signal_ctx_wait(sig_ctx *ctx)
1642 if (!ctx || !ctx->loop)
1645 g_main_loop_run(ctx->loop);
1647 _D("quit g_main_loop");
1649 return ctx->quit_reason;
1652 int _check_type_string_is_container(const char *signature)
1657 switch (signature[0]) {
1672 int dbus_handle_emit_dbus_signal(const char *dest,
1678 dbus_handle_s *dh = NULL;
1682 dh = _dbus_handle_get_default_connection();
1684 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1688 ret = g_dbus_connection_emit_signal(dh->conn, dest, path, iface, name, param, &err);
1690 _E("%d %s\n", ret, err ? err->message : "NULL");
1697 int dbus_handle_emit_dbus_signal_sync(const char *dest,
1703 dbus_handle_s *dh = NULL;
1707 dh = _dbus_handle_get_default_connection();
1709 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1713 ret = g_dbus_connection_emit_signal(dh->conn, dest, path, iface, name, param, &err);
1715 _E("%d %s\n", ret, err ? err->message : "NULL");
1719 ret = g_dbus_connection_flush_sync(dh->conn, NULL, &err);
1721 _E("%d %s\n", ret, err ? err->message : "NULL");
1728 int dbus_handle_flush_sync(dbus_handle_h handle)
1735 dh = _dbus_handle_get_default_connection();
1737 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1742 ret = g_dbus_connection_flush_sync(dh->conn, NULL, &err);
1744 _E("%d %s\n", ret, err ? err->message : "NULL");
1751 GVariant *dbus_handle_method_sync_with_reply_var(const char *dest,
1758 GVariant * ret = NULL;
1759 dbus_handle_s *dh = NULL;
1761 if (!dest || !path || !iface || !method) {
1762 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1764 g_variant_unref(var);
1768 dh = _dbus_handle_get_default_connection();
1770 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1772 g_variant_unref(var);
1776 ret = g_dbus_connection_call_sync(dh->conn,
1777 dest, path, iface, method,
1779 G_DBUS_CALL_FLAGS_NONE,
1785 _E("failed to g_dbus_connection_call_sync:%s", err->message);
1786 if (g_error_matches(err, G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED))
1787 ret = g_variant_new("(i)", -EPERM);
1793 _E("failed to g_dbus_connection_call_sync");
1801 GVariant *dbus_handle_method_sync_with_reply_var_timeout(const char *dest, const char *path,
1802 const char *iface, const char *method, GVariant *var, int timeout)
1805 GVariant * ret = NULL;
1806 dbus_handle_s *dh = NULL;
1808 if (!dest || !path || !iface || !method) {
1809 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1811 g_variant_unref(var);
1815 dh = _dbus_handle_get_default_connection();
1817 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1819 g_variant_unref(var);
1823 ret = g_dbus_connection_call_sync(dh->conn,
1824 dest, path, iface, method,
1826 G_DBUS_CALL_FLAGS_NONE,
1832 _E("failed to g_dbus_connection_call_sync:%s", err->message);
1835 _E("failed to g_dbus_connection_call_sync");
1843 gint* dbus_handle_get_unix_fd_list(GDBusMethodInvocation *invocation, int *size)
1845 GUnixFDList *fd_list = NULL;
1848 fd_list = g_dbus_message_get_unix_fd_list(g_dbus_method_invocation_get_message(invocation));
1851 _E("failed to g_unix_fd_list_get_length: fd_list is null");
1855 length = g_unix_fd_list_get_length(fd_list);
1857 _E("failed to g_unix_fd_list_get_length: list size is 0");
1863 return g_unix_fd_list_steal_fds(fd_list, NULL);
1866 GVariant *dbus_handle_method_with_unix_fd_list_sync_with_reply_var(const char *dest,
1877 GVariant * ret = NULL;
1878 dbus_handle_s *dh = NULL;
1879 GUnixFDList *g_infdlist = NULL;
1880 GUnixFDList *g_outfdlist = NULL;
1882 if (!dest || !path || !iface || !method) {
1883 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1886 if (in_fdlist && in_size == 0) {
1887 _E("wrong in_fdlist is not null but in_size is 0");
1891 dh = _dbus_handle_get_default_connection();
1893 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1899 g_infdlist = g_unix_fd_list_new_from_array(in_fdlist, in_size);
1901 _E("failed to g_unix_fd_list_new_from_array\n");
1904 //g_infdlist = g_unix_fd_list_new();
1905 //if (g_unix_fd_list_append(g_infdlist, in_fdlist[0], &err) < 0) {
1909 ret = g_dbus_connection_call_with_unix_fd_list_sync(dh->conn,
1910 dest, path, iface, method,
1912 G_DBUS_CALL_FLAGS_NONE,
1914 g_infdlist, &g_outfdlist,
1918 _E("failed to g_dbus_connection_call_with_unix_fd_list_sync:%s", err->message);
1921 _E("failed to g_dbus_connection_call_with_unix_fd_list_sync:");
1923 g_variant_unref(param);
1925 g_object_unref(g_infdlist);
1930 /* copy fds to out array */
1932 *out_size = g_unix_fd_list_get_length(g_outfdlist);
1935 *out_fdlist = g_unix_fd_list_steal_fds(g_outfdlist, NULL);
1939 g_object_unref(g_outfdlist);
1943 int dbus_handle_method_sync_var(const char *dest,
1950 gboolean result_bool;
1951 GVariant *reply = NULL;
1953 if (!dest || !path || !iface || !method) {
1954 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1958 reply = dbus_handle_method_sync_with_reply_var(dest, path, iface, method, param);
1962 if (g_strcmp0("(i)", g_variant_get_type_string(reply)) == 0) {
1963 g_variant_get(reply, "(i)", &result);
1964 } else if (g_strcmp0("(b)", g_variant_get_type_string(reply)) == 0) {
1965 g_variant_get(reply, "(b)", &result_bool);
1966 result = (int)result_bool;
1971 g_variant_unref(reply);
1976 int dbus_handle_method_async_var(const char *dest,
1982 dbus_handle_s *dh = NULL;
1984 if (!dest || !path || !iface || !method) {
1985 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
1989 dh = _dbus_handle_get_default_connection();
1991 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
1995 g_dbus_connection_call(dh->conn,
1996 dest, path, iface, method,
1998 G_DBUS_CALL_FLAGS_NONE,
2007 /* callback should free gvariant */
2008 static void _cb_pending(GDBusConnection *conn,
2012 GVariant *reply = NULL;
2014 pending_call_data *data = (pending_call_data *)user_data;
2016 reply = g_dbus_connection_call_finish(conn, res, &err);
2017 if (!reply || err) {
2019 g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED,
2020 "Error during g_dbus_connection_call");
2022 if (data && data->func)
2023 data->func(NULL, data->data, err);
2027 if (data && data->func)
2028 data->func(reply, data->data, err);
2036 int dbus_handle_method_async_with_reply_var(const char *dest,
2045 dbus_handle_s *dh = NULL;
2046 pending_call_data *pdata = NULL;
2049 if (!dest || !path || !iface || !method) {
2050 _E("wrong parameters dest(%s) path(%s) iface(%s) method(%s)", dest, path, iface, method);
2054 if (timeout_msec < -1) {
2055 _E("wrong timeout %d", timeout_msec);
2059 dh = _dbus_handle_get_default_connection();
2061 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2066 pdata = (pending_call_data*)malloc(sizeof(pending_call_data));
2075 g_dbus_connection_call(dh->conn,
2076 dest, path, iface, method,
2078 G_DBUS_CALL_FLAGS_NONE,
2081 (GAsyncReadyCallback)_cb_pending,
2087 g_variant_unref(param);
2091 int dbus_connection_get_sender_pid(GDBusConnection *conn, const char * sender)
2094 GVariant *vret = NULL;
2098 _E("connection is null");
2102 _E("sender is null");
2106 vret = g_dbus_connection_call_sync(conn,
2107 "org.freedesktop.DBus", "/", "org.freedesktop.DBus", "GetConnectionUnixProcessID",
2108 g_variant_new("(s)", sender), NULL,
2109 G_DBUS_CALL_FLAGS_NONE,
2114 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2119 g_variant_get(vret, "(u)", &pid);
2120 g_variant_unref(vret);
2125 int dbus_handle_get_sender_pid(dbus_handle_h handle, const char * sender)
2130 dh = _dbus_handle_get_default_connection();
2132 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2137 _E("wrong dbus handle. connection is null");
2142 return dbus_connection_get_sender_pid(dh->conn, sender);
2145 int dbus_handle_get_sender_credentials(dbus_handle_h handle, const char *name, GDBusCredentials *creds)
2148 GVariant *vret = NULL;
2150 GVariantIter *iter = NULL;
2155 dh = _dbus_handle_get_default_connection();
2157 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2161 vret = g_dbus_connection_call_sync(dh->conn,
2164 DBUS_INTERFACE_NAME,
2165 "GetConnectionCredentials",
2166 g_variant_new("(s)", name),
2168 G_DBUS_CALL_FLAGS_NONE,
2173 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2177 g_variant_get(vret, "(a{sv})", &iter);
2179 while (g_variant_iter_loop(iter, "{sv}", &item, &sub)) {
2180 if (!g_strcmp0(item, "UnixUserID")) {
2181 g_variant_get(sub, "u", &creds->uid);
2182 //_D("UnixUserID %u", creds->uid);
2183 } else if (!g_strcmp0(item, "ProcessID")) {
2184 g_variant_get(sub, "u", &creds->pid);
2185 //_D("ProcessID %u", creds->pid);
2186 } else if (!g_strcmp0(item, "LinuxSecurityLabel")) {
2187 g_variant_get(sub, "^ay", &creds->sec_label);
2188 //_D("%s", creds->sec_label);
2193 g_variant_iter_free(iter);
2195 g_variant_unref(vret);
2200 void _destroy_notify_watch_name(gpointer data)
2206 int dbus_handle_watch_name(const char *name,
2207 GBusNameAppearedCallback name_appeared_handler,
2208 GBusNameVanishedCallback name_vanished_handler,
2210 GDestroyNotify user_data_free_func)
2215 _E("wrong name name is null");
2218 if (!name_appeared_handler && !name_vanished_handler) {
2219 _E("both function pointers are null");
2223 id = g_bus_watch_name(dbus_handle_get_default_bus_type(),
2225 G_BUS_NAME_WATCHER_FLAGS_NONE,
2226 name_appeared_handler,
2227 name_vanished_handler,
2229 user_data_free_func ? user_data_free_func : _destroy_notify_watch_name);
2231 _E("failed to g_bus_watch_name");
2238 void dbus_handle_unwatch_name(guint id)
2241 _E("wrong id %d", id);
2244 g_bus_unwatch_name(id);
2247 int _get_cmdline_name(pid_t pid, char *cmdline, size_t cmdline_size)
2250 char buf[PATH_MAX + 1];
2253 snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
2254 fd = open(buf, O_RDONLY);
2260 ret = read(fd, buf, PATH_MAX);
2265 buf[PATH_MAX] = '\0';
2267 filename = strrchr(buf, '/');
2268 if (filename == NULL)
2271 filename = filename + 1;
2273 if (cmdline_size < strlen(filename) + 1) {
2278 strncpy(cmdline, filename, cmdline_size - 1);
2279 cmdline[cmdline_size - 1] = '\0';
2284 char **dbus_handle_get_owner_list(dbus_handle_h handle, const char *bus_name)
2288 GVariant *vret = NULL;
2289 GVariantIter *iter = NULL;
2290 gchar **strv = NULL;
2295 _E("wrong parameter bus_name is null");
2300 dh = _dbus_handle_get_default_connection();
2302 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2307 vret = g_dbus_connection_call_sync(dh->conn,
2308 "org.freedesktop.DBus",
2310 "org.freedesktop.DBus",
2312 g_variant_new("(s)", bus_name),
2314 G_DBUS_CALL_FLAGS_NONE,
2319 _E("failed to g_dbus_connection_call_sync:%s", err->message);
2324 g_variant_get(vret, "(as)", &iter);
2325 strv = g_new(gchar *, g_variant_iter_n_children(iter) + 1);
2328 while (g_variant_iter_loop(iter, "s", &str))
2329 strv[i++] = g_strdup(str);
2332 g_variant_iter_free(iter);
2333 g_variant_unref(vret);
2338 void dbus_handle_check_owner_name(dbus_handle_h handle, const char *owner_name)
2341 char exe_name[PATH_MAX];
2347 dh = _dbus_handle_get_default_connection();
2349 _E("failed to get default connection, bustype:%d", (int)dbus_handle_get_default_bus_type());
2354 strv = dbus_handle_get_owner_list(dh, owner_name);
2356 _E("failed to get owner list of %s", owner_name);
2360 for (i = 0; strv[i] != NULL; ++i) {
2361 pid = dbus_handle_get_sender_pid(dh, strv[i]);
2362 if (_get_cmdline_name(pid, exe_name, PATH_MAX) != 0)
2364 _I("%s(%d)", exe_name, pid);
2370 int check_systemd_active(void)
2373 GVariant *msg = NULL;
2374 GVariant *var = NULL;
2377 _I("%s %s", "org.freedesktop.systemd1.Unit", "ActiveState");
2379 msg = dbus_handle_method_sync_with_reply_var("org.freedesktop.systemd1",
2380 "/org/freedesktop/systemd1/unit/default_2etarget",
2381 "org.freedesktop.DBus.Properties",
2383 g_variant_new("(ss)", "org.freedesktop.systemd1.Unit", "ActiveState"));
2387 if (!g_variant_get_safe(msg, "(v)", &var)) {
2388 _E("reply is not variant type");
2392 if (!g_variant_get_safe(var, "(s)", &state)) {
2393 _E("variant doesn't have string (%s)", g_variant_get_type_string(var));
2398 if (strncmp(state, "active", 6) == 0)
2404 g_variant_unref(var);
2406 g_variant_unref(msg);
2411 GVariant *dbus_handle_make_simple_array(const char *sig, int *param)
2413 GVariantBuilder *builder = NULL;
2414 GVariant *var = NULL;
2418 builder = g_variant_builder_new(G_VARIANT_TYPE(sig));
2420 _E("failed to g_variant_builder_new");
2425 g_variant_builder_add(builder, "i", param[i++]);
2427 snprintf(format, sizeof(format) - 1, "(%s)", sig);
2428 var = g_variant_new(format, builder);
2429 g_variant_builder_unref(builder);