add handler for SIG_CHLD
This commit is contained in:
@@ -13,6 +13,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include "getopt.h"
|
#include "getopt.h"
|
||||||
|
|
||||||
@@ -73,6 +75,9 @@ static int process_response(char *str);
|
|||||||
static int exec_command(MenuEntry *cmd);
|
static int exec_command(MenuEntry *cmd);
|
||||||
static int main_loop(void);
|
static int main_loop(void);
|
||||||
|
|
||||||
|
static pid_t last_child_pid = 0;
|
||||||
|
static int last_child_status = 0;
|
||||||
|
static void sigchld_handler(int);
|
||||||
|
|
||||||
#define CHAIN(e,f) { if (e>=0) { e=(f); }}
|
#define CHAIN(e,f) { if (e>=0) { e=(f); }}
|
||||||
#define CHAIN_END(e) { if (e<0) { report(RPT_CRIT,"Critical error, abort"); exit(e); }}
|
#define CHAIN_END(e) { if (e<0) { report(RPT_CRIT,"Critical error, abort"); exit(e); }}
|
||||||
@@ -81,6 +86,7 @@ static int main_loop(void);
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
struct sigaction sa;
|
||||||
|
|
||||||
CHAIN(error, process_command_line(argc, argv));
|
CHAIN(error, process_command_line(argc, argv));
|
||||||
if (configfile == NULL)
|
if (configfile == NULL)
|
||||||
@@ -103,12 +109,47 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* setup signal handler for children to avoid zombies */
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
|
||||||
|
sa.sa_handler = sigchld_handler;
|
||||||
|
sigaction(SIGCHLD, &sa, NULL);
|
||||||
|
|
||||||
main_loop();
|
main_loop();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* the grim reaper ;-) */
|
||||||
|
static void sigchld_handler(int signal)
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if ((pid = wait(&status)) != -1) {
|
||||||
|
last_child_pid = pid;
|
||||||
|
last_child_status = status;
|
||||||
|
|
||||||
|
// better:
|
||||||
|
// - build a queue with (pid,status) pairs (here)
|
||||||
|
// - show a screen for each pair (in the main_loop)
|
||||||
|
// - remove elements from the queue which are shown (dito)
|
||||||
|
// even better:
|
||||||
|
// - build a queue of (pid, name) on exec (in exec command)
|
||||||
|
// - display a screen about start (in main_loop)
|
||||||
|
// - add status to the appropriate queue element (here)
|
||||||
|
// - display screen about exit (in main_loop)
|
||||||
|
// - remove elements from the queue which are shown (dito)
|
||||||
|
// screens should be shown in main_loop to
|
||||||
|
// - not show a startup screen when the command is already done
|
||||||
|
// (note: danger for a race between sig_handler and main_loop,
|
||||||
|
// in the 1st case above, since both work on the queue)
|
||||||
|
// - automatically time screens
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int process_command_line(int argc, char **argv)
|
static int process_command_line(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|||||||
Reference in New Issue
Block a user