#include "verbose.h"
#include "utils-dir.h"
-#include "afm-run.h"
+#include "utils-json.h"
+#include "afm-launch-mode.h"
#include "afm-launch.h"
+#include "afm-run.h"
enum appstate {
as_starting,
/****************** manages pgids **********************/
+#if 0
/* get a runner by its pgid */
static struct apprun *runner_of_pgid(pid_t pgid)
{
result = result->next_by_pgid;
return result;
}
+#endif
/* insert a runner for its pgid */
static void pgid_insert(struct apprun *runner)
/* get a runner by its pid */
static struct apprun *runner_of_pid(pid_t pid)
{
- /* try avoiding system call */
- struct apprun *result = runner_of_pgid(pid);
- if (result == NULL) {
- result = runner_of_pgid(getpgid(pid));
- if (result && result->pids[1] != pid)
- result = NULL;
- }
- return result;
+ int i;
+ struct apprun *result;
+
+ for (i = 0 ; i < ROOT_RUNNERS_COUNT ; i++)
+ for (result = runners_by_pgid[i] ; result != NULL ; result = result->next_by_pgid)
+ if (result->pids[0] == pid || result->pids[1] == pid)
+ return result;
+ return NULL;
}
/****************** manages runners (by runid) **********************/
{
struct apprun *runner;
- runner = runner_of_pgid(info->si_pid);
+ runner = runner_of_pid(info->si_pid);
if (!runner)
return;
case CLD_TRAPPED:
runner->state = as_terminated;
pgid_remove(runner);
+ killpg(runner->pids[0], SIGKILL);
break;
case CLD_STOPPED:
/**************** handle afm_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 afm_launch_desc *desc)
+static int fill_launch_desc(struct json_object *appli, enum afm_launch_mode mode, struct afm_launch_desc *desc)
{
json_object *pub;
+ assert(launch_mode_is_valid(mode));
+
/* 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)) {
+ if(!j_read_object_at(appli, "public", &pub)
+ || !j_read_string_at(appli, "path", &desc->path)
+ || !j_read_string_at(appli, "id", &desc->tag)
+ || !j_read_string_at(appli, "content", &desc->content)
+ || !j_read_string_at(appli, "type", &desc->type)
+ || !j_read_string_at(pub, "name", &desc->name)
+ || !j_read_integer_at(pub, "width", &desc->width)
+ || !j_read_integer_at(pub, "height", &desc->height)) {
errno = EINVAL;
return -1;
}
/* finaly */
desc->home = homeappdir;
+ desc->mode = mode;
return 0;
};
/**************** API handling ************************/
-int afm_run_start(struct json_object *appli)
+int afm_run_start(struct json_object *appli, enum afm_launch_mode mode, char **uri)
{
static struct apprun *runner;
struct afm_launch_desc desc;
int rc;
sigset_t saved, blocked;
+ assert(launch_mode_is_valid(mode));
+ assert(mode == mode_local || uri != NULL);
+ assert(uri == NULL || *uri == NULL);
+
/* prepare to launch */
- rc = fill_launch_desc(appli, &desc);
+ rc = fill_launch_desc(appli, mode, &desc);
if (rc)
return rc;
runner = createrunner(appli);
sigprocmask(SIG_BLOCK, &blocked, &saved);
/* launch now */
- rc = afm_launch(&desc, runner->pids);
+ rc = afm_launch(&desc, runner->pids, uri);
if (rc < 0) {
/* fork failed */
sigprocmask(SIG_SETMASK, &saved, NULL);
goto error;
/* the runid */
- obj = json_object_new_int(runner->runid);
- if (obj == NULL)
+ if (!j_add_integer(result, "runid", runner->runid))
goto error2;
- json_object_object_add(result, "runid", obj); /* TODO TEST STATUS */
/* the state */
switch(runner->state) {
state = "terminated";
break;
}
- obj = json_object_new_string(state);
- if (obj == NULL)
+ if (!j_add_string(result, "state", state))
goto error2;
- json_object_object_add(result, "state", obj); /* TODO TEST STATUS */
/* the application id */
rc = json_object_object_get_ex(runner->appli, "public", &obj);
assert(rc);
rc = json_object_object_get_ex(obj, "id", &obj);
assert(rc);
- json_object_object_add(result, "id", obj); /* TODO TEST STATUS */
+ if (!j_add(result, "id", obj))
+ goto error2;
json_object_get(obj);
/* done */
/* creates the object */
result = json_object_new_array();
- if (result == NULL) {
- errno = ENOMEM;
- return NULL;
- }
+ if (result == NULL)
+ goto error;
for (i = 0 ; i < ROOT_RUNNERS_COUNT ; i++) {
for (runner = runners_by_runid[i] ; runner ; runner = runner->next_by_runid) {
if (runner->state != as_terminating && runner->state != as_terminated) {
obj = mkstate(runner);
- if (obj == NULL) {
- json_object_put(result);
- return NULL;
+ if (obj == NULL)
+ goto error2;
+ if (json_object_array_add(result, obj) == -1) {
+ json_object_put(obj);
+ goto error2;
}
- /* TODO status ? */
- json_object_array_add(result, obj);
}
}
}
return result;
+
+error2:
+ json_object_put(result);
+error:
+ errno = ENOMEM;
+ return NULL;
}
struct json_object *afm_run_state(int runid)
struct passwd passwd, *pw;
struct sigaction siga;
+ /* init launcher */
+ rc = afm_launch_initialize();
+ if (rc)
+ return rc;
+
/* computes the 'homeappdir' */
me = geteuid();
rc = getpwuid_r(me, &passwd, buf, sizeof buf, &pw);