ladishd: maintain list of currently running apps
This commit is contained in:
parent
8acc3ee6d2
commit
6b7103ead6
|
@ -24,6 +24,8 @@
|
|||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "app_supervisor.h"
|
||||
#include "../dbus/error.h"
|
||||
#include "../dbus_constants.h"
|
||||
|
@ -35,6 +37,7 @@ struct ladish_app
|
|||
uint64_t id;
|
||||
char * name;
|
||||
char * commandline;
|
||||
pid_t pid;
|
||||
};
|
||||
|
||||
struct ladish_app_supervisor
|
||||
|
@ -84,6 +87,23 @@ bool ladish_app_supervisor_create(ladish_app_supervisor_handle * supervisor_hand
|
|||
return true;
|
||||
}
|
||||
|
||||
struct ladish_app * ladish_app_supervisor_find_app_by_name(struct ladish_app_supervisor * supervisor_ptr, const char * name)
|
||||
{
|
||||
struct list_head * node_ptr;
|
||||
struct ladish_app * app_ptr;
|
||||
|
||||
list_for_each(node_ptr, &supervisor_ptr->applist)
|
||||
{
|
||||
app_ptr = list_entry(node_ptr, struct ladish_app, siblings);
|
||||
if (strcmp(app_ptr->name, name) == 0)
|
||||
{
|
||||
return app_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define supervisor_ptr ((struct ladish_app_supervisor *)supervisor_handle)
|
||||
|
||||
void ladish_app_supervisor_destroy(ladish_app_supervisor_handle supervisor_handle)
|
||||
|
@ -104,6 +124,28 @@ void ladish_app_supervisor_destroy(ladish_app_supervisor_handle supervisor_handl
|
|||
free(supervisor_ptr);
|
||||
}
|
||||
|
||||
bool ladish_app_supervisor_child_exit(ladish_app_supervisor_handle supervisor_handle, pid_t pid)
|
||||
{
|
||||
struct list_head * node_ptr;
|
||||
struct ladish_app * app_ptr;
|
||||
|
||||
list_for_each(node_ptr, &supervisor_ptr->applist)
|
||||
{
|
||||
app_ptr = list_entry(node_ptr, struct ladish_app, siblings);
|
||||
if (app_ptr->pid == pid)
|
||||
{
|
||||
log_info("exit of studio child '%s' detected.", app_ptr->name);
|
||||
list_del(&app_ptr->siblings);
|
||||
free(app_ptr->name);
|
||||
free(app_ptr->commandline);
|
||||
free(app_ptr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#undef supervisor_ptr
|
||||
#define supervisor_ptr ((struct ladish_app_supervisor *)call_ptr->iface_context)
|
||||
|
||||
|
@ -178,24 +220,111 @@ static void run_custom(struct dbus_method_call * call_ptr)
|
|||
{
|
||||
dbus_bool_t terminal;
|
||||
const char * commandline;
|
||||
pid_t pid;
|
||||
const char * name_param;
|
||||
char * name;
|
||||
size_t len;
|
||||
char * end;
|
||||
unsigned int index;
|
||||
struct ladish_app * app_ptr;
|
||||
|
||||
if (!dbus_message_get_args(call_ptr->message, &g_dbus_error, DBUS_TYPE_BOOLEAN, &terminal, DBUS_TYPE_STRING, &commandline, DBUS_TYPE_INVALID))
|
||||
if (!dbus_message_get_args(
|
||||
call_ptr->message,
|
||||
&g_dbus_error,
|
||||
DBUS_TYPE_BOOLEAN, &terminal,
|
||||
DBUS_TYPE_STRING, &commandline,
|
||||
DBUS_TYPE_STRING, &name_param,
|
||||
DBUS_TYPE_INVALID))
|
||||
{
|
||||
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_INVALID_ARGS, "Invalid arguments to method \"%s\": %s", call_ptr->method_name, g_dbus_error.message);
|
||||
dbus_error_free(&g_dbus_error);
|
||||
return;
|
||||
}
|
||||
|
||||
log_info("run_custom(%s,'%s') called", terminal ? "terminal" : "shell", commandline);
|
||||
log_info("run_custom('%s', %s, '%s') called", name_param, terminal ? "terminal" : "shell", commandline);
|
||||
|
||||
if (!loader_execute(supervisor_ptr->name, "xxx", "/", terminal, commandline, &pid))
|
||||
if (*name_param)
|
||||
{
|
||||
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "Execution of '%s' failed", commandline);
|
||||
/* allocate and copy app name */
|
||||
len = strlen(name_param);
|
||||
name = malloc(len + 100);
|
||||
if (name == NULL)
|
||||
{
|
||||
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "malloc of app name failed");
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(name, name_param);
|
||||
|
||||
end = name + len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* allocate app name */
|
||||
len = strlen(commandline) + 100;
|
||||
name = malloc(len);
|
||||
if (name == NULL)
|
||||
{
|
||||
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "malloc of app name failed");
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(name, commandline);
|
||||
|
||||
/* use first word as name */
|
||||
end = name;
|
||||
while (*end)
|
||||
{
|
||||
if (isspace(*end))
|
||||
{
|
||||
*end = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
end++;
|
||||
}
|
||||
}
|
||||
|
||||
/* make the app name unique */
|
||||
index = 2;
|
||||
while (ladish_app_supervisor_find_app_by_name(supervisor_ptr, name) != NULL)
|
||||
{
|
||||
sprintf(end, "-%u", index);
|
||||
index++;
|
||||
}
|
||||
|
||||
app_ptr = malloc(sizeof(struct ladish_app));
|
||||
if (app_ptr == NULL)
|
||||
{
|
||||
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "malloc of struct ladish_app failed");
|
||||
free(name);
|
||||
return;
|
||||
}
|
||||
|
||||
log_info("pid is %lu", (unsigned long)pid);
|
||||
app_ptr->id = supervisor_ptr->next_id++;
|
||||
app_ptr->name = name;
|
||||
app_ptr->commandline = strdup(commandline);
|
||||
app_ptr->pid = 0;
|
||||
if (app_ptr->commandline == NULL)
|
||||
{
|
||||
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "strdup() failed for commandline");
|
||||
free(app_ptr);
|
||||
free(name);
|
||||
return;
|
||||
}
|
||||
|
||||
list_add_tail(&app_ptr->siblings, &supervisor_ptr->applist);
|
||||
|
||||
if (!loader_execute(supervisor_ptr->name, name, "/", terminal, commandline, &app_ptr->pid))
|
||||
{
|
||||
lash_dbus_error(call_ptr, LASH_DBUS_ERROR_GENERIC, "Execution of '%s' failed", commandline);
|
||||
list_del(&app_ptr->siblings);
|
||||
free(app_ptr->commandline);
|
||||
free(app_ptr);
|
||||
free(name);
|
||||
return;
|
||||
}
|
||||
|
||||
log_info("%s pid is %lu", app_ptr->name, (unsigned long)app_ptr->pid);
|
||||
|
||||
method_return_new_void(call_ptr);
|
||||
}
|
||||
|
@ -210,6 +339,7 @@ METHOD_ARGS_END
|
|||
METHOD_ARGS_BEGIN(RunCustom, "Start application by supplying commandline")
|
||||
METHOD_ARG_DESCRIBE_IN("terminal", "b", "Whether to run in terminal")
|
||||
METHOD_ARG_DESCRIBE_IN("commandline", "s", "Commandline")
|
||||
METHOD_ARG_DESCRIBE_IN("name", "s", "Name")
|
||||
METHOD_ARGS_END
|
||||
|
||||
METHODS_BEGIN
|
||||
|
|
|
@ -34,6 +34,8 @@ typedef struct ladish_app_supervisor_tag { int unused; } * ladish_app_supervisor
|
|||
bool ladish_app_supervisor_create(ladish_app_supervisor_handle * supervisor_handle_ptr, const char * opath, const char * name);
|
||||
void ladish_app_supervisor_destroy(ladish_app_supervisor_handle supervisor_handle);
|
||||
|
||||
bool ladish_app_supervisor_child_exit(ladish_app_supervisor_handle supervisor_handle, pid_t pid);
|
||||
|
||||
extern const struct dbus_interface_descriptor g_iface_app_supervisor;
|
||||
|
||||
#endif /* #ifndef APP_SUPERVISOR_H__712E6589_DCB1_4CE9_9812_4F250D55E8A2__INCLUDED */
|
||||
|
|
|
@ -182,11 +182,6 @@ static void disconnect_dbus(void)
|
|||
dbus_connection_unref(g_dbus_connection);
|
||||
}
|
||||
|
||||
static void on_child_exit(pid_t pid)
|
||||
{
|
||||
//client_disconnected(server_find_client_by_pid(child_ptr->pid));
|
||||
}
|
||||
|
||||
void term_signal_handler(int signum)
|
||||
{
|
||||
log_info("Caught signal %d (%s), terminating", signum, strsignal(signum));
|
||||
|
@ -269,7 +264,7 @@ int main(int argc, char ** argv, char ** envp)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
loader_init(on_child_exit);
|
||||
loader_init(studio_on_child_exit);
|
||||
|
||||
if (!connect_dbus())
|
||||
{
|
||||
|
|
|
@ -327,6 +327,14 @@ void studio_uninit(void)
|
|||
log_info("studio object destroy");
|
||||
}
|
||||
|
||||
void studio_on_child_exit(pid_t pid)
|
||||
{
|
||||
if (!ladish_app_supervisor_child_exit(g_studio.app_supervisor, pid))
|
||||
{
|
||||
log_error("non-studio child exit detected. pid is %llu", (unsigned long long)pid);
|
||||
}
|
||||
}
|
||||
|
||||
bool studio_is_loaded(void)
|
||||
{
|
||||
return g_studio.dbus_object != NULL;
|
||||
|
|
|
@ -35,4 +35,6 @@ bool studio_is_loaded(void);
|
|||
bool studios_iterate(void * call_ptr, void * context, bool (* callback)(void * call_ptr, void * context, const char * studio, uint32_t modtime));
|
||||
bool studio_delete(void * call_ptr, const char * studio_name);
|
||||
|
||||
void studio_on_child_exit(pid_t pid);
|
||||
|
||||
#endif /* #ifndef STUDIO_H__0BEDE85E_4FB3_4D74_BC08_C373A22409C0__INCLUDED */
|
||||
|
|
Loading…
Reference in New Issue