Ecore exe: Fix windows build by making the windows stuff less redundant.

This should fix the dumb way it was split until now (everything was redundant).
Now we just reimplement the parts we need to reimplement and the rest is shared.
The win32 code is called from within the normal code.
This commit is contained in:
Tom Hacohen 2014-08-26 16:48:07 +01:00
parent 791f1e5f6c
commit d4f6870bb5
4 changed files with 246 additions and 437 deletions

View File

@ -92,10 +92,11 @@ lib/ecore/ecore_time.c \
lib/ecore/ecore_timer.c \
lib/ecore/ecore_thread.c \
lib/ecore/ecore_throttle.c \
lib/ecore/ecore_exe.c \
lib/ecore/ecore_exe_private.h \
lib/ecore/ecore_private.h
if HAVE_WIN32
lib_ecore_libecore_la_SOURCES += lib/ecore/ecore_exe_win32.c
else
EXTRA_DIST += lib/ecore/ecore_exe_ps3.c
#if ECORE_HAVE_PS3
@ -104,7 +105,7 @@ EXTRA_DIST += lib/ecore/ecore_exe_ps3.c
#if ECORE_HAVE_EXOTIC
#libecore_la_SOURCES +=
#else
lib_ecore_libecore_la_SOURCES += lib/ecore/ecore_signal.c lib/ecore/ecore_exe.c
lib_ecore_libecore_la_SOURCES += lib/ecore/ecore_signal.c
#endif
#endif
endif

View File

