forked from enlightenment/efl
164 lines
7.7 KiB
C
164 lines
7.7 KiB
C
typedef enum
|
|
{
|
|
ECORE_EXE_WIN32_SIGINT,
|
|
ECORE_EXE_WIN32_SIGQUIT,
|
|
ECORE_EXE_WIN32_SIGTERM,
|
|
ECORE_EXE_WIN32_SIGKILL
|
|
} Ecore_Exe_Win32_Signal;
|
|
|
|
/* 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
|
|
{
|
|
void *data;
|
|
char *tag, *cmd;
|
|
Eo *loop;
|
|
|
|
#ifdef _WIN32
|
|
HANDLE process;
|
|
HANDLE process_thread;
|
|
DWORD thread_id;
|
|
Ecore_Win32_Handler *h_close;
|
|
Ecore_Exe_Win32_Signal sig;
|
|
|
|
Ecore_Thread *th;
|
|
|
|
struct {
|
|
HANDLE child_pipe;
|
|
void *data_buf;
|
|
int data_size;
|
|
} pipe_read;
|
|
|
|
struct {
|
|
HANDLE child_pipe;
|
|
void *data_buf;
|
|
int data_size;
|
|
} pipe_error;
|
|
|
|
struct {
|
|
HANDLE child_pipe;
|
|
HANDLE child_pipe_x;
|
|
} pipe_write;
|
|
|
|
Eina_Bool close_threads : 1;
|
|
Eina_Bool is_suspended : 1;
|
|
#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. */
|
|
#endif
|
|
|
|
Ecore_Exe_Cb pre_free_cb;
|
|
pid_t pid;
|
|
Ecore_Exe_Flags flags;
|
|
Eina_Bool close_stdin : 1;
|
|
};
|
|
|
|
typedef struct _Ecore_Exe_Data Ecore_Exe_Data;
|
|
|
|
EAPI extern int ECORE_EXE_EVENT_ADD;
|
|
EAPI extern int ECORE_EXE_EVENT_DEL;
|
|
EAPI extern int ECORE_EXE_EVENT_DATA;
|
|
EAPI extern int ECORE_EXE_EVENT_ERROR;
|
|
|
|
Ecore_Exe *_ecore_exe_find(pid_t pid);
|
|
void *_ecore_exe_event_del_new(void);
|
|
void _ecore_exe_event_del_free(void *data EINA_UNUSED, void *ev);
|
|
void _ecore_exe_event_exe_data_free(void *data EINA_UNUSED, void *ev);
|
|
Ecore_Exe_Event_Add * _ecore_exe_event_add_new(void);
|
|
void _ecore_exe_event_add_free(void *data EINA_UNUSED, void *ev);
|
|
|
|
void _impl_ecore_exe_run_priority_set(int pri);
|
|
int _impl_ecore_exe_run_priority_get(void);
|
|
void _impl_ecore_exe_auto_limits_set(Ecore_Exe *obj, Ecore_Exe_Data *exe, int start_bytes, int end_bytes, int start_lines, int end_lines);
|
|
Eo *_impl_ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe);
|
|
void _impl_ecore_exe_efl_control_suspend_set(Eo *obj EINA_UNUSED, Ecore_Exe_Data *exe, Eina_Bool suspend);
|
|
Eina_Bool _impl_ecore_exe_send(Ecore_Exe *obj, Ecore_Exe_Data *exe, const void *data, int size);
|
|
Ecore_Exe_Event_Data *_impl_ecore_exe_event_data_get(Ecore_Exe *obj, Ecore_Exe_Data *exe, Ecore_Exe_Flags flags);
|
|
void _impl_ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe);
|
|
void _impl_ecore_exe_pause(Ecore_Exe *obj, Ecore_Exe_Data *exe);
|
|
void _impl_ecore_exe_continue(Ecore_Exe *obj, Ecore_Exe_Data *exe);
|
|
void _impl_ecore_exe_interrupt(Ecore_Exe *obj, Ecore_Exe_Data *exe);
|
|
void _impl_ecore_exe_quit(Ecore_Exe *obj, Ecore_Exe_Data *exe);
|
|
void _impl_ecore_exe_terminate(Ecore_Exe *obj, Ecore_Exe_Data *exe);
|
|
void _impl_ecore_exe_kill(Ecore_Exe *obj, Ecore_Exe_Data *exe);
|
|
void _impl_ecore_exe_signal(Ecore_Exe *obj, Ecore_Exe_Data *exe, int num);
|
|
void _impl_ecore_exe_hup(Ecore_Exe *obj EINA_UNUSED, Ecore_Exe_Data *exe);
|