forked from enlightenment/efl
If you terminate an exe, make sure it really is terminated.
Check it's pulse, hold a mirror to it's mouth, check for brain activity. Pump another round or two into it, cut off it's head, put a stake through it's heart. Sprinkle holy water over it's corpse, hold a black mass to ask Lucifer if it turned up in hell yet, consult the entrails of rasters three headed chicken. If all else fails, complain that the bitch is still alive, and stronger measures will be needed. SVN revision: 19475
This commit is contained in:
parent
56a0bc26d9
commit
c06b7a851f
|
@ -6,11 +6,20 @@
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
|
|
||||||
|
struct _ecore_exe_dead_exe
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
char *cmd;
|
||||||
|
};
|
||||||
|
|
||||||
static void _ecore_exe_exec_it(const char *exe_cmd);
|
static void _ecore_exe_exec_it(const char *exe_cmd);
|
||||||
static int _ecore_exe_data_read_handler(void *data, Ecore_Fd_Handler *fd_handler);
|
static int _ecore_exe_data_read_handler(void *data, Ecore_Fd_Handler *fd_handler);
|
||||||
static int _ecore_exe_data_write_handler(void *data, Ecore_Fd_Handler *fd_handler);
|
static int _ecore_exe_data_write_handler(void *data, Ecore_Fd_Handler *fd_handler);
|
||||||
static void _ecore_exe_flush(Ecore_Exe *exe);
|
static void _ecore_exe_flush(Ecore_Exe *exe);
|
||||||
static void _ecore_exe_event_exe_data_free(void *data __UNUSED__, void *ev);
|
static void _ecore_exe_event_exe_data_free(void *data __UNUSED__, void *ev);
|
||||||
|
static int _ecore_exe_is_it_alive(pid_t pid);
|
||||||
|
static int _ecore_exe_make_sure_its_dead(void *data);
|
||||||
|
static int _ecore_exe_make_sure_its_really_dead(void *data);
|
||||||
|
|
||||||
static Ecore_Exe *exes = NULL;
|
static Ecore_Exe *exes = NULL;
|
||||||
static char *shell = NULL;
|
static char *shell = NULL;
|
||||||
|
@ -393,6 +402,7 @@ ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
|
||||||
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{ /* Something went wrong, so pull down everything. */
|
{ /* Something went wrong, so pull down everything. */
|
||||||
|
/* FIXME: should kill it if it managed to start up. */
|
||||||
IF_FN_DEL(_ecore_exe_free, exe);
|
IF_FN_DEL(_ecore_exe_free, exe);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -601,13 +611,24 @@ ecore_exe_continue(Ecore_Exe *exe)
|
||||||
void
|
void
|
||||||
ecore_exe_terminate(Ecore_Exe *exe)
|
ecore_exe_terminate(Ecore_Exe *exe)
|
||||||
{
|
{
|
||||||
|
struct _ecore_exe_dead_exe *dead;
|
||||||
|
|
||||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||||
{
|
{
|
||||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
||||||
"ecore_exe_terminate");
|
"ecore_exe_terminate");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
printf("Sending TERM signal to %s (%d).\n", exe->cmd, exe->pid);
|
||||||
kill(exe->pid, SIGTERM);
|
kill(exe->pid, SIGTERM);
|
||||||
|
|
||||||
|
dead = calloc(1, sizeof(struct _ecore_exe_dead_exe));
|
||||||
|
if (dead)
|
||||||
|
{
|
||||||
|
dead->pid = exe->pid;
|
||||||
|
dead->cmd = strdup(exe->cmd);
|
||||||
|
ecore_timer_add(10.0, _ecore_exe_make_sure_its_dead, dead);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -618,13 +639,24 @@ ecore_exe_terminate(Ecore_Exe *exe)
|
||||||
void
|
void
|
||||||
ecore_exe_kill(Ecore_Exe *exe)
|
ecore_exe_kill(Ecore_Exe *exe)
|
||||||
{
|
{
|
||||||
|
struct _ecore_exe_dead_exe *dead;
|
||||||
|
|
||||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||||
{
|
{
|
||||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
||||||
"ecore_exe_kill");
|
"ecore_exe_kill");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
printf("Sending KILL signal to %s (%d).\n", exe->cmd, exe->pid);
|
||||||
kill(exe->pid, SIGKILL);
|
kill(exe->pid, SIGKILL);
|
||||||
|
|
||||||
|
dead = calloc(1, sizeof(struct _ecore_exe_dead_exe));
|
||||||
|
if (dead)
|
||||||
|
{
|
||||||
|
dead->pid = exe->pid;
|
||||||
|
dead->cmd = strdup(exe->cmd);
|
||||||
|
ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead, dead);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -666,6 +698,90 @@ ecore_exe_hup(Ecore_Exe *exe)
|
||||||
kill(exe->pid, SIGHUP);
|
kill(exe->pid, SIGHUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_ecore_exe_is_it_alive(pid_t pid)
|
||||||
|
{
|
||||||
|
Ecore_Exe *exe;
|
||||||
|
|
||||||
|
/* FIXME: There is no nice, safe, OS independant way to tell if a
|
||||||
|
* particular PID is still alive. I have written code to do so
|
||||||
|
* for my urunlevel busybox applet (http://urunlevel.sourceforge.net/),
|
||||||
|
* but it's for linux only, and still not guaranteed.
|
||||||
|
*
|
||||||
|
* So for now, we just check that a valid Ecore_Exe structure
|
||||||
|
* exists for it. Even that is not a guarantee, as the structure
|
||||||
|
* can be freed without killing the process.
|
||||||
|
*
|
||||||
|
* I think we can safely put exe's into two categories, those users
|
||||||
|
* that care about the life of the exe, and the run and forget type.
|
||||||
|
* The run and forget type starts up the exe, then free's the
|
||||||
|
* Ecore_Exe structure straight away. They can never call any of
|
||||||
|
* the functions that can call this, so we don't worry about them.
|
||||||
|
*
|
||||||
|
* Those user's that care about the life of exe's will keep the
|
||||||
|
* Ecore_Exe structure around, terminate them eventually, or
|
||||||
|
* register for exit events. For these ones the assumption
|
||||||
|
* that valid Ecore_Exe struct == live exe is almost valid.
|
||||||
|
*
|
||||||
|
* I will probably copy my urunlevel code into here someday.
|
||||||
|
*/
|
||||||
|
exe = _ecore_exe_find(pid);
|
||||||
|
if (exe)
|
||||||
|
{
|
||||||
|
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||||
|
return (pid_t) 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (pid_t) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_ecore_exe_make_sure_its_dead(void *data)
|
||||||
|
{
|
||||||
|
struct _ecore_exe_dead_exe *dead;
|
||||||
|
|
||||||
|
dead = data;
|
||||||
|
if (dead)
|
||||||
|
{
|
||||||
|
if (_ecore_exe_is_it_alive(dead->pid))
|
||||||
|
{
|
||||||
|
if (dead->cmd)
|
||||||
|
printf("Sending KILL signal to alledgedly dead %s (%d).\n", dead->cmd, dead->pid);
|
||||||
|
else
|
||||||
|
printf("Sending KILL signal to alledgedly dead PID %d.\n", dead->pid);
|
||||||
|
kill(dead->pid, SIGKILL);
|
||||||
|
ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead, dead);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IF_FREE(dead->cmd);
|
||||||
|
free(dead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_ecore_exe_make_sure_its_really_dead(void *data)
|
||||||
|
{
|
||||||
|
struct _ecore_exe_dead_exe *dead;
|
||||||
|
|
||||||
|
dead = data;
|
||||||
|
if (dead)
|
||||||
|
{
|
||||||
|
if (_ecore_exe_is_it_alive(dead->pid))
|
||||||
|
{
|
||||||
|
if (dead->cmd)
|
||||||
|
printf("%s (%d) is not really dead.\n", dead->cmd, dead->pid);
|
||||||
|
else
|
||||||
|
printf("PID %d is not really dead.\n", dead->pid);
|
||||||
|
}
|
||||||
|
IF_FREE(dead->cmd);
|
||||||
|
free(dead);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_ecore_exe_shutdown(void)
|
_ecore_exe_shutdown(void)
|
||||||
|
|
Loading…
Reference in New Issue