@ -27,101 +27,7 @@
#include <Efl.h>
/* FIXME: Getting respawn to work
*
* There is no way that we can do anything about the internal state info of
* an external exe. The same can be said about the state of user code. User
* code in this context means the code that is using ecore_exe to manage exe's
* for it.
*
* Document that the exe must be respawnable, in other words, there is no
* state that it cannot regenerate by just killing it and starting it again.
* This includes state that the user code knows about, as the respawn is
* transparent to that code. On the other hand, maybe a respawn event might
* be useful, or maybe resend the currently non existent add event. For
* consistancy with ecore_con, an add event is good anyway.
*
* The Ecore_exe structure is reused for respawning, so that the (opaque)
* pointer held by the user remains valid. This means that the Ecore_Exe
* init and del functions may need to be split into two parts each to avoid
* duplicating code - common code part, and the rest. This implies that
* the unchanging members mentioned next should NEVER change.
*
* These structure members don't need to change -
* __list_data - we stay on the list
* data - passed in originally
* cmd - passed in originally
* flags - passed in originally
*
* These structure members need to change -
* tag - state that must be regenerated, zap it
* pid - it will be different
* child_fd_write - it will be different
* child_fd_read - it will be different
* child_fd_error - it will be different
* write_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
* read_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
* error_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
*
* Hmm, the read, write, and error buffers could be tricky.
* They are not atomic, and could be in a semi complete state.
* They fall into the "state must be regenerated" mentioned above.
* A respawn/add event should take care of it.
*
* These structure members need to change -
* write_data_buf - state that must be regenerated, zap it
* write_data_size - state that must be regenerated, zap it
* write_data_offset - state that must be regenerated, zap it
* read_data_buf - state that must be regenerated, zap it
* read_data_size - state that must be regenerated, zap it
* error_data_buf - state that must be regenerated, zap it
* error_data_size - state that must be regenerated, zap it
* close_write - state that must be regenerated, zap it
*
* There is the problem that an exe that fell over and needs respawning
* might keep falling over, keep needing to be respawned, and tie up system
* resources with the constant respawning. An exponentially increasing
* timeout (with maximum timeout) between respawns should take care of that.
* Although this is not a "contention for a resource" problem, the exe falling
* over may be, so a random element added to the timeout may help, and won't
* hurt. The user code may need to be informed that a timeout is in progress.
*/
struct _Ecore_Exe_Data
{
pid_t pid;
void *data;
char *tag, *cmd;
Ecore_Exe_Flags flags;
Ecore_Fd_Handler *write_fd_handler; /* the fd_handler to handle write to child - if this was used, or NULL if not */
Ecore_Fd_Handler *read_fd_handler; /* the fd_handler to handle read from child - if this was used, or NULL if not */
Ecore_Fd_Handler *error_fd_handler; /* the fd_handler to handle errors from child - if this was used, or NULL if not */
void *write_data_buf; /* a data buffer for data to write to the child -
* realloced as needed for more data and flushed when the fd handler says writes are possible
*/
int write_data_size; /* the size in bytes of the data buffer */
int write_data_offset; /* the offset in bytes in the data buffer */
void *read_data_buf; /* data read from the child awating delivery to an event */
int read_data_size; /* data read from child in bytes */
void *error_data_buf; /* errors read from the child awating delivery to an event */
int error_data_size; /* errors read from child in bytes */
int child_fd_write; /* fd to write TO to send data to the child */
int child_fd_read; /* fd to read FROM when child has sent us (the parent) data */
int child_fd_error; /* fd to read FROM when child has sent us (the parent) errors */
int child_fd_write_x; /* fd to write TO to send data to the child */
int child_fd_read_x; /* fd to read FROM when child has sent us (the parent) data */
int child_fd_error_x; /* fd to read FROM when child has sent us (the parent) errors */
Eina_Bool close_stdin : 1;
int start_bytes, end_bytes, start_lines, end_lines; /* Number of bytes/lines to auto pipe at start/end of stdout/stderr. */
Ecore_Timer *doomsday_clock; /* The Timer of Death. Muahahahaha. */
void *doomsday_clock_dead; /* data for the doomsday clock */
Ecore_Exe_Cb pre_free_cb;
};
typedef struct _Ecore_Exe_Data Ecore_Exe_Data;
#include "ecore_exe_private.h"
/* TODO: Something to let people build a command line and does auto escaping -
*
@ -323,14 +229,22 @@ EAPI void
ecore_exe_run_priority_set(int pri)
{
EINA_MAIN_LOOP_CHECK_RETURN;
#ifdef _WIN32
_win32_ecore_exe_run_priority_set(pri);
#else
run_pri = pri;
#endif
}
EAPI int
ecore_exe_run_priority_get(void)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
#ifdef _WIN32
return _win32_ecore_exe_run_priority_get();
#else
return run_pri;
#endif
}
EAPI Ecore_Exe *
@ -373,6 +287,10 @@ _ecore_exe_command_get(Eo *obj EINA_UNUSED, Ecore_Exe_Data *pd, const char **cmd
EOLIAN static Eo *
_ecore_exe_eo_base_finalize(Eo *obj, Ecore_Exe_Data *exe)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
#ifdef _WIN32
return _win32_ecore_exe_eo_base_finalize(obj, exe);
#else
int statusPipe[2] = { -1, -1 };
int errorPipe[2] = { -1, -1 };
int readPipe[2] = { -1, -1 };
@ -381,7 +299,6 @@ _ecore_exe_eo_base_finalize(Eo *obj, Ecore_Exe_Data *exe)
int ok = 1;
int result;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
if (!exe->cmd) return NULL;
const char *exe_cmd = exe->cmd;
@ -666,6 +583,7 @@ _ecore_exe_eo_base_finalize(Eo *obj, Ecore_Exe_Data *exe)
errno = n;
return obj;
#endif
}
EAPI void
@ -689,8 +607,6 @@ ecore_exe_send(Ecore_Exe *obj,
if (!eo_isa(obj, MY_CLASS))
return EINA_FALSE;
void *buf;
if (exe->close_stdin)
{
ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p",
@ -698,6 +614,11 @@ ecore_exe_send(Ecore_Exe *obj,
return EINA_FALSE;
}
#if _WIN32
return _win32_ecore_exe_send(obj, exe, data, size);
#else
void *buf;
if (exe->child_fd_write == -1)
{
ERR("Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! "
@ -716,6 +637,7 @@ ecore_exe_send(Ecore_Exe *obj,
ecore_main_fd_handler_active_set(exe->write_fd_handler, ECORE_FD_WRITE);
return EINA_TRUE;
#endif
}
EAPI void
@ -790,16 +712,19 @@ EAPI Ecore_Exe_Event_Data *
ecore_exe_event_data_get(Ecore_Exe *obj,
Ecore_Exe_Flags flags)
{
Ecore_Exe_Event_Data *e = NULL;
int is_buffered = 0;
unsigned char *inbuf;
int inbuf_num;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
Ecore_Exe_Data *exe = eo_data_scope_get(obj, MY_CLASS);
if (!eo_isa(obj, MY_CLASS))
return NULL;
#ifdef _WIN32
return _win32_ecore_exe_event_data_get(obj, exe, flags);
#else
Ecore_Exe_Event_Data *e = NULL;
int is_buffered = 0;
unsigned char *inbuf;
int inbuf_num;
/* Sort out what sort of event we are. */
if (flags & ECORE_EXE_PIPE_READ)
{
@ -908,6 +833,7 @@ ecore_exe_event_data_get(Ecore_Exe *obj,
}
return e;
#endif
}
EAPI void
@ -1087,9 +1013,21 @@ _ecore_exe_efl_control_suspend_set(Eo *obj EINA_UNUSED, Ecore_Exe_Data *exe, Ein
EINA_MAIN_LOOP_CHECK_RETURN;
if (suspend)
kill(exe->pid, SIGSTOP);
{
#ifdef _WIN32
_win32_ecore_exe_pause(obj, exe);
#else
kill(exe->pid, SIGSTOP);
#endif
}
else
kill(exe->pid, SIGCONT);
{
#ifdef _WIN32
_win32_ecore_exe_continue(obj, exe);
#else
kill(exe->pid, SIGCONT);
#endif
}
}
EAPI void
@ -1100,8 +1038,12 @@ ecore_exe_interrupt(Ecore_Exe *obj)
if (!eo_isa(obj, MY_CLASS))
return;
#ifdef _WIN32
_win32_ecore_exe_interrupt(obj, exe);
#else
_ecore_exe_dead_attach(obj);
kill(exe->pid, SIGINT);
#endif
}
EAPI void
@ -1112,8 +1054,12 @@ ecore_exe_quit(Ecore_Exe *obj)
if (!eo_isa(obj, MY_CLASS))
return;
#ifdef _WIN32
_win32_ecore_exe_quit(obj, exe);
#else
_ecore_exe_dead_attach(obj);
kill(exe->pid, SIGQUIT);
#endif
}
EAPI void
@ -1124,9 +1070,13 @@ ecore_exe_terminate(Ecore_Exe *obj)
if (!eo_isa(obj, MY_CLASS))
return;
#ifdef _WIN32
_win32_ecore_exe_terminate(obj, exe);
#else
_ecore_exe_dead_attach(obj);
INF("Sending TERM signal to %s (%d).", exe->cmd, exe->pid);
kill(exe->pid, SIGTERM);
#endif
}
EAPI void
@ -1138,6 +1088,9 @@ ecore_exe_kill(Ecore_Exe *obj)
if (!eo_isa(obj, MY_CLASS))
return;
#ifdef _WIN32
_win32_ecore_exe_kill(obj, exe);
#else
dead = calloc(1, sizeof(struct _ecore_exe_dead_exe));
if (dead)
{
@ -1150,6 +1103,7 @@ ecore_exe_kill(Ecore_Exe *obj)
INF("Sending KILL signal to %s (%d).", exe->cmd, exe->pid);
kill(exe->pid, SIGKILL);
#endif
}
EAPI void

