ladishd: maintain list of currently running apps

This commit is contained in:
Nedko Arnaudov 2009-11-30 23:45:14 +02:00
parent 8acc3ee6d2
commit 6b7103ead6
5 changed files with 149 additions and 12 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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())
{

View File

@ -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;

View File

@ -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 */