efl/legacy/ecore/src/lib/ecore/ecore_exe.c

264 lines
5.6 KiB
C

#include "ecore_private.h"
#include "Ecore.h"
#include <sys/types.h>
#include <signal.h>
#include <unistd.h>
#ifndef WIN32
static Ecore_Exe *exes = NULL;
/**
* @defgroup Ecore_Exe_Basic_Group Process Spawning Functions
*
* Functions that deal with spawned processes.
*/
/**
* Spawns a child process.
*
* This function forks and runs the given command using @c /bin/sh.
*
* Note that the process handle is only valid until a child process
* terminated event is received. After all handlers for the child process
* terminated event have been called, the handle will be freed by Ecore.
*
* @param exe_cmd The command to run with @c /bin/sh.
* @param data Data to attach to the returned process handle.
* @return A process handle to the spawned process.
* @ingroup Ecore_Exe_Basic_Group
*/
Ecore_Exe *
ecore_exe_run(const char *exe_cmd, const void *data)
{
Ecore_Exe *exe;
pid_t pid;
if (!exe_cmd) return NULL;
pid = fork();
if (pid)
{
exe = calloc(1, sizeof(Ecore_Exe));
if (!exe)
{
kill(pid, SIGKILL);
return NULL;
}
ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE);
exe->pid = pid;
exe->data = (void *)data;
exes = _ecore_list_append(exes, exe);
return exe;
}
setsid();
execl("/bin/sh", "/bin/sh", "-c", exe_cmd, NULL);
exit(0);
return NULL;
}
/**
* Frees the given process handle.
*
* Note that the process that the handle represents is unaffected by this
* function.
*
* @param exe The given process handle.
* @return The data attached to the handle when @ref ecore_exe_run was
* called.
* @ingroup Ecore_Exe_Basic_Group
*/
void *
ecore_exe_free(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
"ecore_exe_free");
return NULL;
}
return _ecore_exe_free(exe);
}
/**
* Retrieves the process ID of the given spawned process.
* @param exe Handle to the given spawned process.
* @return The process ID on success. @c -1 otherwise.
* @ingroup Ecore_Exe_Basic_Group
*/
pid_t
ecore_exe_pid_get(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
"ecore_exe_pid_get");
return -1;
}
return exe->pid;
}
/**
* Retrieves the data attached to the given process handle.
* @param exe The given process handle.
* @return The data pointer attached to @p exe.
* @ingroup Ecore_Exe_Basic_Group
*/
void *
ecore_exe_data_get(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
"ecore_exe_data_get");
return NULL;
}
return exe->data;
}
/**
* @defgroup Ecore_Exe_Signal_Group Spawned Process Signal Functions
*
* Functions that send signals to spawned processes.
*/
/**
* Pauses the given process by sending it a @c SIGSTOP signal.
* @param exe Process handle to the given process.
* @ingroup Ecore_Exe_Signal_Group
*/
void
ecore_exe_pause(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
"ecore_exe_pause");
return;
}
kill(exe->pid, SIGSTOP);
}
/**
* Continues the given paused process by sending it a @c SIGCONT signal.
* @param exe Process handle to the given process.
* @ingroup Ecore_Exe_Signal_Group
*/
void
ecore_exe_continue(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
"ecore_exe_continue");
return;
}
kill(exe->pid, SIGCONT);
}
/**
* Sends the given spawned process a terminate (@c SIGTERM) signal.
* @param exe Process handle to the given process.
* @ingroup Ecore_Exe_Signal_Group
*/
void
ecore_exe_terminate(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
"ecore_exe_terminate");
return;
}
kill(exe->pid, SIGTERM);
}
/**
* Kills the given spawned process by sending it a @c SIGKILL signal.
* @param exe Process handle to the given process.
* @ingroup Ecore_Exe_Signal_Group
*/
void
ecore_exe_kill(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
"ecore_exe_kill");
return;
}
kill(exe->pid, SIGKILL);
}
/**
* Sends a @c SIGUSR signal to the given spawned process.
* @param exe Process handle to the given process.
* @param num The number user signal to send. Must be either 1 or 2, or
* the signal will be ignored.
* @ingroup Ecore_Exe_Signal_Group
*/
void
ecore_exe_signal(Ecore_Exe *exe, int num)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
"ecore_exe_signal");
return;
}
if (num == 1)
kill(exe->pid, SIGUSR1);
else if (num == 2)
kill(exe->pid, SIGUSR2);
}
/**
* Sends a @c SIGHUP signal to the given spawned process.
* @param exe Process handle to the given process.
* @ingroup Ecore_Exe_Signal_Group
*/
void
ecore_exe_hup(Ecore_Exe *exe)
{
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
{
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
"ecore_exe_hup");
return;
}
kill(exe->pid, SIGHUP);
}
void
_ecore_exe_shutdown(void)
{
while (exes) _ecore_exe_free(exes);
}
Ecore_Exe *
_ecore_exe_find(pid_t pid)
{
Ecore_Oldlist *l;
for (l = (Ecore_Oldlist *)exes; l; l = l->next)
{
Ecore_Exe *exe;
exe = (Ecore_Exe *)l;
if (exe->pid == pid) return exe;
}
return NULL;
}
void *
_ecore_exe_free(Ecore_Exe *exe)
{
void *data;
data = exe->data;
exes = _ecore_list_remove(exes, exe);
ECORE_MAGIC_SET(exe, ECORE_MAGIC_NONE);
free(exe);
return data;
}
#endif