1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2009 Nedko Arnaudov <nedko@arnaudov.name>
7 **************************************************************************
8 * This file contains implementation of app supervisor object
9 **************************************************************************
11 * LADI Session Handler is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * LADI Session Handler is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
23 * or write to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "app_supervisor.h"
28 #include "../dbus/error.h"
29 #include "../dbus_constants.h"
34 struct list_head siblings
;
40 struct ladish_app_supervisor
46 struct list_head applist
;
49 bool ladish_app_supervisor_create(ladish_app_supervisor_handle
* supervisor_handle_ptr
, const char * opath
, const char * name
)
51 struct ladish_app_supervisor
* supervisor_ptr
;
53 supervisor_ptr
= malloc(sizeof(struct ladish_app_supervisor
));
54 if (supervisor_ptr
== NULL
)
56 log_error("malloc() failed to allocate struct ladish_app_supervisor");
60 supervisor_ptr
->opath
= strdup(opath
);
61 if (supervisor_ptr
->opath
== NULL
)
63 log_error("strdup() failed for app supervisor opath");
68 supervisor_ptr
->name
= strdup(name
);
69 if (supervisor_ptr
->name
== NULL
)
71 log_error("strdup() failed for app supervisor name");
72 free(supervisor_ptr
->opath
);
77 supervisor_ptr
->version
= 0;
78 supervisor_ptr
->next_id
= 1;
80 INIT_LIST_HEAD(&supervisor_ptr
->applist
);
82 *supervisor_handle_ptr
= (ladish_app_supervisor_handle
)supervisor_ptr
;
87 #define supervisor_ptr ((struct ladish_app_supervisor *)supervisor_handle)
89 void ladish_app_supervisor_destroy(ladish_app_supervisor_handle supervisor_handle
)
91 struct ladish_app
* app_ptr
;
93 while (!list_empty(&supervisor_ptr
->applist
))
95 app_ptr
= list_entry(supervisor_ptr
->applist
.next
, struct ladish_app
, siblings
);
96 list_del(&app_ptr
->siblings
);
98 free(app_ptr
->commandline
);
102 free(supervisor_ptr
->name
);
103 free(supervisor_ptr
->opath
);
104 free(supervisor_ptr
);
107 #undef supervisor_ptr
108 #define supervisor_ptr ((struct ladish_app_supervisor *)call_ptr->iface_context)
110 static void get_all(struct dbus_method_call
* call_ptr
)
112 DBusMessageIter iter
, array_iter
, struct_iter
;
113 struct list_head
* node_ptr
;
114 struct ladish_app
* app_ptr
;
116 log_info("get_all called");
118 call_ptr
->reply
= dbus_message_new_method_return(call_ptr
->message
);
119 if (call_ptr
->reply
== NULL
)
124 dbus_message_iter_init_append(call_ptr
->reply
, &iter
);
126 if (!dbus_message_iter_append_basic(&iter
, DBUS_TYPE_UINT64
, &supervisor_ptr
->version
))
131 if (!dbus_message_iter_open_container(&iter
, DBUS_TYPE_ARRAY
, "(ts)", &array_iter
))
136 list_for_each(node_ptr
, &supervisor_ptr
->applist
)
138 app_ptr
= list_entry(node_ptr
, struct ladish_app
, siblings
);
140 if (!dbus_message_iter_open_container (&array_iter
, DBUS_TYPE_STRUCT
, NULL
, &struct_iter
))
145 if (!dbus_message_iter_append_basic(&struct_iter
, DBUS_TYPE_UINT64
, &app_ptr
->id
))
150 log_info("app '%s' (%llu)", app_ptr
->name
, (unsigned long long)app_ptr
->id
);
151 if (!dbus_message_iter_append_basic(&struct_iter
, DBUS_TYPE_STRING
, &app_ptr
->name
))
156 if (!dbus_message_iter_close_container(&array_iter
, &struct_iter
))
162 if (!dbus_message_iter_close_container(&iter
, &array_iter
))
170 dbus_message_unref(call_ptr
->reply
);
171 call_ptr
->reply
= NULL
;
174 log_error("Ran out of memory trying to construct method return");
177 static void run_custom(struct dbus_method_call
* call_ptr
)
179 dbus_bool_t terminal
;
180 const char * commandline
;
183 if (!dbus_message_get_args(call_ptr
->message
, &g_dbus_error
, DBUS_TYPE_BOOLEAN
, &terminal
, DBUS_TYPE_STRING
, &commandline
, DBUS_TYPE_INVALID
))
185 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_INVALID_ARGS
, "Invalid arguments to method \"%s\": %s", call_ptr
->method_name
, g_dbus_error
.message
);
186 dbus_error_free(&g_dbus_error
);
190 log_info("run_custom(%s,'%s') called", terminal
? "terminal" : "shell", commandline
);
192 if (!loader_execute(supervisor_ptr
->name
, "xxx", "/", terminal
, commandline
, &pid
))
194 lash_dbus_error(call_ptr
, LASH_DBUS_ERROR_GENERIC
, "Execution of '%s' failed", commandline
);
198 log_info("pid is %lu", (unsigned long)pid
);
200 method_return_new_void(call_ptr
);
203 #undef supervisor_ptr
205 METHOD_ARGS_BEGIN(GetAll
, "Get list of running apps")
206 METHOD_ARG_DESCRIBE_OUT("list_version", "t", "Version of the list")
207 METHOD_ARG_DESCRIBE_OUT("apps_list", "a(ts)", "List of running apps")
210 METHOD_ARGS_BEGIN(RunCustom
, "Start application by supplying commandline")
211 METHOD_ARG_DESCRIBE_IN("terminal", "b", "Whether to run in terminal")
212 METHOD_ARG_DESCRIBE_IN("commandline", "s", "Commandline")
216 METHOD_DESCRIBE(GetAll
, get_all
)
217 METHOD_DESCRIBE(RunCustom
, run_custom
)
223 INTERFACE_BEGIN(g_iface_app_supervisor
, IFACE_APP_SUPERVISOR
)
224 INTERFACE_DEFAULT_HANDLER
225 INTERFACE_EXPOSE_METHODS
226 INTERFACE_EXPOSE_SIGNALS