View File

@ -0,0 +1,152 @@
/* FIXME: Getting respawn to work
*
* There is no way that we can do anything about the internal state info of
* an external exe. The same can be said about the state of user code. User
* code in this context means the code that is using ecore_exe to manage exe's
* for it.
*
* Document that the exe must be respawnable, in other words, there is no
* state that it cannot regenerate by just killing it and starting it again.
* This includes state that the user code knows about, as the respawn is
* transparent to that code. On the other hand, maybe a respawn event might
* be useful, or maybe resend the currently non existent add event. For
* consistancy with ecore_con, an add event is good anyway.
*
* The Ecore_exe structure is reused for respawning, so that the (opaque)
* pointer held by the user remains valid. This means that the Ecore_Exe
* init and del functions may need to be split into two parts each to avoid
* duplicating code - common code part, and the rest. This implies that
* the unchanging members mentioned next should NEVER change.
*
* These structure members don't need to change -
* __list_data - we stay on the list
* data - passed in originally
* cmd - passed in originally
* flags - passed in originally
*
* These structure members need to change -
* tag - state that must be regenerated, zap it
* pid - it will be different
* child_fd_write - it will be different
* child_fd_read - it will be different
* child_fd_error - it will be different
* write_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
* read_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
* error_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
*
* Hmm, the read, write, and error buffers could be tricky.
* They are not atomic, and could be in a semi complete state.
* They fall into the "state must be regenerated" mentioned above.
* A respawn/add event should take care of it.
*
* These structure members need to change -
* write_data_buf - state that must be regenerated, zap it
* write_data_size - state that must be regenerated, zap it
* write_data_offset - state that must be regenerated, zap it
* read_data_buf - state that must be regenerated, zap it
* read_data_size - state that must be regenerated, zap it
* error_data_buf - state that must be regenerated, zap it
* error_data_size - state that must be regenerated, zap it
* close_write - state that must be regenerated, zap it
*
* There is the problem that an exe that fell over and needs respawning
* might keep falling over, keep needing to be respawned, and tie up system
* resources with the constant respawning. An exponentially increasing
* timeout (with maximum timeout) between respawns should take care of that.
* Although this is not a "contention for a resource" problem, the exe falling
* over may be, so a random element added to the timeout may help, and won't
* hurt. The user code may need to be informed that a timeout is in progress.
*/
struct _Ecore_Exe_Data
{
pid_t pid;
void *data;
char *tag, *cmd;
Ecore_Exe_Flags flags;
#ifdef _WIN32
HANDLE process;
HANDLE process_thread;
DWORD process_id;
DWORD thread_id;
Ecore_Win32_Handler *h_close;
Ecore_Exe_Win32_Signal sig;
struct
{
HANDLE child_pipe;
HANDLE child_pipe_x;
HANDLE thread;
void *data_buf;
DWORD data_size;
} pipe_read;
struct
{
HANDLE child_pipe;
HANDLE child_pipe_x;
void *data_buf;
int data_size;
} pipe_write;
struct
{
HANDLE child_pipe;
HANDLE child_pipe_x;
HANDLE thread;
void *data_buf;
DWORD data_size;
} pipe_error;
Eina_Bool close_threads : 1;
Eina_Bool is_suspended : 1;
#endif
// FIXME: For now just waste memory on windows.
// #else
Ecore_Fd_Handler *write_fd_handler; /* the fd_handler to handle write to child - if this was used, or NULL if not */
Ecore_Fd_Handler *read_fd_handler; /* the fd_handler to handle read from child - if this was used, or NULL if not */
Ecore_Fd_Handler *error_fd_handler; /* the fd_handler to handle errors from child - if this was used, or NULL if not */
void *write_data_buf; /* a data buffer for data to write to the child -
* realloced as needed for more data and flushed when the fd handler says writes are possible
*/
int write_data_size; /* the size in bytes of the data buffer */
int write_data_offset; /* the offset in bytes in the data buffer */
void *read_data_buf; /* data read from the child awating delivery to an event */
int read_data_size; /* data read from child in bytes */
void *error_data_buf; /* errors read from the child awating delivery to an event */
int error_data_size; /* errors read from child in bytes */
int child_fd_write; /* fd to write TO to send data to the child */
int child_fd_read; /* fd to read FROM when child has sent us (the parent) data */
int child_fd_error; /* fd to read FROM when child has sent us (the parent) errors */
int child_fd_write_x; /* fd to write TO to send data to the child */
int child_fd_read_x; /* fd to read FROM when child has sent us (the parent) data */
int child_fd_error_x; /* fd to read FROM when child has sent us (the parent) errors */
int start_bytes, end_bytes, start_lines, end_lines; /* Number of bytes/lines to auto pipe at start/end of stdout/stderr. */
Ecore_Timer *doomsday_clock; /* The Timer of Death. Muahahahaha. */
void *doomsday_clock_dead; /* data for the doomsday clock */
//#endif
Ecore_Exe_Cb pre_free_cb;
Eina_Bool close_stdin : 1;
};
typedef struct _Ecore_Exe_Data Ecore_Exe_Data;
#ifdef _WIN32
void _win32_ecore_exe_run_priority_set(int pri);
int _win32_ecore_exe_run_priority_get(void);
Eo *_win32_ecore_exe_eo_base_finalize(Eo *obj, Ecore_Exe_Data *exe);
Eina_Bool _win32_ecore_exe_send(Ecore_Exe *obj, Ecore_Exe_Data *exe, const void *data, int size);
Ecore_Exe_Event_Data *ecore_exe_event_data_get(Ecore_Exe *obj, Ecore_Exe_Data *exe, Ecore_Exe_Flags flags);
void _win32_ecore_exe_eo_base_destructor(Eo *obj, Ecore_Exe_Data *exe);
void _win32_ecore_exe_pause(Ecore_Exe *obj, Ecore_Exe_Data *exe);
void _win32_ecore_exe_continue(Ecore_Exe *obj, Ecore_Exe_Data *exe);
void _win32_ecore_exe_interrupt(Ecore_Exe *obj, Ecore_Exe_Data *exe);
void _win32_ecore_exe_quit(Ecore_Exe *obj, Ecore_Exe_Data *exe);
void _win32_ecore_exe_terminate(Ecore_Exe *obj, Ecore_Exe_Data *exe);
void _win32_ecore_exe_kill(Ecore_Exe *obj, Ecore_Exe_Data *exe);
#endif

