forked from enlightenment/efl
parent
f51753a4b8
commit
224b968219
|
@ -5,7 +5,6 @@
|
|||
|
||||
#ifndef WIN32
|
||||
|
||||
|
||||
struct _ecore_exe_dead_exe
|
||||
{
|
||||
pid_t pid;
|
||||
|
@ -14,12 +13,21 @@ struct _ecore_exe_dead_exe
|
|||
|
||||
static inline void _ecore_exe_exec_it(const char *exe_cmd);
|
||||
|
||||
static int _ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_Exe_Flags flags);
|
||||
static int _ecore_exe_data_error_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 void _ecore_exe_flush(Ecore_Exe *exe);
|
||||
static void _ecore_exe_event_exe_data_free(void *data __UNUSED__, void *ev);
|
||||
static int _ecore_exe_data_generic_handler(void *data,
|
||||
Ecore_Fd_Handler *
|
||||
fd_handler,
|
||||
Ecore_Exe_Flags flags);
|
||||
static int _ecore_exe_data_error_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 void _ecore_exe_flush(Ecore_Exe * exe);
|
||||
static void _ecore_exe_event_exe_data_free(void *data __UNUSED__,
|
||||
void *ev);
|
||||
static Ecore_Exe *_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);
|
||||
|
@ -34,11 +42,11 @@ EAPI int ECORE_EXE_EVENT_ERROR = 0;
|
|||
static Ecore_Exe *exes = NULL;
|
||||
static char *shell = NULL;
|
||||
|
||||
|
||||
/* FIXME: This errno checking stuff should be put elsewhere for everybody to use.
|
||||
* For now it lives here though, just to make testing easier.
|
||||
*/
|
||||
static int _ecore_exe_check_errno(int result, char *file, int line);
|
||||
|
||||
#define E_IF_NO_ERRNO(result, foo, ok) \
|
||||
while (((ok) = _ecore_exe_check_errno( (result) = (foo), __FILE__, __LINE__)) == -1) sleep(1); \
|
||||
if (ok)
|
||||
|
@ -114,39 +122,40 @@ _ecore_exe_check_errno(int result, char *file, int line)
|
|||
*/
|
||||
switch (saved_errno)
|
||||
{
|
||||
case EACCES :
|
||||
case EAGAIN :
|
||||
case EINTR :
|
||||
case EACCES:
|
||||
case EAGAIN:
|
||||
case EINTR:
|
||||
{ /* Not now, try later. */
|
||||
fprintf(stderr, "*** Must try again in %s @%u.\n", file, line);
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
case EMFILE :
|
||||
case ENFILE :
|
||||
case ENOLCK :
|
||||
case EMFILE:
|
||||
case ENFILE:
|
||||
case ENOLCK:
|
||||
{ /* Low on resources. */
|
||||
fprintf(stderr, "*** Low on resources in %s @%u.\n", file, line);
|
||||
fprintf(stderr, "*** Low on resources in %s @%u.\n", file,
|
||||
line);
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case EIO :
|
||||
case EIO:
|
||||
{ /* I/O error. */
|
||||
fprintf(stderr, "*** I/O error in %s @%u.\n", file, line);
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case EFAULT :
|
||||
case EBADF :
|
||||
case EINVAL :
|
||||
case EROFS :
|
||||
case EISDIR :
|
||||
case EDEADLK :
|
||||
case EPERM :
|
||||
case EBUSY :
|
||||
case EFAULT:
|
||||
case EBADF:
|
||||
case EINVAL:
|
||||
case EROFS:
|
||||
case EISDIR:
|
||||
case EDEADLK:
|
||||
case EPERM:
|
||||
case EBUSY:
|
||||
{ /* Programmer fucked up. */
|
||||
fprintf(stderr,
|
||||
"*** NAUGHTY PROGRAMMER!!!\n"
|
||||
|
@ -157,7 +166,7 @@ _ecore_exe_check_errno(int result, char *file, int line)
|
|||
break;
|
||||
}
|
||||
|
||||
default :
|
||||
default:
|
||||
{ /* Unsupported errno code, please add this one. */
|
||||
fprintf(stderr,
|
||||
"*** NAUGHTY PROGRAMMER!!!\n"
|
||||
|
@ -177,8 +186,6 @@ _ecore_exe_check_errno(int result, char *file, int line)
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup Ecore_Exe_Basic_Group Process Spawning Functions
|
||||
*
|
||||
|
@ -203,7 +210,8 @@ ecore_exe_run(const char *exe_cmd, const void *data)
|
|||
Ecore_Exe *exe;
|
||||
pid_t pid;
|
||||
|
||||
if (!exe_cmd) return NULL;
|
||||
if (!exe_cmd)
|
||||
return NULL;
|
||||
pid = fork();
|
||||
if (pid)
|
||||
{
|
||||
|
@ -266,12 +274,15 @@ ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
|
|||
int ok = 1;
|
||||
int result;
|
||||
|
||||
if (!exe_cmd) return NULL;
|
||||
if (!exe_cmd)
|
||||
return NULL;
|
||||
|
||||
exe = calloc(1, sizeof(Ecore_Exe));
|
||||
if (exe == NULL) return NULL;
|
||||
if (exe == NULL)
|
||||
return NULL;
|
||||
|
||||
if ( (flags & ECORE_EXE_PIPE_AUTO) && (! (flags & ECORE_EXE_PIPE_ERROR)) && (! (flags & ECORE_EXE_PIPE_READ)) )
|
||||
if ((flags & ECORE_EXE_PIPE_AUTO) && (!(flags & ECORE_EXE_PIPE_ERROR))
|
||||
&& (!(flags & ECORE_EXE_PIPE_READ)))
|
||||
flags |= ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR; /* We need something to auto pipe. */
|
||||
|
||||
exe->child_fd_error = -1;
|
||||
|
@ -282,8 +293,8 @@ ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
|
|||
exe->child_fd_write_x = -1;
|
||||
|
||||
/* Create some pipes. */
|
||||
if (ok) E_IF_NO_ERRNO_NOLOOP(result, pipe(statusPipe), ok)
|
||||
;
|
||||
if (ok)
|
||||
E_IF_NO_ERRNO_NOLOOP(result, pipe(statusPipe), ok);
|
||||
if (ok && (flags & ECORE_EXE_PIPE_ERROR))
|
||||
E_IF_NO_ERRNO_NOLOOP(result, pipe(errorPipe), ok)
|
||||
{
|
||||
|
@ -352,9 +363,12 @@ ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
|
|||
vfork_exec_errno = errno;
|
||||
|
||||
/* Close the pipes. */
|
||||
if (flags & ECORE_EXE_PIPE_ERROR) E_NO_ERRNO(result, close(errorPipe[1]), ok);
|
||||
if (flags & ECORE_EXE_PIPE_READ) E_NO_ERRNO(result, close(readPipe[1]), ok);
|
||||
if (flags & ECORE_EXE_PIPE_WRITE) E_NO_ERRNO(result, close(writePipe[0]), ok);
|
||||
if (flags & ECORE_EXE_PIPE_ERROR)
|
||||
E_NO_ERRNO(result, close(errorPipe[1]), ok);
|
||||
if (flags & ECORE_EXE_PIPE_READ)
|
||||
E_NO_ERRNO(result, close(readPipe[1]), ok);
|
||||
if (flags & ECORE_EXE_PIPE_WRITE)
|
||||
E_NO_ERRNO(result, close(writePipe[0]), ok);
|
||||
E_NO_ERRNO(result, close(statusPipe[1]), ok);
|
||||
|
||||
_exit(-1);
|
||||
|
@ -377,7 +391,8 @@ ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
|
|||
if (vfork_exec_errno != 0)
|
||||
{
|
||||
n = vfork_exec_errno;
|
||||
fprintf(stderr, "Could not start \"%s\"\n", exe_cmd);
|
||||
fprintf(stderr, "Could not start \"%s\"\n",
|
||||
exe_cmd);
|
||||
pid = 0;
|
||||
}
|
||||
break;
|
||||
|
@ -403,33 +418,45 @@ ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
|
|||
{
|
||||
if (flags & ECORE_EXE_PIPE_ERROR)
|
||||
{ /* Setup the error stuff. */
|
||||
E_IF_NO_ERRNO(result, fcntl(exe->child_fd_error, F_SETFL, O_NONBLOCK), ok)
|
||||
E_IF_NO_ERRNO(result,
|
||||
fcntl(exe->child_fd_error, F_SETFL,
|
||||
O_NONBLOCK), ok)
|
||||
{
|
||||
exe->error_fd_handler = ecore_main_fd_handler_add(exe->child_fd_error,
|
||||
ECORE_FD_READ, _ecore_exe_data_error_handler, exe,
|
||||
NULL, NULL);
|
||||
exe->error_fd_handler =
|
||||
ecore_main_fd_handler_add(exe->child_fd_error,
|
||||
ECORE_FD_READ,
|
||||
_ecore_exe_data_error_handler,
|
||||
exe, NULL, NULL);
|
||||
if (exe->error_fd_handler == NULL)
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
if (ok && (flags & ECORE_EXE_PIPE_READ))
|
||||
{ /* Setup the read stuff. */
|
||||
E_IF_NO_ERRNO(result, fcntl(exe->child_fd_read, F_SETFL, O_NONBLOCK), ok)
|
||||
E_IF_NO_ERRNO(result,
|
||||
fcntl(exe->child_fd_read, F_SETFL,
|
||||
O_NONBLOCK), ok)
|
||||
{
|
||||
exe->read_fd_handler = ecore_main_fd_handler_add(exe->child_fd_read,
|
||||
ECORE_FD_READ, _ecore_exe_data_read_handler, exe,
|
||||
NULL, NULL);
|
||||
exe->read_fd_handler =
|
||||
ecore_main_fd_handler_add(exe->child_fd_read,
|
||||
ECORE_FD_READ,
|
||||
_ecore_exe_data_read_handler,
|
||||
exe, NULL, NULL);
|
||||
if (exe->read_fd_handler == NULL)
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
if (ok && (flags & ECORE_EXE_PIPE_WRITE))
|
||||
{ /* Setup the write stuff. */
|
||||
E_IF_NO_ERRNO(result, fcntl(exe->child_fd_write, F_SETFL, O_NONBLOCK), ok)
|
||||
E_IF_NO_ERRNO(result,
|
||||
fcntl(exe->child_fd_write, F_SETFL,
|
||||
O_NONBLOCK), ok)
|
||||
{
|
||||
exe->write_fd_handler = ecore_main_fd_handler_add(exe->child_fd_write,
|
||||
ECORE_FD_WRITE, _ecore_exe_data_write_handler, exe,
|
||||
NULL, NULL);
|
||||
exe->write_fd_handler =
|
||||
ecore_main_fd_handler_add(exe->child_fd_write,
|
||||
ECORE_FD_WRITE,
|
||||
_ecore_exe_data_write_handler,
|
||||
exe, NULL, NULL);
|
||||
if (exe->write_fd_handler)
|
||||
ecore_main_fd_handler_active_set(exe->write_fd_handler, 0); /* Nothing to write to start with. */
|
||||
else
|
||||
|
@ -449,7 +476,8 @@ ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
|
|||
|
||||
if (!ok)
|
||||
{ /* Something went wrong, so pull down everything. */
|
||||
if (exe->pid) ecore_exe_terminate(exe);
|
||||
if (exe->pid)
|
||||
ecore_exe_terminate(exe);
|
||||
IF_FN_DEL(ecore_exe_free, exe);
|
||||
}
|
||||
else
|
||||
|
@ -482,12 +510,13 @@ ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
|
|||
* @ingroup Ecore_Exe_Basic_Group
|
||||
*/
|
||||
EAPI int
|
||||
ecore_exe_send(Ecore_Exe *exe, void *data, int size)
|
||||
ecore_exe_send(Ecore_Exe * exe, void *data, int size)
|
||||
{
|
||||
void *buf;
|
||||
|
||||
buf = realloc(exe->write_data_buf, exe->write_data_size + size);
|
||||
if (buf == NULL) return 0;
|
||||
if (buf == NULL)
|
||||
return 0;
|
||||
|
||||
exe->write_data_buf = buf;
|
||||
memcpy(exe->write_data_buf + exe->write_data_size, data, size);
|
||||
|
@ -506,18 +535,16 @@ ecore_exe_send(Ecore_Exe *exe, void *data, int size)
|
|||
* @ingroup Ecore_Exe_Basic_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_exe_close_stdin(Ecore_Exe *exe)
|
||||
ecore_exe_close_stdin(Ecore_Exe * exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
||||
"ecore_exe_close_stdin");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_close_stdin");
|
||||
return;
|
||||
}
|
||||
exe->close_stdin = 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the auto pipe limits for the given process handle
|
||||
*
|
||||
|
@ -529,12 +556,12 @@ ecore_exe_close_stdin(Ecore_Exe *exe)
|
|||
* @ingroup Ecore_Exe_Basic_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_exe_auto_limits_set(Ecore_Exe *exe, int start_bytes, int end_bytes, int start_lines, int end_lines)
|
||||
ecore_exe_auto_limits_set(Ecore_Exe * exe, int start_bytes, int end_bytes,
|
||||
int start_lines, int end_lines)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
||||
"ecore_exe_auto_limits_set");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_auto_limits_set");
|
||||
return;
|
||||
}
|
||||
/* FIXME: sanitize the input. */
|
||||
|
@ -591,7 +618,7 @@ ecore_exe_auto_limits_set(Ecore_Exe *exe, int start_bytes, int end_bytes, int st
|
|||
* @ingroup Ecore_Exe_Basic_Group
|
||||
*/
|
||||
EAPI Ecore_Exe_Event_Data *
|
||||
ecore_exe_event_data_get(Ecore_Exe *exe, Ecore_Exe_Flags flags)
|
||||
ecore_exe_event_data_get(Ecore_Exe * exe, Ecore_Exe_Flags flags)
|
||||
{
|
||||
Ecore_Exe_Event_Data *e = NULL;
|
||||
int is_buffered = 0;
|
||||
|
@ -600,8 +627,7 @@ ecore_exe_event_data_get(Ecore_Exe *exe, Ecore_Exe_Flags flags)
|
|||
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
||||
"ecore_exe_event_data_get");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_event_data_get");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -715,7 +741,6 @@ ecore_exe_event_data_get(Ecore_Exe *exe, Ecore_Exe_Flags flags)
|
|||
return e;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the string tag for the given process handle
|
||||
*
|
||||
|
@ -724,16 +749,16 @@ ecore_exe_event_data_get(Ecore_Exe *exe, Ecore_Exe_Flags flags)
|
|||
* @ingroup Ecore_Exe_Basic_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_exe_tag_set(Ecore_Exe *exe, const char *tag)
|
||||
ecore_exe_tag_set(Ecore_Exe * exe, const char *tag)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
||||
"ecore_exe_tag_set");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_set");
|
||||
return;
|
||||
}
|
||||
IF_FREE(exe->tag);
|
||||
if (tag) exe->tag = strdup(tag);
|
||||
if (tag)
|
||||
exe->tag = strdup(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -747,12 +772,11 @@ ecore_exe_tag_set(Ecore_Exe *exe, const char *tag)
|
|||
* @ingroup Ecore_Exe_Basic_Group
|
||||
*/
|
||||
EAPI char *
|
||||
ecore_exe_tag_get(Ecore_Exe *exe)
|
||||
ecore_exe_tag_get(Ecore_Exe * exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
||||
"ecore_exe_tag_get");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_get");
|
||||
return NULL;
|
||||
}
|
||||
return exe->tag;
|
||||
|
@ -770,7 +794,7 @@ ecore_exe_tag_get(Ecore_Exe *exe)
|
|||
* @ingroup Ecore_Exe_Basic_Group
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_exe_free(Ecore_Exe *exe)
|
||||
ecore_exe_free(Ecore_Exe * exe)
|
||||
{
|
||||
void *data;
|
||||
int ok = 0;
|
||||
|
@ -778,8 +802,7 @@ ecore_exe_free(Ecore_Exe *exe)
|
|||
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
||||
"ecore_exe_free");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_free");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -789,12 +812,18 @@ ecore_exe_free(Ecore_Exe *exe)
|
|||
IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler);
|
||||
IF_FN_DEL(ecore_main_fd_handler_del, exe->read_fd_handler);
|
||||
IF_FN_DEL(ecore_main_fd_handler_del, exe->error_fd_handler);
|
||||
if (exe->child_fd_write_x != -1) E_NO_ERRNO(result, close(exe->child_fd_write_x), ok);
|
||||
if (exe->child_fd_read_x != -1) E_NO_ERRNO(result, close(exe->child_fd_read_x), ok);
|
||||
if (exe->child_fd_error_x != -1) E_NO_ERRNO(result, close(exe->child_fd_error_x), ok);
|
||||
if (exe->child_fd_write != -1) E_NO_ERRNO(result, close(exe->child_fd_write), ok);
|
||||
if (exe->child_fd_read != -1) E_NO_ERRNO(result, close(exe->child_fd_read), ok);
|
||||
if (exe->child_fd_error != -1) E_NO_ERRNO(result, close(exe->child_fd_error), ok);
|
||||
if (exe->child_fd_write_x != -1)
|
||||
E_NO_ERRNO(result, close(exe->child_fd_write_x), ok);
|
||||
if (exe->child_fd_read_x != -1)
|
||||
E_NO_ERRNO(result, close(exe->child_fd_read_x), ok);
|
||||
if (exe->child_fd_error_x != -1)
|
||||
E_NO_ERRNO(result, close(exe->child_fd_error_x), ok);
|
||||
if (exe->child_fd_write != -1)
|
||||
E_NO_ERRNO(result, close(exe->child_fd_write), ok);
|
||||
if (exe->child_fd_read != -1)
|
||||
E_NO_ERRNO(result, close(exe->child_fd_read), ok);
|
||||
if (exe->child_fd_error != -1)
|
||||
E_NO_ERRNO(result, close(exe->child_fd_error), ok);
|
||||
IF_FREE(exe->write_data_buf);
|
||||
IF_FREE(exe->read_data_buf);
|
||||
IF_FREE(exe->error_data_buf);
|
||||
|
@ -807,7 +836,6 @@ ecore_exe_free(Ecore_Exe *exe)
|
|||
return data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Frees the given event data.
|
||||
*
|
||||
|
@ -815,14 +843,13 @@ ecore_exe_free(Ecore_Exe *exe)
|
|||
* @ingroup Ecore_Exe_Basic_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_exe_event_data_free(Ecore_Exe_Event_Data *e)
|
||||
ecore_exe_event_data_free(Ecore_Exe_Event_Data * e)
|
||||
{
|
||||
IF_FREE(e->lines);
|
||||
IF_FREE(e->data);
|
||||
free(e);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the process ID of the given spawned process.
|
||||
* @param exe Handle to the given spawned process.
|
||||
|
@ -830,12 +857,11 @@ ecore_exe_event_data_free(Ecore_Exe_Event_Data *e)
|
|||
* @ingroup Ecore_Exe_Basic_Group
|
||||
*/
|
||||
EAPI pid_t
|
||||
ecore_exe_pid_get(Ecore_Exe *exe)
|
||||
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");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pid_get");
|
||||
return -1;
|
||||
}
|
||||
return exe->pid;
|
||||
|
@ -848,12 +874,11 @@ ecore_exe_pid_get(Ecore_Exe *exe)
|
|||
* @ingroup Ecore_Exe_Basic_Group
|
||||
*/
|
||||
EAPI void *
|
||||
ecore_exe_data_get(Ecore_Exe *exe)
|
||||
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");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get");
|
||||
return NULL;
|
||||
}
|
||||
return exe->data;
|
||||
|
@ -871,12 +896,11 @@ ecore_exe_data_get(Ecore_Exe *exe)
|
|||
* @ingroup Ecore_Exe_Signal_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_exe_pause(Ecore_Exe *exe)
|
||||
ecore_exe_pause(Ecore_Exe * exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
||||
"ecore_exe_pause");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pause");
|
||||
return;
|
||||
}
|
||||
kill(exe->pid, SIGSTOP);
|
||||
|
@ -888,12 +912,11 @@ ecore_exe_pause(Ecore_Exe *exe)
|
|||
* @ingroup Ecore_Exe_Signal_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_exe_continue(Ecore_Exe *exe)
|
||||
ecore_exe_continue(Ecore_Exe * exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
||||
"ecore_exe_continue");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_continue");
|
||||
return;
|
||||
}
|
||||
kill(exe->pid, SIGCONT);
|
||||
|
@ -905,14 +928,13 @@ ecore_exe_continue(Ecore_Exe *exe)
|
|||
* @ingroup Ecore_Exe_Signal_Group
|
||||
*/
|
||||
EAPI 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))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
||||
"ecore_exe_terminate");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_terminate");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -922,7 +944,8 @@ ecore_exe_terminate(Ecore_Exe *exe)
|
|||
dead->pid = exe->pid;
|
||||
dead->cmd = strdup(exe->cmd);
|
||||
IF_FN_DEL(ecore_timer_del, exe->doomsday_clock);
|
||||
exe->doomsday_clock = ecore_timer_add(10.0, _ecore_exe_make_sure_its_dead, dead);
|
||||
exe->doomsday_clock =
|
||||
ecore_timer_add(10.0, _ecore_exe_make_sure_its_dead, dead);
|
||||
}
|
||||
|
||||
printf("Sending TERM signal to %s (%d).\n", exe->cmd, exe->pid);
|
||||
|
@ -935,14 +958,13 @@ ecore_exe_terminate(Ecore_Exe *exe)
|
|||
* @ingroup Ecore_Exe_Signal_Group
|
||||
*/
|
||||
EAPI 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))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
||||
"ecore_exe_kill");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_kill");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -952,7 +974,8 @@ ecore_exe_kill(Ecore_Exe *exe)
|
|||
dead->pid = exe->pid;
|
||||
dead->cmd = strdup(exe->cmd);
|
||||
IF_FN_DEL(ecore_timer_del, exe->doomsday_clock);
|
||||
exe->doomsday_clock = ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead, dead);
|
||||
exe->doomsday_clock =
|
||||
ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead, dead);
|
||||
}
|
||||
|
||||
printf("Sending KILL signal to %s (%d).\n", exe->cmd, exe->pid);
|
||||
|
@ -967,12 +990,11 @@ ecore_exe_kill(Ecore_Exe *exe)
|
|||
* @ingroup Ecore_Exe_Signal_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_exe_signal(Ecore_Exe *exe, int num)
|
||||
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");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_signal");
|
||||
return;
|
||||
}
|
||||
if (num == 1)
|
||||
|
@ -987,12 +1009,11 @@ ecore_exe_signal(Ecore_Exe *exe, int num)
|
|||
* @ingroup Ecore_Exe_Signal_Group
|
||||
*/
|
||||
EAPI void
|
||||
ecore_exe_hup(Ecore_Exe *exe)
|
||||
ecore_exe_hup(Ecore_Exe * exe)
|
||||
{
|
||||
if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE))
|
||||
{
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,
|
||||
"ecore_exe_hup");
|
||||
ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_hup");
|
||||
return;
|
||||
}
|
||||
kill(exe->pid, SIGHUP);
|
||||
|
@ -1045,13 +1066,17 @@ _ecore_exe_make_sure_its_dead(void *data)
|
|||
{
|
||||
Ecore_Exe *exe = NULL;
|
||||
|
||||
if ((exe =_ecore_exe_is_it_alive(dead->pid)) != NULL)
|
||||
if ((exe = _ecore_exe_is_it_alive(dead->pid)) != NULL)
|
||||
{
|
||||
if (dead->cmd)
|
||||
printf("Sending KILL signal to alledgedly dead %s (%d).\n", dead->cmd, dead->pid);
|
||||
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);
|
||||
exe->doomsday_clock = ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead, dead);
|
||||
printf("Sending KILL signal to alledgedly dead PID %d.\n",
|
||||
dead->pid);
|
||||
exe->doomsday_clock =
|
||||
ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead,
|
||||
dead);
|
||||
kill(dead->pid, SIGKILL);
|
||||
}
|
||||
else
|
||||
|
@ -1073,9 +1098,10 @@ _ecore_exe_make_sure_its_really_dead(void *data)
|
|||
{
|
||||
Ecore_Exe *exe = NULL;
|
||||
|
||||
if ((exe =_ecore_exe_is_it_alive(dead->pid)) != NULL)
|
||||
if ((exe = _ecore_exe_is_it_alive(dead->pid)) != NULL)
|
||||
{
|
||||
printf("RUN! The zombie wants to eat your brains! And your CPU!\n");
|
||||
printf
|
||||
("RUN! The zombie wants to eat your brains! And your CPU!\n");
|
||||
if (dead->cmd)
|
||||
printf("%s (%d) is not really dead.\n", dead->cmd, dead->pid);
|
||||
else
|
||||
|
@ -1088,7 +1114,6 @@ _ecore_exe_make_sure_its_really_dead(void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_ecore_exe_init(void)
|
||||
{
|
||||
|
@ -1101,7 +1126,8 @@ _ecore_exe_init(void)
|
|||
void
|
||||
_ecore_exe_shutdown(void)
|
||||
{
|
||||
while (exes) ecore_exe_free(exes);
|
||||
while (exes)
|
||||
ecore_exe_free(exes);
|
||||
}
|
||||
|
||||
Ecore_Exe *
|
||||
|
@ -1109,12 +1135,13 @@ _ecore_exe_find(pid_t pid)
|
|||
{
|
||||
Ecore_List2 *l;
|
||||
|
||||
for (l = (Ecore_List2 *)exes; l; l = l->next)
|
||||
for (l = (Ecore_List2 *) exes; l; l = l->next)
|
||||
{
|
||||
Ecore_Exe *exe;
|
||||
|
||||
exe = (Ecore_Exe *)l;
|
||||
if (exe->pid == pid) return exe;
|
||||
exe = (Ecore_Exe *) l;
|
||||
if (exe->pid == pid)
|
||||
return exe;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1123,8 +1150,8 @@ static inline void
|
|||
_ecore_exe_exec_it(const char *exe_cmd)
|
||||
{
|
||||
char use_sh = 1;
|
||||
char* buf = NULL;
|
||||
char** args = NULL;
|
||||
char *buf = NULL;
|
||||
char **args = NULL;
|
||||
int save_errno = 0;
|
||||
|
||||
/* So what is this doing?
|
||||
|
@ -1135,15 +1162,15 @@ _ecore_exe_exec_it(const char *exe_cmd)
|
|||
*/
|
||||
if (!strpbrk(exe_cmd, "|&;<>()$`\\\"'*?#"))
|
||||
{
|
||||
char* token;
|
||||
char *token;
|
||||
char pre_command = 1;
|
||||
int num_tokens = 0;
|
||||
|
||||
if (! (buf = strdup(exe_cmd)))
|
||||
if (!(buf = strdup(exe_cmd)))
|
||||
return;
|
||||
|
||||
token = strtok(buf, " \t\n\v");
|
||||
while(token)
|
||||
while (token)
|
||||
{
|
||||
if (token[0] == '~')
|
||||
break;
|
||||
|
@ -1156,26 +1183,26 @@ _ecore_exe_exec_it(const char *exe_cmd)
|
|||
else
|
||||
pre_command = 0;
|
||||
}
|
||||
num_tokens ++;
|
||||
num_tokens++;
|
||||
token = strtok(NULL, " \t\n\v");
|
||||
}
|
||||
IF_FREE(buf);
|
||||
if (! token && num_tokens)
|
||||
if (!token && num_tokens)
|
||||
{
|
||||
int i = 0;
|
||||
char* token;
|
||||
char *token;
|
||||
|
||||
if (! (buf = strdup(exe_cmd)))
|
||||
if (!(buf = strdup(exe_cmd)))
|
||||
return;
|
||||
|
||||
token = strtok(buf, " \t\n\v");
|
||||
use_sh = 0;
|
||||
if (! (args = (char**) calloc(num_tokens + 1, sizeof(char*))))
|
||||
if (!(args = (char **)calloc(num_tokens + 1, sizeof(char *))))
|
||||
{
|
||||
IF_FREE(buf);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < num_tokens; i ++)
|
||||
for (i = 0; i < num_tokens; i++)
|
||||
{
|
||||
if (token)
|
||||
args[i] = token;
|
||||
|
@ -1211,7 +1238,8 @@ _ecore_exe_exec_it(const char *exe_cmd)
|
|||
}
|
||||
|
||||
static int
|
||||
_ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_Exe_Flags flags)
|
||||
_ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler * fd_handler,
|
||||
Ecore_Exe_Flags flags)
|
||||
{
|
||||
Ecore_Exe *exe;
|
||||
int child_fd;
|
||||
|
@ -1238,7 +1266,8 @@ _ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_
|
|||
is_buffered = 1;
|
||||
}
|
||||
|
||||
if ((fd_handler) && (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)))
|
||||
if ((fd_handler)
|
||||
&& (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)))
|
||||
{
|
||||
unsigned char *inbuf;
|
||||
int inbuf_num;
|
||||
|
@ -1271,8 +1300,7 @@ _ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_
|
|||
lost_exe = ((errno == EIO) ||
|
||||
(errno == EBADF) ||
|
||||
(errno == EPIPE) ||
|
||||
(errno == EINVAL) ||
|
||||
(errno == ENOSPC));
|
||||
(errno == EINVAL) || (errno == ENOSPC));
|
||||
if ((errno != EAGAIN) && (errno != EINTR))
|
||||
perror("_ecore_exe_generic_handler() read problem ");
|
||||
}
|
||||
|
@ -1296,16 +1324,17 @@ _ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_
|
|||
}
|
||||
else
|
||||
{
|
||||
exe->error_data_buf = inbuf ;
|
||||
exe->error_data_buf = inbuf;
|
||||
exe->error_data_size = inbuf_num;
|
||||
}
|
||||
|
||||
if (! (exe->flags & ECORE_EXE_PIPE_AUTO))
|
||||
if (!(exe->flags & ECORE_EXE_PIPE_AUTO))
|
||||
{
|
||||
e = ecore_exe_event_data_get(exe, flags);
|
||||
if (e) /* Send the event. */
|
||||
ecore_event_add(event_type, e,
|
||||
_ecore_exe_event_exe_data_free, NULL);
|
||||
_ecore_exe_event_exe_data_free,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
if (lost_exe)
|
||||
|
@ -1313,12 +1342,16 @@ _ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_
|
|||
if (flags & ECORE_EXE_PIPE_READ)
|
||||
{
|
||||
if (exe->read_data_size)
|
||||
printf("There are %d bytes left unsent from the dead exe %s.\n", exe->read_data_size, exe->cmd);
|
||||
printf
|
||||
("There are %d bytes left unsent from the dead exe %s.\n",
|
||||
exe->read_data_size, exe->cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (exe->error_data_size)
|
||||
printf("There are %d bytes left unsent from the dead exe %s.\n", exe->error_data_size, exe->cmd);
|
||||
printf
|
||||
("There are %d bytes left unsent from the dead exe %s.\n",
|
||||
exe->error_data_size, exe->cmd);
|
||||
}
|
||||
/* Thought about this a bit. If the exe has actually
|
||||
* died, this won't do any harm as it must have died
|
||||
|
@ -1338,36 +1371,43 @@ _ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_
|
|||
}
|
||||
|
||||
static int
|
||||
_ecore_exe_data_error_handler(void *data, Ecore_Fd_Handler *fd_handler)
|
||||
_ecore_exe_data_error_handler(void *data, Ecore_Fd_Handler * fd_handler)
|
||||
{
|
||||
return _ecore_exe_data_generic_handler(data, fd_handler, ECORE_EXE_PIPE_ERROR);
|
||||
return _ecore_exe_data_generic_handler(data, fd_handler,
|
||||
ECORE_EXE_PIPE_ERROR);
|
||||
}
|
||||
|
||||
static int
|
||||
_ecore_exe_data_read_handler(void *data, Ecore_Fd_Handler *fd_handler)
|
||||
_ecore_exe_data_read_handler(void *data, Ecore_Fd_Handler * fd_handler)
|
||||
{
|
||||
return _ecore_exe_data_generic_handler(data, fd_handler, ECORE_EXE_PIPE_READ);
|
||||
return _ecore_exe_data_generic_handler(data, fd_handler,
|
||||
ECORE_EXE_PIPE_READ);
|
||||
}
|
||||
|
||||
static int
|
||||
_ecore_exe_data_write_handler(void *data, Ecore_Fd_Handler *fd_handler)
|
||||
_ecore_exe_data_write_handler(void *data, Ecore_Fd_Handler * fd_handler)
|
||||
{
|
||||
Ecore_Exe *exe;
|
||||
|
||||
exe = data;
|
||||
if ((exe->write_fd_handler) && (ecore_main_fd_handler_active_get(exe->write_fd_handler, ECORE_FD_WRITE)))
|
||||
if ((exe->write_fd_handler)
|
||||
&&
|
||||
(ecore_main_fd_handler_active_get
|
||||
(exe->write_fd_handler, ECORE_FD_WRITE)))
|
||||
_ecore_exe_flush(exe);
|
||||
|
||||
/* If we have sent all there is to send, and we need to close the pipe, then close it. */
|
||||
if ((exe->close_stdin == 1) && (exe->write_data_size == exe->write_data_offset))
|
||||
if ((exe->close_stdin == 1)
|
||||
&& (exe->write_data_size == exe->write_data_offset))
|
||||
{
|
||||
int ok = 0;
|
||||
int result;
|
||||
|
||||
printf("Closing stdin for %s\n", exe->cmd);
|
||||
printf("Closing stdin for %s\n", exe->cmd);
|
||||
/* if (exe->child_fd_write != -1) E_NO_ERRNO(result, fsync(exe->child_fd_write), ok); This a) doesn't work, and b) isn't needed. */
|
||||
IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler);
|
||||
if (exe->child_fd_write != -1) E_NO_ERRNO(result, close(exe->child_fd_write), ok);
|
||||
if (exe->child_fd_write != -1)
|
||||
E_NO_ERRNO(result, close(exe->child_fd_write), ok);
|
||||
exe->child_fd_write = -1;
|
||||
IF_FREE(exe->write_data_buf);
|
||||
}
|
||||
|
@ -1376,22 +1416,22 @@ printf("Closing stdin for %s\n", exe->cmd);
|
|||
}
|
||||
|
||||
static void
|
||||
_ecore_exe_flush(Ecore_Exe *exe)
|
||||
_ecore_exe_flush(Ecore_Exe * exe)
|
||||
{
|
||||
int count;
|
||||
|
||||
/* check whether we need to write anything at all. */
|
||||
if ((exe->child_fd_write == -1) || (!exe->write_data_buf)) return;
|
||||
if (exe->write_data_size == exe->write_data_offset) return;
|
||||
if ((exe->child_fd_write == -1) || (!exe->write_data_buf))
|
||||
return;
|
||||
if (exe->write_data_size == exe->write_data_offset)
|
||||
return;
|
||||
|
||||
count = write(exe->child_fd_write,
|
||||
exe->write_data_buf + exe->write_data_offset,
|
||||
exe->write_data_size - exe->write_data_offset);
|
||||
if (count < 1)
|
||||
{
|
||||
if (errno == EIO || errno == EBADF ||
|
||||
errno == EPIPE || errno == EINVAL ||
|
||||
errno == ENOSPC) /* we lost our exe! */
|
||||
if (errno == EIO || errno == EBADF || errno == EPIPE || errno == EINVAL || errno == ENOSPC) /* we lost our exe! */
|
||||
{
|
||||
ecore_exe_terminate(exe);
|
||||
if (exe->write_fd_handler)
|
||||
|
@ -1454,7 +1494,8 @@ _ecore_exe_event_del_free(void *data __UNUSED__, void *ev)
|
|||
Ecore_Exe_Event_Del *e;
|
||||
|
||||
e = ev;
|
||||
if (e->exe) ecore_exe_free(e->exe);
|
||||
if (e->exe)
|
||||
ecore_exe_free(e->exe);
|
||||
free(e);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue