+static void on_sigchld(int signum, siginfo_t *info, void *uctxt)
+{
+ struct apprun *runner;
+
+ runner = runner_of_pgid(info->si_pid);
+ if (!runner)
+ return;
+
+ switch(info->si_code) {
+ case CLD_EXITED:
+ case CLD_KILLED:
+ case CLD_DUMPED:
+ case CLD_TRAPPED:
+ runner->state = as_terminated;
+ pgid_remove(runner);
+ break;
+
+ case CLD_STOPPED:
+ runner->state = as_stopped;
+ break;
+
+ case CLD_CONTINUED:
+ runner->state = as_running;
+ break;
+ }
+}
+
+/**************** handle af_launch_desc *********************/
+
+static int get_jstr(struct json_object *obj, const char *key, const char **value)
+{
+ json_object *data;
+ return json_object_object_get_ex(obj, key, &data)
+ && json_object_get_type(data) == json_type_string
+ && (*value = json_object_get_string(data)) != NULL;
+}
+
+static int get_jint(struct json_object *obj, const char *key, int *value)
+{
+ json_object *data;
+ return json_object_object_get_ex(obj, key, &data)
+ && json_object_get_type(data) == json_type_int
+ && ((*value = (int)json_object_get_int(data)), 1);
+}
+
+static int fill_launch_desc(struct json_object *appli, struct af_launch_desc *desc)
+{
+ json_object *pub;
+
+ /* main items */
+ if(!json_object_object_get_ex(appli, "public", &pub)
+ || !get_jstr(appli, "path", &desc->path)
+ || !get_jstr(appli, "id", &desc->tag)
+ || !get_jstr(appli, "content", &desc->content)
+ || !get_jstr(appli, "type", &desc->type)
+ || !get_jstr(pub, "name", &desc->name)
+ || !get_jint(pub, "width", &desc->width)
+ || !get_jint(pub, "height", &desc->height)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* plugins */
+ {
+ /* TODO */
+ static const char *null = NULL;
+ desc->plugins = &null;
+ }
+
+ /* finaly */
+ desc->home = homeappdir;
+ return 0;