View File

@ -10,6 +10,8 @@
#include "Ecore.h"
#include "ecore_private.h"
#include "ecore_exe_private.h"
/*
* TESTS
*
@ -40,87 +42,6 @@ typedef enum
ECORE_EXE_WIN32_SIGKILL
} Ecore_Exe_Win32_Signal;
static Eina_List *exes = NULL;
static int run_pri = NORMAL_PRIORITY_CLASS;
struct _Ecore_Exe_Data
{
char *cmd;
char *tag;
HANDLE process;
HANDLE process_thread;
DWORD process_id;
DWORD thread_id;
void *data;
Ecore_Win32_Handler *h_close;
Ecore_Exe_Flags flags;
Ecore_Exe_Win32_Signal sig;
Ecore_Exe_Cb pre_free_cb;
struct
{
HANDLE child_pipe;
HANDLE child_pipe_x;
HANDLE thread;
void *data_buf;
DWORD data_size;
} pipe_read;
struct
{
HANDLE child_pipe;
HANDLE child_pipe_x;
void *data_buf;
int data_size;
} pipe_write;
struct
{
HANDLE child_pipe;
HANDLE child_pipe_x;
HANDLE thread;
void *data_buf;
DWORD data_size;
} pipe_error;
Eina_Bool close_threads : 1;
Eina_Bool close_stdin : 1;
Eina_Bool is_suspended : 1;
};
typedef struct _Ecore_Exe_Data Ecore_Exe_Data;
static void
_ecore_exe_event_add_free(void *data EINA_UNUSED,
void *ev)
{
free(ev);
}
static void
_ecore_exe_event_del_free(void *data EINA_UNUSED,
void *ev)
{
Ecore_Exe_Event_Del *e;
e = (Ecore_Exe_Event_Del *)ev;
if (e->exe)
ecore_exe_free(e->exe);
free(e);
}
static void
_ecore_exe_event_exe_data_free(void *data EINA_UNUSED,
void *ev)
{
Ecore_Exe_Event_Data *e;
e = (Ecore_Exe_Event_Data *)ev;
ecore_exe_event_data_free(e);
}
static Eina_Bool
_ecore_exe_close_cb(void *data,
Ecore_Win32_Handler *wh EINA_UNUSED)
@ -318,7 +239,7 @@ static BOOL CALLBACK
_ecore_exe_enum_windows_procedure(HWND window,
LPARAM data)
{
Ecore_Exe *exe = data;
Ecore_Exe *obj = (Ecore_Exe *) data;
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
DWORD thread_id;
@ -382,33 +303,8 @@ _ecore_exe_enum_windows_procedure(HWND window,
}
void
_ecore_exe_init(void)
_win32_ecore_exe_run_priority_set(int pri)
{
ECORE_EXE_EVENT_ADD = ecore_event_type_new();
ECORE_EXE_EVENT_DEL = ecore_event_type_new();
ECORE_EXE_EVENT_DATA = ecore_event_type_new();
ECORE_EXE_EVENT_ERROR = ecore_event_type_new();
}
void
_ecore_exe_shutdown(void)
{
Eina_List *l1, *l2;
Ecore_Exe *exe;
EINA_LIST_FOREACH_SAFE(exes, l1, l2, exe)
ecore_exe_free(exes);
}
EAPI int ECORE_EXE_EVENT_ADD = 0;
EAPI int ECORE_EXE_EVENT_DEL = 0;
EAPI int ECORE_EXE_EVENT_DATA = 0;
EAPI int ECORE_EXE_EVENT_ERROR = 0;
EAPI void
ecore_exe_run_priority_set(int pri)
{
EINA_MAIN_LOOP_CHECK_RETURN;
switch (pri)
{
case ECORE_EXE_WIN32_PRIORITY_IDLE:
@ -440,10 +336,9 @@ ecore_exe_run_priority_set(int pri)
}
}
EAPI int
ecore_exe_run_priority_get(void)
int
_win32_ecore_exe_run_priority_get(void)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
switch (run_pri)
{
case IDLE_PRIORITY_CLASS:
@ -470,24 +365,13 @@ ecore_exe_run_priority_get(void)
}
}
EAPI Ecore_Exe *
ecore_exe_run(const char *exe_cmd,
const void *data)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
return ecore_exe_pipe_run(exe_cmd, 0, data);
}
EAPI Ecore_Exe *
ecore_exe_pipe_run(const char *exe_cmd,
Ecore_Exe_Flags flags,
const void *data)
Eo *
_win32_ecore_exe_eo_base_finalize(Eo *obj, Ecore_Exe_Data *exe);
{
char exe_cmd_buf[PATH_MAX];
SECURITY_ATTRIBUTES sa;
STARTUPINFO si;
PROCESS_INFORMATION pi;
Ecore_Exe *obj;
Ecore_Exe_Event_Add *e;
Eina_Bool use_sh = EINA_FALSE;
const char *shell = NULL;
@ -495,14 +379,8 @@ ecore_exe_pipe_run(const char *exe_cmd,
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
DBG("Creating process %s", exe_cmd);
if (!exe_cmd || !*exe_cmd)
return NULL;
obj = eo_add(MY_CLASS, NULL, ecore_obj_exe_command_set(exe_cmd, flags));
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!obj)
return NULL;
const char *exe_cmd = exe->cmd;
Ecore_Exe_Flags flags = exe->flags;
if ((flags & ECORE_EXE_PIPE_AUTO) && (!(flags & ECORE_EXE_PIPE_ERROR))
&& (!(flags & ECORE_EXE_PIPE_READ)))
@ -539,8 +417,6 @@ ecore_exe_pipe_run(const char *exe_cmd,
exe_cmd_buf[sizeof(exe_cmd_buf) - 1] = '\0';
}
exe->flags = flags;
exe->cmd = strdup(exe_cmd_buf);
if (!exe->cmd)
goto free_exe;
@ -615,7 +491,6 @@ ecore_exe_pipe_run(const char *exe_cmd,
exe->process_thread = pi.hThread;
exe->process_id = pi.dwProcessId;
exe->thread_id = pi.dwThreadId;
exe->data = (void *)data;
exe->h_close = ecore_main_win32_handler_add(exe->process,
_ecore_exe_close_cb, obj);
@ -670,19 +545,9 @@ delete_h_close:
return NULL;
}
EAPI void
ecore_exe_callback_pre_free_set(Ecore_Exe *obj,
Ecore_Exe_Cb func)
{
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return;
exe->pre_free_cb = func;
}
EAPI Eina_Bool
ecore_exe_send(Ecore_Exe *obj,
Eina_Bool
_win32_ecore_exe_send(Ecore_Exe *obj,
Ecore_Exe_Data *exe,
const void *data,
int size)
{
@ -690,17 +555,6 @@ ecore_exe_send(Ecore_Exe *obj,
DWORD num_exe;
BOOL res;
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return EINA_FALSE;
if (exe->close_stdin)
{
ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p",
obj, size, data);
return EINA_FALSE;
}
buf = realloc(exe->pipe_write.data_buf, exe->pipe_write.data_size + size);
if (!buf) return EINA_FALSE;
@ -720,38 +574,15 @@ ecore_exe_send(Ecore_Exe *obj,
return EINA_TRUE;
}
EAPI void
ecore_exe_close_stdin(Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return;
exe->close_stdin = 1;
}
/* Not used on Windows */
EAPI void
ecore_exe_auto_limits_set(Ecore_Exe *exe EINA_UNUSED,
int start_bytes EINA_UNUSED,
int end_bytes EINA_UNUSED,
int start_lines EINA_UNUSED,
int end_lines EINA_UNUSED)
{
}
EAPI Ecore_Exe_Event_Data *
ecore_exe_event_data_get(Ecore_Exe *obj,
Ecore_Exe_Event_Data *
_win32_ecore_exe_event_data_get(Ecore_Exe *obj,
Ecore_Exe_Data *exe,
Ecore_Exe_Flags flags)
{
Ecore_Exe_Event_Data *e = NULL;
unsigned char *inbuf;
DWORD inbuf_num;
Eina_Bool is_buffered = EINA_FALSE;
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return NULL;
/* Sort out what sort of event we are. */
if (flags & ECORE_EXE_PIPE_READ)
@ -855,29 +686,14 @@ ecore_exe_event_data_get(Ecore_Exe *obj,
return e;
}
EAPI void
ecore_exe_event_data_free(Ecore_Exe_Event_Data *e)
{
if (!e) return;
IF_FREE(e->lines);
IF_FREE(e->data);
free(e);
}
EAPI void *
ecore_exe_free(Ecore_Exe *obj)
void
_win32_ecore_exe_eo_base_destructor(Eo *obj, Ecore_Exe_Data *exe)
{
void *data;
if (!exe) return NULL;
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return NULL;
data = exe->data;
if (exe->pre_free_cb)
exe->pre_free_cb(data, exe);
exe->pre_free_cb(data, obj);
/* if (exe->h_close) */
/* ecore_main_win32_handler_del(exe->h_close); */
@ -887,7 +703,7 @@ ecore_exe_free(Ecore_Exe *obj)
CloseHandle(exe->pipe_write.child_pipe);
if (exe->pipe_write.child_pipe_x)
CloseHandle(exe->pipe_write.child_pipe_x);
_ecore_exe_threads_terminate(exe);
_ecore_exe_threads_terminate(obj);
if (exe->pipe_error.child_pipe)
CloseHandle(exe->pipe_error.child_pipe);
if (exe->pipe_error.child_pipe_x)
@ -900,105 +716,11 @@ ecore_exe_free(Ecore_Exe *obj)
exes = eina_list_remove(exes, obj);
IF_FREE(exe->tag);
eo_del(exe);
return data;
}
EAPI pid_t
ecore_exe_pid_get(const Ecore_Exe *obj)
void
_win32_ecore_exe_pause(Ecore_Exe *obj, Ecore_Exe_Data *exe)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return -1;
return exe->process_id;
}
EAPI void
ecore_exe_tag_set(Ecore_Exe *obj,
const char *tag)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return;
IF_FREE(exe->tag);
if (tag)
exe->tag = strdup(tag);
else
exe->tag = NULL;
}
EAPI const char *
ecore_exe_tag_get(const Ecore_Exe *obj)
{
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return NULL;
return exe->tag;
}
EAPI const char *
ecore_exe_cmd_get(const Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return NULL;
return exe->cmd;
}
EAPI void *
ecore_exe_data_get(const Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return NULL;
return exe->data;
}
EAPI void *
ecore_exe_data_set(Ecore_Exe *obj,
void *data)
{
void *ret;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return NULL;
ret = exe->data;
exe->data = data;
return ret;
}
EAPI Ecore_Exe_Flags
ecore_exe_flags_get(const Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return 0;
return exe->flags;
}
EAPI void
ecore_exe_pause(Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return;
if (exe->is_suspended)
return;
@ -1006,14 +728,9 @@ ecore_exe_pause(Ecore_Exe *obj)
exe->is_suspended = 1;
}
EAPI void
ecore_exe_continue(Ecore_Exe *obj)
void
_win32_ecore_exe_continue(Ecore_Exe *obj, Ecore_Exe_Data *exe)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
if (!exe)
return;
if (!exe->is_suspended)
return;
@ -1021,8 +738,8 @@ ecore_exe_continue(Ecore_Exe *obj)
exe->is_suspended = 0;
}
EAPI void
ecore_exe_interrupt(Ecore_Exe *obj)
void
_win32_ecore_exe_interrupt(Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
@ -1037,8 +754,8 @@ ecore_exe_interrupt(Ecore_Exe *obj)
while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)obj)) ;
}
EAPI void
ecore_exe_quit(Ecore_Exe *obj)
void
_win32_ecore_exe_quit(Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
@ -1053,8 +770,8 @@ ecore_exe_quit(Ecore_Exe *obj)
while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)obj)) ;
}
EAPI void
ecore_exe_terminate(Ecore_Exe *obj)
void
_win32_ecore_exe_terminate(Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
@ -1069,8 +786,8 @@ ecore_exe_terminate(Ecore_Exe *obj)
while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)obj)) ;
}
EAPI void
ecore_exe_kill(Ecore_Exe *obj)
void
_win32_ecore_exe_kill(Ecore_Exe *obj)
{
EINA_MAIN_LOOP_CHECK_RETURN;
Ecore_Exe_Data *exe = eo_data_scope_get(obj, ECORE_EXE_CLASS);
@ -1084,18 +801,3 @@ ecore_exe_kill(Ecore_Exe *obj)
exe->sig = ECORE_EXE_WIN32_SIGKILL;
while (EnumWindows(_ecore_exe_enum_windows_procedure, (LPARAM)obj)) ;
}
EAPI void
ecore_exe_signal(Ecore_Exe *exe EINA_UNUSED,
int num EINA_UNUSED)
{
/* does nothing */
}
EAPI void
ecore_exe_hup(Ecore_Exe *exe EINA_UNUSED)
{
/* does nothing */
}
#include "ecore_exe.eo.c"