ladishd: rework loader interface
[ladish.git] / daemon / app_supervisor.c
blob790187bead67e862ce9daae71477d0e8feaa9f43
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
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"
30 #include "loader.h"
32 struct ladish_app
34 struct list_head siblings;
35 uint64_t id;
36 char * name;
37 char * commandline;
40 struct ladish_app_supervisor
42 char * name;
43 char * opath;
44 uint64_t version;
45 uint64_t next_id;
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");
57 return false;
60 supervisor_ptr->opath = strdup(opath);
61 if (supervisor_ptr->opath == NULL)
63 log_error("strdup() failed for app supervisor opath");
64 free(supervisor_ptr);
65 return false;
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);
73 free(supervisor_ptr);
74 return false;
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;
84 return true;
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);
97 free(app_ptr->name);
98 free(app_ptr->commandline);
99 free(app_ptr);
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)
121 goto fail;
124 dbus_message_iter_init_append(call_ptr->reply, &iter);
126 if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT64, &supervisor_ptr->version))
128 goto fail_unref;
131 if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ts)", &array_iter))
133 goto fail_unref;
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))
142 goto fail_unref;
145 if (!dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT64, &app_ptr->id))
147 goto fail_unref;
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))
153 goto fail_unref;
156 if (!dbus_message_iter_close_container(&array_iter, &struct_iter))
158 goto fail_unref;
162 if (!dbus_message_iter_close_container(&iter, &array_iter))
164 goto fail_unref;
167 return;
169 fail_unref:
170 dbus_message_unref(call_ptr->reply);
171 call_ptr->reply = NULL;
173 fail:
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;
181 pid_t pid;
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);
187 return;
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);
195 return;
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")
208 METHOD_ARGS_END
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")
213 METHOD_ARGS_END
215 METHODS_BEGIN
216 METHOD_DESCRIBE(GetAll, get_all)
217 METHOD_DESCRIBE(RunCustom, run_custom)
218 METHODS_END
220 SIGNALS_BEGIN
221 SIGNALS_END
223 INTERFACE_BEGIN(g_iface_app_supervisor, IFACE_APP_SUPERVISOR)
224 INTERFACE_DEFAULT_HANDLER
225 INTERFACE_EXPOSE_METHODS
226 INTERFACE_EXPOSE_SIGNALS
227 INTERFACE_END