afm-run: fix bug in handling pids
[src/app-framework-main.git] / src / afm-run.c
index 4e002e0..915230d 100644 (file)
@@ -32,8 +32,9 @@
 #include "verbose.h"
 #include "utils-dir.h"
 #include "utils-json.h"
-#include "afm-run.h"
+#include "afm-launch-mode.h"
 #include "afm-launch.h"
+#include "afm-run.h"
 
 enum appstate {
        as_starting,
@@ -63,6 +64,21 @@ static int runnerid = 0;
 static const char fwk_user_app_dir[] = FWK_USER_APP_DIR;
 static char *homeappdir;
 
+/****************** manages pids **********************/
+
+/* get a runner by its pid */
+static struct apprun *runner_of_pid(pid_t pid)
+{
+       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 pgids **********************/
 
 /* get a runner by its pgid */
@@ -77,7 +93,7 @@ static struct apprun *runner_of_pgid(pid_t pgid)
 /* insert a runner for its pgid */
 static void pgid_insert(struct apprun *runner)
 {
-       struct apprun **prev = &runners_by_runid[(int)(runner->pids[0] & (ROOT_RUNNERS_COUNT - 1))];
+       struct apprun **prev = &runners_by_pgid[(int)(runner->pids[0] & (ROOT_RUNNERS_COUNT - 1))];
        runner->next_by_pgid = *prev;
        *prev = runner;
 }
@@ -85,24 +101,14 @@ static void pgid_insert(struct apprun *runner)
 /* remove a runner for its pgid */
 static void pgid_remove(struct apprun *runner)
 {
-       struct apprun **prev = &runners_by_runid[(int)(runner->pids[0] & (ROOT_RUNNERS_COUNT - 1))];
-       runner->next_by_pgid = *prev;
-       *prev = runner;
-}
-
-/****************** manages pids **********************/
-
-/* 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;
+       struct apprun **prev = &runners_by_pgid[(int)(runner->pids[0] & (ROOT_RUNNERS_COUNT - 1))];
+       while (*prev) {
+               if (*prev == runner) {
+                       *prev = runner->next_by_pgid;
+                       break;
+               }
+               prev = &(*prev)->next_by_pgid;
        }
-       return result;
 }
 
 /****************** manages runners (by runid) **********************/
@@ -214,7 +220,7 @@ static void on_sigchld(int signum, siginfo_t *info, void *uctxt)
 {
        struct apprun *runner;
 
-       runner = runner_of_pgid(info->si_pid);
+       runner = runner_of_pid(info->si_pid);
        if (!runner)
                return;
 
@@ -225,6 +231,7 @@ static void on_sigchld(int signum, siginfo_t *info, void *uctxt)
        case CLD_TRAPPED:
                runner->state = as_terminated;
                pgid_remove(runner);
+               killpg(runner->pids[0], SIGKILL);
                break;
 
        case CLD_STOPPED:
@@ -239,10 +246,12 @@ static void on_sigchld(int signum, siginfo_t *info, void *uctxt)
 
 /**************** handle afm_launch_desc *********************/
 
-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(!j_read_object_at(appli, "public", &pub)
        || !j_read_string_at(appli, "path", &desc->path)
@@ -265,20 +274,25 @@ static int fill_launch_desc(struct json_object *appli, struct afm_launch_desc *d
 
        /* 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);
@@ -291,7 +305,7 @@ int afm_run_start(struct json_object *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);