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.
This commit is contained in:
Nedko Arnaudov 2012-10-09 02:32:42 +03:00
parent a2a17cd392
commit 2c3c3f0290
6 changed files with 30 additions and 21 deletions

View File

@ -2,7 +2,7 @@
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2009, 2010, 2011, 2012 Nedko Arnaudov <nedko@arnaudov.name>
*
**************************************************************************
* 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);
}

View File

@ -2,7 +2,7 @@
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2009, 2010, 2011, 2012 Nedko Arnaudov <nedko@arnaudov.name>
*
**************************************************************************
* 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

View File

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

View File

@ -2,7 +2,7 @@
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2009, 2010, 2011, 2012 Nedko Arnaudov <nedko@arnaudov.name>
*
**************************************************************************
* 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(

View File

@ -2,7 +2,7 @@
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2009, 2010, 2011 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2009, 2010, 2011, 2012 Nedko Arnaudov <nedko@arnaudov.name>
*
**************************************************************************
* 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);

View File

@ -2,7 +2,7 @@
/*
* LADI Session Handler (ladish)
*
* Copyright (C) 2009, 2010 Nedko Arnaudov <nedko@arnaudov.name>
* Copyright (C) 2009, 2010, 2012 Nedko Arnaudov <nedko@arnaudov.name>
*
**************************************************************************
* 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(