From 2c3c3f0290275f65e55899a9fb69cb8709932d5f Mon Sep 17 00:00:00 2001 From: Nedko Arnaudov Date: Tue, 9 Oct 2012 02:32:42 +0300 Subject: [PATCH] Don't notify user about unexpectedly stopped apps that returned 0 exit code. Fixes #197 The exit code detection for apps ran in terminal is not working, at least with xterm. xterm doesnt seem to be able to return exit code of its child process. --- daemon/app_supervisor.c | 11 +++++++---- daemon/app_supervisor.h | 8 +++++--- daemon/loader.c | 16 +++++++++------- daemon/loader.h | 4 ++-- daemon/studio.c | 8 +++++--- daemon/studio.h | 4 ++-- 6 files changed, 30 insertions(+), 21 deletions(-) diff --git a/daemon/app_supervisor.c b/daemon/app_supervisor.c index 1909cdd3..dc34857d 100644 --- a/daemon/app_supervisor.c +++ b/daemon/app_supervisor.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov + * Copyright (C) 2009, 2010, 2011, 2012 Nedko Arnaudov * ************************************************************************** * This file contains implementation of app supervisor object @@ -903,17 +903,20 @@ ladish_app_supervisor_set_project_name( return true; } -bool ladish_app_supervisor_child_exit(ladish_app_supervisor_handle supervisor_handle, pid_t pid) +bool ladish_app_supervisor_child_exit(ladish_app_supervisor_handle supervisor_handle, pid_t pid, int exit_status) { struct list_head * node_ptr; struct ladish_app * app_ptr; + bool clean; 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 child '%s' detected.", app_ptr->name); + clean = WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == 0; + + log_info("%s exit of child '%s' detected.", clean ? "clean" : "dirty", app_ptr->name); app_ptr->pid = 0; app_ptr->pgrp = 0; @@ -926,7 +929,7 @@ bool ladish_app_supervisor_child_exit(ladish_app_supervisor_handle supervisor_ha } else { - if (app_ptr->state == LADISH_APP_STATE_STARTED) + if (app_ptr->state == LADISH_APP_STATE_STARTED && !clean) { ladish_notify_simple(LADISH_NOTIFY_URGENCY_HIGH, "App terminated unexpectedly", app_ptr->name); } diff --git a/daemon/app_supervisor.h b/daemon/app_supervisor.h index 62ffadd4..cc6ed528 100644 --- a/daemon/app_supervisor.h +++ b/daemon/app_supervisor.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov + * Copyright (C) 2009, 2010, 2011, 2012 Nedko Arnaudov * ************************************************************************** * This file contains interface to app supervisor object @@ -165,12 +165,14 @@ ladish_app_supervisor_set_project_name( * This function is called to mark that app has quit. Must not be called from signal handler because app supervisor object is not thread safe. * * @param[in] supervisor_handle supervisor object handle - * @param[in] pid of the app whose termination was detected + * @param[in] pid pid of the app whose termination was detected + * @param[in] exit_statis process exit status as returned by waitpid() */ bool ladish_app_supervisor_child_exit( ladish_app_supervisor_handle supervisor_handle, - pid_t pid); + pid_t pid, + int exit_status); /** * Iterate apps that are owned by supervisor diff --git a/daemon/loader.c b/daemon/loader.c index 37fb94fa..aa0030a9 100644 --- a/daemon/loader.c +++ b/daemon/loader.c @@ -55,6 +55,7 @@ struct loader_child char * project_name; bool dead; + int exit_status; pid_t pid; bool terminal; @@ -72,11 +73,11 @@ struct loader_child char * stderr_buffer_ptr; }; -static void (* g_on_child_exit)(pid_t pid); +static void (* g_on_child_exit)(pid_t pid, int exit_status); static struct list_head g_childs_list; static struct loader_child * -loader_child_find_and_mark_dead(pid_t pid) +loader_child_find(pid_t pid) { struct list_head *node_ptr; struct loader_child *child_ptr; @@ -86,7 +87,6 @@ loader_child_find_and_mark_dead(pid_t pid) child_ptr = list_entry(node_ptr, struct loader_child, siblings); if (child_ptr->pid == pid) { - child_ptr->dead = true; return child_ptr; } } @@ -153,7 +153,7 @@ loader_childs_bury(void) close(child_ptr->stderr); } - g_on_child_exit(child_ptr->pid); + g_on_child_exit(child_ptr->pid, child_ptr->exit_status); free(child_ptr); } } @@ -168,7 +168,7 @@ static void loader_sigchld_handler(int signum) while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { - child_ptr = loader_child_find_and_mark_dead(pid); + child_ptr = loader_child_find(pid); if (!child_ptr) { @@ -177,11 +177,13 @@ static void loader_sigchld_handler(int signum) else { log_info("Termination of child process '%s' with PID %llu detected", child_ptr->app_name, (unsigned long long)pid); + child_ptr->dead = true; + child_ptr->exit_status = status; } if (WIFEXITED(status)) { - log_info("Child exited, status=%d", WEXITSTATUS(status)); + log_info("Child exited, code=%d", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { @@ -205,7 +207,7 @@ static void loader_sigchld_handler(int signum) } } -void loader_init(void (* on_child_exit)(pid_t pid)) +void loader_init(void (* on_child_exit)(pid_t pid, int exit_status)) { g_on_child_exit = on_child_exit; signal(SIGCHLD, loader_sigchld_handler); diff --git a/daemon/loader.h b/daemon/loader.h index f2ee99f6..537bbdb8 100644 --- a/daemon/loader.h +++ b/daemon/loader.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov + * Copyright (C) 2009, 2010, 2011, 2012 Nedko Arnaudov * ************************************************************************** * This file contains interface to the code that starts programs @@ -27,7 +27,7 @@ #ifndef __LASHD_LOADER_H__ #define __LASHD_LOADER_H__ -void loader_init(void (* on_child_exit)(pid_t pid)); +void loader_init(void (* on_child_exit)(pid_t pid, int exit_status)); bool loader_execute( diff --git a/daemon/studio.c b/daemon/studio.c index 61c8c0db..fcbbd8ec 100644 --- a/daemon/studio.c +++ b/daemon/studio.c @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010, 2011 Nedko Arnaudov + * Copyright (C) 2009, 2010, 2011, 2012 Nedko Arnaudov * ************************************************************************** * This file contains part of the studio singleton object implementation @@ -655,6 +655,7 @@ void ladish_studio_uninit(void) struct on_child_exit_context { pid_t pid; + int exit_status; bool found; }; @@ -667,7 +668,7 @@ ladish_studio_on_child_exit_callback( ladish_graph_handle graph, ladish_app_supervisor_handle app_supervisor) { - child_exit_context_ptr->found = ladish_app_supervisor_child_exit(app_supervisor, child_exit_context_ptr->pid); + child_exit_context_ptr->found = ladish_app_supervisor_child_exit(app_supervisor, child_exit_context_ptr->pid, child_exit_context_ptr->exit_status); /* if child is found, return false - it will cause iteration to stop */ /* if child is not found, return true - it will cause next supervisor to be checked */ return !child_exit_context_ptr->found; @@ -675,11 +676,12 @@ ladish_studio_on_child_exit_callback( #undef child_exit_context_ptr -void ladish_studio_on_child_exit(pid_t pid) +void ladish_studio_on_child_exit(pid_t pid, int exit_status) { struct on_child_exit_context context; context.pid = pid; + context.exit_status = exit_status; context.found = false; ladish_studio_iterate_virtual_graphs(&context, ladish_studio_on_child_exit_callback); diff --git a/daemon/studio.h b/daemon/studio.h index 11a01d3c..a40f4154 100644 --- a/daemon/studio.h +++ b/daemon/studio.h @@ -2,7 +2,7 @@ /* * LADI Session Handler (ladish) * - * Copyright (C) 2009, 2010 Nedko Arnaudov + * Copyright (C) 2009, 2010, 2012 Nedko Arnaudov * ************************************************************************** * This file contains interface of the studio singleton object @@ -41,7 +41,7 @@ bool ladish_studio_is_started(void); bool ladish_studios_iterate(void * call_ptr, void * context, bool (* callback)(void * call_ptr, void * context, const char * studio, uint32_t modtime)); bool ladish_studio_delete(void * call_ptr, const char * studio_name); -void ladish_studio_on_child_exit(pid_t pid); +void ladish_studio_on_child_exit(pid_t pid, int exit_status); bool ladish_studio_iterate_virtual_graphs(