summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-11-09 15:59:04 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2017-12-15 14:16:53 +0900
commit5dd52fd09b7d79c70b3134423a87aa6400a2d994 (patch)
tree5b4b8823f857fc2188e14c861af4b21fe356ee45 /src/lib
parentccfa9ae2201a6b567859f8d16d2674c3be7b81f6 (diff)
ecore - begin moving data into the efl loop data in the object
we really should have data inside the loop object, so begin moving it one small thing at a time. this is the basics that will allow multiple efl loops. make an eo efl object and class for fd handlers that is efl loop bound make fd handlers really bound to their parent loop and not global as well as have a nice class/obj. create an message queue per loop and put legacy ecore events on top of it... and a lot more. this is not 100% done, but it's a lot of the core and groundwork. various ecore_timer_add(), ecore_diler_add() etc. need changes. The following still need doing: ecore_timer (internal usage for sure) ecore_idler (internal usage for sure) ecore_idle_enterer ecore_idle_exiter ecore_pollers? (is the new efl loop stuff ok?) ecore_exe (fork/spawn from any thread and track exe from that thread?) ecore_signal code ecore_throttle (should we have a single global too? we have per loop) ecore_app ? (should every loop be given its own argv/argc?) Lots of internal ecore code uses/calls these legacy calls and we should have efl loop replacements and/or use the ones we have The following will bedifferently designed for loop to loop control/messaging/ipc: ecore_thread ecore_pipe
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ecore/Ecore_Eo.h7
-rw-r--r--src/lib/ecore/ecore.c11
-rw-r--r--src/lib/ecore/ecore_alloc.c18
-rw-r--r--src/lib/ecore/ecore_event_message.c81
-rw-r--r--src/lib/ecore/ecore_event_message.eo34
-rw-r--r--src/lib/ecore/ecore_event_message_handler.c414
-rw-r--r--src/lib/ecore/ecore_event_message_handler.eo86
-rw-r--r--src/lib/ecore/ecore_events.c644
-rw-r--r--src/lib/ecore/ecore_exe.c163
-rw-r--r--src/lib/ecore/ecore_exe_posix.c1562
-rw-r--r--src/lib/ecore/ecore_exe_private.h7
-rw-r--r--src/lib/ecore/ecore_exe_win32.c7
-rw-r--r--src/lib/ecore/ecore_job.c2
-rw-r--r--src/lib/ecore/ecore_main.c3221
-rw-r--r--src/lib/ecore/ecore_main_common.h96
-rw-r--r--src/lib/ecore/ecore_main_timechanges.c88
-rw-r--r--src/lib/ecore/ecore_pipe.c350
-rw-r--r--src/lib/ecore/ecore_private.h170
-rw-r--r--src/lib/ecore/ecore_signal.c99
-rw-r--r--src/lib/ecore/ecore_time.c44
-rw-r--r--src/lib/ecore/ecore_timer.c433
-rw-r--r--src/lib/ecore/efl_loop.c717
-rw-r--r--src/lib/ecore/efl_loop.eo37
-rw-r--r--src/lib/ecore/efl_loop_handler.c341
-rw-r--r--src/lib/ecore/efl_loop_handler.eo72
-rw-r--r--src/lib/ecore/efl_loop_message.c83
-rw-r--r--src/lib/ecore/efl_loop_message.eo13
-rw-r--r--src/lib/ecore/efl_loop_message_handler.c145
-rw-r--r--src/lib/ecore/efl_loop_message_handler.eo38
-rw-r--r--src/lib/ecore/efl_promise.c36
-rw-r--r--src/lib/ecore/efl_promise.eo1
31 files changed, 5048 insertions, 3972 deletions
diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h
index 9203bf1e4d..be1929aa42 100644
--- a/src/lib/ecore/Ecore_Eo.h
+++ b/src/lib/ecore/Ecore_Eo.h
@@ -29,12 +29,18 @@
29 */ 29 */
30 30
31 31
32#include "ecore_event_message.eo.h"
33#include "ecore_event_message_handler.eo.h"
34
32/** 35/**
33 * @ingroup Ecore_MainLoop_Group 36 * @ingroup Ecore_MainLoop_Group
34 * 37 *
35 * @{ 38 * @{
36 */ 39 */
37 40
41#include "efl_loop_message.eo.h"
42#include "efl_loop_message_handler.eo.h"
43
38#include "efl_loop.eo.h" 44#include "efl_loop.eo.h"
39 45
40/** 46/**
@@ -56,6 +62,7 @@ EAPI int efl_loop_exit_code_process(Eina_Value *value);
56EAPI Eina_Future_Scheduler *efl_loop_future_scheduler_get(Eo *obj); 62EAPI Eina_Future_Scheduler *efl_loop_future_scheduler_get(Eo *obj);
57 63
58#include "efl_loop_fd.eo.h" 64#include "efl_loop_fd.eo.h"
65#include "efl_loop_handler.eo.h"
59 66
60#include "efl_promise.eo.h" 67#include "efl_promise.eo.h"
61 68
diff --git a/src/lib/ecore/ecore.c b/src/lib/ecore/ecore.c
index 97dc4b2aa3..0c19d4b482 100644
--- a/src/lib/ecore/ecore.c
+++ b/src/lib/ecore/ecore.c
@@ -273,14 +273,12 @@ ecore_init(void)
273 if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1; 273 if (getenv("ECORE_FPS_DEBUG")) _ecore_fps_debug = 1;
274 if (_ecore_fps_debug) _ecore_fps_debug_init(); 274 if (_ecore_fps_debug) _ecore_fps_debug_init();
275 if (!ecore_mempool_init()) goto shutdown_mempool; 275 if (!ecore_mempool_init()) goto shutdown_mempool;
276 if (!_ecore_event_init()) goto shutdown_mempool;
277 _ecore_main_loop_init(); 276 _ecore_main_loop_init();
277 if (!_ecore_event_init()) goto shutdown_event;
278 278
279 vpath = efl_add(EFL_VPATH_CORE_CLASS, NULL); 279 vpath = efl_add(EFL_VPATH_CORE_CLASS, NULL);
280 if (vpath) efl_vpath_manager_register(EFL_VPATH_MANAGER_CLASS, 0, vpath); 280 if (vpath) efl_vpath_manager_register(EFL_VPATH_MANAGER_CLASS, 0, vpath);
281 281
282 _mainloop_singleton = efl_add(EFL_LOOP_CLASS, NULL);
283
284 _ecore_signal_init(); 282 _ecore_signal_init();
285#ifndef HAVE_EXOTIC 283#ifndef HAVE_EXOTIC
286 _ecore_exe_init(); 284 _ecore_exe_init();
@@ -359,6 +357,9 @@ ecore_init(void)
359 357
360 return _ecore_init_count; 358 return _ecore_init_count;
361 359
360shutdown_event:
361 _ecore_event_shutdown();
362 _ecore_main_shutdown();
362shutdown_mempool: 363shutdown_mempool:
363 ecore_mempool_shutdown(); 364 ecore_mempool_shutdown();
364 efl_object_shutdown(); 365 efl_object_shutdown();
@@ -403,9 +404,6 @@ ecore_shutdown(void)
403 } 404 }
404#endif 405#endif
405 406
406 efl_del(_mainloop_singleton);
407 _mainloop_singleton = NULL;
408
409 if (_ecore_fps_debug) _ecore_fps_debug_shutdown(); 407 if (_ecore_fps_debug) _ecore_fps_debug_shutdown();
410 _ecore_poller_shutdown(); 408 _ecore_poller_shutdown();
411 _ecore_animator_shutdown(); 409 _ecore_animator_shutdown();
@@ -442,7 +440,6 @@ ecore_shutdown(void)
442#ifndef HAVE_EXOTIC 440#ifndef HAVE_EXOTIC
443 _ecore_exe_shutdown(); 441 _ecore_exe_shutdown();
444#endif 442#endif
445 _efl_loop_timer_shutdown();
446 _ecore_event_shutdown(); 443 _ecore_event_shutdown();
447 _ecore_main_shutdown(); 444 _ecore_main_shutdown();
448 _ecore_signal_shutdown(); 445 _ecore_signal_shutdown();
diff --git a/src/lib/ecore/ecore_alloc.c b/src/lib/ecore/ecore_alloc.c
index 3196b82a2d..c98ef92335 100644
--- a/src/lib/ecore/ecore_alloc.c
+++ b/src/lib/ecore/ecore_alloc.c
@@ -33,9 +33,9 @@ struct _Ecore_Mempool
33 } 33 }
34 34
35//GENERIC_ALLOC_FREE(Ecore_Animator, ecore_animator); 35//GENERIC_ALLOC_FREE(Ecore_Animator, ecore_animator);
36GENERIC_ALLOC_FREE(Ecore_Event_Handler, ecore_event_handler); 36//GENERIC_ALLOC_FREE(Ecore_Event_Handler, ecore_event_handler);
37GENERIC_ALLOC_FREE(Ecore_Event_Filter, ecore_event_filter); 37//GENERIC_ALLOC_FREE(Ecore_Event_Filter, ecore_event_filter);
38GENERIC_ALLOC_FREE(Ecore_Event, ecore_event); 38//GENERIC_ALLOC_FREE(Ecore_Event, ecore_event);
39//GENERIC_ALLOC_FREE(Ecore_Idle_Exiter, ecore_idle_exiter); 39//GENERIC_ALLOC_FREE(Ecore_Idle_Exiter, ecore_idle_exiter);
40//GENERIC_ALLOC_FREE(Ecore_Idle_Enterer, ecore_idle_enterer); 40//GENERIC_ALLOC_FREE(Ecore_Idle_Enterer, ecore_idle_enterer);
41//GENERIC_ALLOC_FREE(Ecore_Idler, ecore_idler); 41//GENERIC_ALLOC_FREE(Ecore_Idler, ecore_idler);
@@ -51,9 +51,9 @@ GENERIC_ALLOC_FREE(Ecore_Win32_Handler, ecore_win32_handler);
51 51
52static Ecore_Mempool *mempool_array[] = { 52static Ecore_Mempool *mempool_array[] = {
53// &ecore_animator_mp, 53// &ecore_animator_mp,
54 &ecore_event_handler_mp, 54// &ecore_event_handler_mp,
55 &ecore_event_filter_mp, 55// &ecore_event_filter_mp,
56 &ecore_event_mp, 56// &ecore_event_mp,
57// &ecore_idle_exiter_mp, 57// &ecore_idle_exiter_mp,
58// &ecore_idle_enterer_mp, 58// &ecore_idle_enterer_mp,
59// &ecore_idler_mp, 59// &ecore_idler_mp,
@@ -78,9 +78,9 @@ ecore_mempool_init(void)
78 Type##_mp.size = _ecore_sizeof_##TYPE 78 Type##_mp.size = _ecore_sizeof_##TYPE
79 79
80// MP_SIZE_INIT(Ecore_Animator, ecore_animator); 80// MP_SIZE_INIT(Ecore_Animator, ecore_animator);
81 MP_SIZE_INIT(Ecore_Event_Handler, ecore_event_handler); 81// MP_SIZE_INIT(Ecore_Event_Handler, ecore_event_handler);
82 MP_SIZE_INIT(Ecore_Event_Filter, ecore_event_filter); 82// MP_SIZE_INIT(Ecore_Event_Filter, ecore_event_filter);
83 MP_SIZE_INIT(Ecore_Event, ecore_event); 83// MP_SIZE_INIT(Ecore_Event, ecore_event);
84// MP_SIZE_INIT(Ecore_Idle_Exiter, ecore_idle_exiter); 84// MP_SIZE_INIT(Ecore_Idle_Exiter, ecore_idle_exiter);
85// MP_SIZE_INIT(Ecore_Idle_Enterer, ecore_idle_enterer); 85// MP_SIZE_INIT(Ecore_Idle_Enterer, ecore_idle_enterer);
86// MP_SIZE_INIT(Ecore_Idler, ecore_idler); 86// MP_SIZE_INIT(Ecore_Idler, ecore_idler);
diff --git a/src/lib/ecore/ecore_event_message.c b/src/lib/ecore/ecore_event_message.c
new file mode 100644
index 0000000000..ca072f8524
--- /dev/null
+++ b/src/lib/ecore/ecore_event_message.c
@@ -0,0 +1,81 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Ecore.h>
6
7#include "ecore_private.h"
8
9#define MY_CLASS ECORE_EVENT_MESSAGE_CLASS
10
11//////////////////////////////////////////////////////////////////////////
12
13typedef struct _Ecore_Event_Message_Data Ecore_Event_Message_Data;
14
15struct _Ecore_Event_Message_Data
16{
17 int type;
18 void *ev;
19 Ecore_End_Cb free_func;
20 void *data;
21};
22
23//////////////////////////////////////////////////////////////////////////
24
25EOLIAN static void
26_ecore_event_message_data_set(Eo *obj EINA_UNUSED, Ecore_Event_Message_Data *pd, int type, void *data, void *free_func, void *free_data)
27{
28 pd->type = type;
29 pd->ev = data;
30 pd->free_func = free_func;
31 pd->data = free_data;
32}
33
34EOLIAN static void
35_ecore_event_message_data_get(Eo *obj EINA_UNUSED, Ecore_Event_Message_Data *pd, int *type, void **data, void **free_func, void **free_data)
36{
37 if (type) *type = pd->type;
38 if (data) *data = pd->ev;
39 if (free_func) *free_func = pd->free_func;
40 if (free_data) *free_data = pd->data;
41}
42
43EOLIAN static void
44_ecore_event_message_data_steal(Eo *obj EINA_UNUSED, Ecore_Event_Message_Data *pd, int *type, void **data, void **free_func, void **free_data)
45{
46 if (type) *type = pd->type;
47 if (data) *data = pd->ev;
48 if (free_func) *free_func = pd->free_func;
49 if (free_data) *free_data = pd->data;
50 pd->type = -1;
51 pd->ev = NULL;
52 pd->free_func = NULL;
53 pd->data = NULL;
54}
55
56EOLIAN static Efl_Object *
57_ecore_event_message_efl_object_constructor(Eo *obj, Ecore_Event_Message_Data *pd EINA_UNUSED)
58{
59 obj = efl_constructor(efl_super(obj, MY_CLASS));
60 pd->type = -1;
61 return obj;
62}
63
64EOLIAN static void
65_ecore_event_message_efl_object_destructor(Eo *obj EINA_UNUSED, Ecore_Event_Message_Data *pd EINA_UNUSED)
66{
67 if (pd->ev)
68 {
69 Ecore_End_Cb fn_free = pd->free_func;
70 void *ev = pd->ev;
71
72 pd->ev = NULL;
73 if (fn_free) fn_free(pd->data, ev);
74 else free(ev);
75 }
76 efl_destructor(efl_super(obj, MY_CLASS));
77}
78
79//////////////////////////////////////////////////////////////////////////
80
81#include "ecore_event_message.eo.c"
diff --git a/src/lib/ecore/ecore_event_message.eo b/src/lib/ecore/ecore_event_message.eo
new file mode 100644
index 0000000000..002197a122
--- /dev/null
+++ b/src/lib/ecore/ecore_event_message.eo
@@ -0,0 +1,34 @@
1import efl_types;
2import eina_types;
3
4class Ecore.Event.Message (Efl.Loop.Message)
5{
6 [[ For Legacy API usage Only. Legacy Ecore Events ]]
7 methods {
8 @property data {
9 [[ Property of the legacy event - set and get it ]]
10 set { }
11 get { }
12 values {
13 type: int; [[ The event type ]]
14 data: void_ptr; [[ The event data ]]
15 free_func: void_ptr; [[ Being lazy for legacy ]]
16 free_data: void_ptr; [[ Free func data ]]
17 }
18 }
19 data_steal {
20 [[ Steal the data out and set internal values to -1
21 for type and NULL for other vals ]]
22 params {
23 @out type: int; [[ The event type ]]
24 @out data: void_ptr; [[ The event data ]]
25 @out free_func: void_ptr; [[ Being lazy for legacy ]]
26 @out free_data: void_ptr; [[ Free func data ]]
27 }
28 }
29 }
30 implements {
31 Efl.Object.constructor;
32 Efl.Object.destructor;
33 }
34}
diff --git a/src/lib/ecore/ecore_event_message_handler.c b/src/lib/ecore/ecore_event_message_handler.c
new file mode 100644
index 0000000000..3879c3c78e
--- /dev/null
+++ b/src/lib/ecore/ecore_event_message_handler.c
@@ -0,0 +1,414 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Ecore.h>
6
7#include "ecore_private.h"
8
9#define MY_CLASS ECORE_EVENT_MESSAGE_HANDLER_CLASS
10
11//////////////////////////////////////////////////////////////////////////
12
13typedef struct _Handler Handler;
14typedef struct _Filter Filter;
15
16struct _Handler
17{
18 EINA_INLIST;
19 Ecore_Event_Handler_Cb func;
20 void *data;
21 int type;
22 Eina_Bool delete_me : 1;
23 Eina_Bool to_add : 1;
24};
25
26struct _Filter
27{
28 EINA_INLIST;
29 Ecore_Data_Cb func_start;
30 Ecore_Filter_Cb func_filter;
31 Ecore_End_Cb func_end;
32 void *data;
33 void *loop_data;
34 Eina_Bool delete_me : 1;
35};
36
37typedef struct _Ecore_Event_Message_Handler_Data Ecore_Event_Message_Handler_Data;
38
39struct _Ecore_Event_Message_Handler_Data
40{
41 int event_type_count;
42 Eina_Inlist **handlers; // array of event_type_count inlists of handlers
43 Eina_Inlist *filters;
44 Eina_List *handlers_delete;
45 Eina_List *handlers_add;
46 Eina_List *filters_delete;
47 Eina_List *filters_add;
48 void *current_event_data;
49 int current_event_type;
50 int handlers_walking;
51 int filters_walking;
52};
53
54//////////////////////////////////////////////////////////////////////////
55
56Eina_Bool
57_ecore_event_do_filter(void *handler_pd, Eo *msg_handler, Eo *msg)
58{
59 Filter *f;
60 void *ev;
61 int type;
62 Ecore_Event_Message_Handler_Data *eemhd = handler_pd;
63
64 if (!eemhd->filters) return EINA_TRUE;
65 if (!efl_isa(msg_handler, MY_CLASS)) return EINA_TRUE;
66 eemhd->filters_walking++;
67 EINA_INLIST_FOREACH(eemhd->filters, f)
68 {
69 if (f->delete_me) continue;
70 type = -1;
71 ev = NULL;
72 ecore_event_message_data_get(msg, &type, &ev, NULL, NULL);
73 if (type >= 0)
74 {
75 if (!f->func_filter(f->data, f->loop_data, type, ev))
76 _efl_loop_message_unsend(msg);
77 }
78 }
79 eemhd->filters_walking--;
80 return EINA_TRUE;
81}
82
83void
84_ecore_event_filters_call(Eo *obj, Efl_Loop_Data *pd)
85{
86 Filter *f;
87 Ecore_Event_Message_Handler_Data *eemhd;
88 Eo *ecore_event_handler = efl_loop_message_handler_get
89 (EFL_LOOP_CLASS, obj, ECORE_EVENT_MESSAGE_HANDLER_CLASS);
90
91 if (!ecore_event_handler) return;
92 eemhd = efl_data_scope_get(ecore_event_handler, MY_CLASS);
93 if (!eemhd) return;
94 if (!eemhd->filters) return;
95 eemhd->filters_walking++;
96 EINA_INLIST_FOREACH(eemhd->filters, f)
97 {
98 if (f->delete_me) continue;
99 if (f->func_start) f->loop_data = f->func_start(f->data);
100 }
101 _efl_loop_messages_filter(obj, pd, eemhd);
102 EINA_INLIST_FOREACH(eemhd->filters, f)
103 {
104 if (f->delete_me) continue;
105 if (f->func_end) f->func_end(f->data, f->loop_data);
106 }
107 eemhd->filters_walking--;
108 if (eemhd->filters_walking == 0)
109 {
110 EINA_LIST_FREE(eemhd->filters_delete, f)
111 {
112 free(f);
113 }
114 }
115}
116
117//////////////////////////////////////////////////////////////////////////
118
119EOLIAN static Ecore_Event_Message *
120_ecore_event_message_handler_message_type_add(Eo *obj, Ecore_Event_Message_Handler_Data *pd EINA_UNUSED)
121{
122 // XXX: implemented event obj cache
123 return efl_add(ECORE_EVENT_MESSAGE_CLASS, obj);
124}
125
126EOLIAN static int
127_ecore_event_message_handler_type_new(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd)
128{
129 Eina_Inlist **tmp;
130 int evnum;
131
132 evnum = pd->event_type_count + 1;
133 tmp = realloc(pd->handlers, sizeof(Eina_Inlist *) * (evnum + 1));
134 if (!tmp) return 0;
135 pd->handlers = tmp;
136 pd->handlers[evnum] = NULL;
137 pd->event_type_count = evnum;
138 return evnum;
139}
140
141EOLIAN static void *
142_ecore_event_message_handler_handler_add(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd, int type, void *func, void *data)
143{
144 Handler *h;
145
146 if ((type < 0) || (type > pd->event_type_count) || (!func)) return NULL;
147 h = calloc(1, sizeof(Handler));
148 if (!h) return NULL;
149 h->func = func;
150 h->data = data;
151 h->type = type;
152 if (pd->current_event_type == type)
153 {
154 h->to_add = EINA_TRUE;
155 pd->handlers_add = eina_list_append(pd->handlers_add, h);
156 }
157 else
158 pd->handlers[type] = eina_inlist_append(pd->handlers[type],
159 EINA_INLIST_GET(h));
160 return h;
161}
162
163EOLIAN static void *
164_ecore_event_message_handler_handler_del(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd, void *handler)
165{
166 Handler *h = handler;
167 void *data;
168
169 if (!h) return NULL;
170 if ((h->type < 0) || (h->type > pd->event_type_count)) return NULL;
171 data = h->data;
172 if (pd->handlers_walking > 0)
173 {
174 h->delete_me = EINA_TRUE;
175 pd->handlers_delete = eina_list_append(pd->handlers_delete, h);
176 }
177 else
178 {
179 if (h->to_add)
180 pd->handlers_add = eina_list_remove(pd->handlers_add, h);
181 else
182 pd->handlers[h->type] = eina_inlist_remove(pd->handlers[h->type],
183 EINA_INLIST_GET(h));
184 free(h);
185 }
186 return data;
187}
188
189EOLIAN static void *
190_ecore_event_message_handler_handler_data_get(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd EINA_UNUSED, void *handler)
191{
192 Handler *h = handler;
193
194 if (!h) return NULL;
195 return h->data;
196}
197
198EOLIAN static void *
199_ecore_event_message_handler_handler_data_set(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd EINA_UNUSED, void *handler, void *data)
200{
201 Handler *h = handler;
202 void *prev_data;
203
204 if (!h) return NULL;
205 prev_data = h->data;
206 h->data = data;
207 return prev_data;
208}
209
210EOLIAN static void *
211_ecore_event_message_handler_filter_add(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd, void *func_start, void *func_filter, void *func_end, void *data)
212{
213 Filter *f;
214
215 if (!func_filter) return NULL;
216 f = calloc(1, sizeof(Filter));
217 if (!f) return NULL;
218 f->func_start = func_start;
219 f->func_filter = func_filter;
220 f->func_end = func_end;
221 f->data = data;
222 pd->filters = eina_inlist_append(pd->filters, EINA_INLIST_GET(f));
223 return f;
224}
225
226EOLIAN static void *
227_ecore_event_message_handler_filter_del(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd, void *filter)
228{
229 Filter *f = filter;
230 void *data;
231
232 if (!f) return NULL;
233 data = f->data;
234 if (pd->filters_walking > 0)
235 {
236 f->delete_me = EINA_TRUE;
237 pd->filters_delete = eina_list_append(pd->filters_delete, f);
238 }
239 else
240 {
241 pd->filters = eina_inlist_remove(pd->filters, EINA_INLIST_GET(f));
242 free(f);
243 }
244 return data;
245}
246
247EOLIAN static int
248_ecore_event_message_handler_current_type_get(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd)
249{
250 return pd->current_event_type;
251}
252
253EOLIAN static void *
254_ecore_event_message_handler_current_event_get(Eo *obj EINA_UNUSED, Ecore_Event_Message_Handler_Data *pd)
255{
256 return pd->current_event_data;
257}
258
259EOLIAN static Efl_Object *
260_ecore_event_message_handler_efl_object_constructor(Eo *obj, Ecore_Event_Message_Handler_Data *pd)
261{
262 obj = efl_constructor(efl_super(obj, MY_CLASS));
263 pd->event_type_count = -1;
264 pd->current_event_type = -1;
265 return obj;
266}
267
268EOLIAN static void
269_ecore_event_message_handler_efl_object_destructor(Eo *obj, Ecore_Event_Message_Handler_Data *pd)
270{
271 Handler *h;
272 int i;
273
274 if (pd->handlers_walking == 0)
275 {
276 EINA_LIST_FREE(pd->handlers_delete, h)
277 {
278 pd->handlers[h->type] =
279 eina_inlist_remove(pd->handlers[h->type],
280 EINA_INLIST_GET(h));
281 free(h);
282 }
283 EINA_LIST_FREE(pd->handlers_add, h)
284 {
285 free(h);
286 }
287 for (i = 0; i < pd->event_type_count; i++)
288 {
289 EINA_INLIST_FREE(pd->handlers[i], h) free(h);
290 }
291 free(pd->handlers);
292 pd->handlers = NULL;
293 }
294 else
295 {
296 ERR("Destruction of ecore_event_message_handler while walking events");
297 }
298 efl_destructor(efl_super(obj, MY_CLASS));
299}
300
301EOLIAN static void
302_ecore_event_message_handler_efl_loop_message_handler_message_call(Eo *obj, Ecore_Event_Message_Handler_Data *pd, Efl_Loop_Message *message)
303{
304 Handler *h;
305 int type = -1;
306 void *data = NULL, *free_func = NULL, *free_data = NULL;
307 Ecore_End_Cb fn_free = NULL;
308 Eina_List *l, *l2;
309 int handled = 0;
310
311 // call legacy handlers which are controled by this class' custom api
312 ecore_event_message_data_steal
313 (message, &type, &data, &free_func, &free_data);
314 if ((type >= 0) && (type <= pd->event_type_count))
315 {
316 if (free_func) fn_free = free_func;
317 pd->current_event_data = data;
318 pd->current_event_type = type;
319 pd->handlers_walking++;
320 EINA_INLIST_FOREACH(pd->handlers[type], h)
321 {
322 if (h->delete_me) continue;
323 handled++;
324 if (!h->func(h->data, h->type, data)) break;
325 }
326 pd->handlers_walking--;
327 pd->current_event_data = NULL;
328 pd->current_event_type = -1;
329 EINA_LIST_FOREACH_SAFE(pd->handlers_add, l, l2, h)
330 {
331 if (h->type == type)
332 {
333 h->to_add = EINA_FALSE;
334 pd->handlers_add =
335 eina_list_remove_list(pd->handlers_add, l);
336 pd->handlers[type] =
337 eina_inlist_append(pd->handlers[type], EINA_INLIST_GET(h));
338 }
339 }
340 if (pd->handlers_walking == 0)
341 {
342 EINA_LIST_FREE(pd->handlers_delete, h)
343 {
344 if (h->to_add)
345 pd->handlers_add = eina_list_remove(pd->handlers_add, h);
346 else
347 pd->handlers[h->type] =
348 eina_inlist_remove(pd->handlers[h->type],
349 EINA_INLIST_GET(h));
350 free(h);
351 }
352 }
353 if ((type == ECORE_EVENT_SIGNAL_EXIT) && (handled == 0))
354 {
355 Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS);
356
357 if (loop)
358 {
359 Eina_Value v = EINA_VALUE_EMPTY;
360 int val = 0;
361
362 eina_value_setup(&v, EINA_VALUE_TYPE_INT);
363 eina_value_set(&v, &val);
364 efl_loop_quit(loop, v);
365 }
366 }
367 }
368
369 efl_event_callback_call
370 (obj, ECORE_EVENT_MESSAGE_HANDLER_EVENT_MESSAGE_ECORE_EVENT, message);
371 efl_loop_message_handler_message_call
372 (efl_super(obj, MY_CLASS), message);
373
374 if (data)
375 {
376 if (fn_free) fn_free(free_data, data);
377 else free(data);
378 }
379}
380
381static Eina_Bool
382_flush_cb(void *data, void *handler EINA_UNUSED, void *message)
383{
384 int *type = data;
385 int evtype = -1;
386 void *evdata = NULL, *free_func = NULL, *free_data = NULL;
387 Ecore_End_Cb fn_free = NULL;
388
389 if (!efl_isa(message, ECORE_EVENT_MESSAGE_CLASS)) return EINA_TRUE;
390 ecore_event_message_data_steal(message, &evtype, &evdata, &free_func, &free_data);
391 if (*type != evtype) return EINA_TRUE;
392 if (free_func)
393 {
394 fn_free = free_func;
395 fn_free(free_data, evdata);
396 }
397 return EINA_FALSE;
398}
399
400EOLIAN static void
401_ecore_event_message_handler_type_flush(Eo *obj, Ecore_Event_Message_Handler_Data *pd EINA_UNUSED, int type)
402{
403 Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS);
404 Efl_Loop_Data *loop_data = efl_data_scope_get(loop, EFL_LOOP_CLASS);
405
406 if (loop && loop_data)
407 {
408 _efl_loop_messages_call(loop, loop_data, _flush_cb, &type);
409 }
410}
411
412//////////////////////////////////////////////////////////////////////////
413
414#include "ecore_event_message_handler.eo.c"
diff --git a/src/lib/ecore/ecore_event_message_handler.eo b/src/lib/ecore/ecore_event_message_handler.eo
new file mode 100644
index 0000000000..78047164ca
--- /dev/null
+++ b/src/lib/ecore/ecore_event_message_handler.eo
@@ -0,0 +1,86 @@
1import efl_types;
2import eina_types;
3
4class Ecore.Event.Message.Handler (Efl.Loop.Message.Handler)
5{
6 [[ For Legacy API usage Only
7 This class is rather hacky/messy as it's really internal glue
8 to handle legacy ecore events alongside the new loop message
9 stuff merged together. This is ugly as it's internal only
10 to quickly glue things together and is destined for death in
11 EFL 2.0 or when we dump legacy.
12 ]]
13 methods {
14 message_type_add {
15 [[ ]]
16 return: Ecore.Event.Message; [[ ]]
17 }
18 type_new {
19 [[ ]]
20 return: int; [[ ]]
21 }
22 handler_add {
23 [[ Legacy list of callback handlers so they can return false ]]
24 params {
25 type: int;
26 func: void_ptr;
27 data: void_ptr;
28 }
29 return: void_ptr; [[ Lazy return handle ]]
30 }
31 handler_del {
32 params {
33 handler: void_ptr; [[ handler returned from handler_add() ]]
34 }
35 return: void_ptr; [[ handler data ptr ]]
36 }
37 handler_data_get {
38 params {
39 handler: void_ptr; [[ handler returned from handler_add() ]]
40 }
41 return: void_ptr; [[ handler data ptr ]]
42 }
43 handler_data_set {
44 params {
45 handler: void_ptr; [[ handler returned from handler_add() ]]
46 data: void_ptr;
47 }
48 return: void_ptr; [[ prev handler data ptr ]]
49 }
50 filter_add {
51 [[ Legacy event filter ]]
52 params {
53 func_start: void_ptr;
54 func_filter: void_ptr;
55 func_end: void_ptr;
56 data: void_ptr;
57 }
58 return: void_ptr; [[ Lazy return filter handle ]]
59 }
60 filter_del {
61 params {
62 filter: void_ptr; [[ filter returned from filter_add() ]]
63 }
64 return: void_ptr; [[ filter data ptr ]]
65 }
66 current_type_get {
67 return: int; [[ ]]
68 }
69 current_event_get {
70 return: void_ptr; [[ ]]
71 }
72 type_flush {
73 params {
74 type: int; [[ the event type to flush ]]
75 }
76 }
77 }
78 events {
79 message,ecore,event: Ecore.Event.Message; [[ Sample - override this ]]
80 }
81 implements {
82 Efl.Object.constructor;
83 Efl.Object.destructor;
84 Efl.Loop.Message.Handler.message_call; [[ Sample - override this ]]
85 }
86}
diff --git a/src/lib/ecore/ecore_events.c b/src/lib/ecore/ecore_events.c
index ed405edb39..2a123a58fe 100644
--- a/src/lib/ecore/ecore_events.c
+++ b/src/lib/ecore/ecore_events.c
@@ -7,47 +7,6 @@
7#include "Ecore.h" 7#include "Ecore.h"
8#include "ecore_private.h" 8#include "ecore_private.h"
9 9
10static int inpurge = 0;
11
12struct _Ecore_Event_Handler
13{
14 EINA_INLIST;
15 ECORE_MAGIC;
16 int type;
17 Ecore_Event_Handler_Cb func;
18 void *data;
19 int references;
20 Eina_Bool delete_me : 1;
21};
22GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event_Handler);
23
24struct _Ecore_Event_Filter
25{
26 EINA_INLIST;
27 ECORE_MAGIC;
28 Ecore_Data_Cb func_start;
29 Ecore_Filter_Cb func_filter;
30 Ecore_End_Cb func_end;
31 void *loop_data;
32 void *data;
33 int references;
34 Eina_Bool delete_me : 1;
35};
36GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event_Filter);
37
38struct _Ecore_Event
39{
40 EINA_INLIST;
41 ECORE_MAGIC;
42 int type;
43 void *event;
44 Ecore_End_Cb func_free;
45 void *data;
46 int references;
47 Eina_Bool delete_me : 1;
48};
49GENERIC_ALLOC_SIZE_DECLARE(Ecore_Event);
50
51typedef struct _Ecore_Future_Schedule_Entry 10typedef struct _Ecore_Future_Schedule_Entry
52{ 11{
53 Eina_Future_Schedule_Entry base; 12 Eina_Future_Schedule_Entry base;
@@ -57,131 +16,45 @@ typedef struct _Ecore_Future_Schedule_Entry
57 Eina_Value value; 16 Eina_Value value;
58} Ecore_Future_Schedule_Entry; 17} Ecore_Future_Schedule_Entry;
59 18
60static int events_num = 0; 19//////
61static Ecore_Event *events = NULL; 20// XXX: still using legacy ecore events
62static Ecore_Event *event_current = NULL; 21static Ecore_Event_Handler *future_handler = NULL;
63static Ecore_Event *purge_events = NULL; 22static Eina_Bool shutting_down = EINA_FALSE;
64 23static Eina_Mempool *mp_future_schedule_entry = NULL;
65static Ecore_Event_Handler **event_handlers = NULL; 24static int ECORE_EV_FUTURE_ID = -1;
66static Ecore_Event_Handler *event_handler_current = NULL; 25//
67static int event_handlers_num = 0; 26//////
68static int event_handlers_alloc_num = 0; 27
69static Eina_List *event_handlers_delete_list = NULL; 28static Ecore_Event_Message_Handler *_event_msg_handler = NULL;
70
71static Ecore_Event_Handler *event_handlers_add_list = NULL;
72
73static Ecore_Event_Filter *event_filters = NULL;
74static Ecore_Event_Filter *event_filter_current = NULL;
75static Ecore_Event *event_filter_event_current = NULL;
76static int event_filters_delete_me = 0;
77static int event_id_max = ECORE_EVENT_COUNT;
78static int ecore_raw_event_type = ECORE_EVENT_NONE;
79static void *ecore_raw_event_event = NULL;
80static Ecore_Event_Handler *future_handler = NULL;
81static int ECORE_EV_FUTURE_ID = -1;
82static Eina_Mempool *mp_future_schedule_entry = NULL;
83static Eina_Bool shutting_down = EINA_FALSE;
84
85static void _ecore_event_purge_deleted(void);
86static void *_ecore_event_del(Ecore_Event *event);
87 29
88EAPI Ecore_Event_Handler * 30EAPI Ecore_Event_Handler *
89ecore_event_handler_add(int type, 31ecore_event_handler_add(int type,
90 Ecore_Event_Handler_Cb func, 32 Ecore_Event_Handler_Cb func,
91 const void *data) 33 const void *data)
92{ 34{
93 Ecore_Event_Handler *eh = NULL; 35 return ecore_event_message_handler_add(_event_msg_handler,
94 36 type, func, (void *)data);
95 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
96
97 if (!func) return NULL;
98 if ((type <= ECORE_EVENT_NONE) || (type >= event_id_max)) return NULL;
99 eh = ecore_event_handler_calloc(1);
100 if (!eh) return NULL;
101 ECORE_MAGIC_SET(eh, ECORE_MAGIC_EVENT_HANDLER);
102 eh->type = type;
103 eh->func = func;
104 eh->data = (void *)data;
105 if (type >= (event_handlers_num - 1))
106 {
107 int p_alloc_num;
108
109 p_alloc_num = event_handlers_alloc_num;
110 event_handlers_num = type + 1;
111 if (event_handlers_num > event_handlers_alloc_num)
112 {
113 Ecore_Event_Handler **new_handlers;
114 int i;
115
116 event_handlers_alloc_num = ((event_handlers_num + 16) / 16) * 16;
117 new_handlers = realloc(event_handlers, event_handlers_alloc_num * sizeof(Ecore_Event_Handler *));
118 if (!new_handlers)
119 {
120 ecore_event_handler_mp_free(eh);
121 return NULL;
122 }
123 event_handlers = new_handlers;
124 for (i = p_alloc_num; i < event_handlers_alloc_num; i++)
125 event_handlers[i] = NULL;
126 }
127 }
128 if (ecore_raw_event_type == type)
129 event_handlers_add_list = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers_add_list), EINA_INLIST_GET(eh));
130 else if (type < event_handlers_alloc_num)
131 event_handlers[type] = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers[type]), EINA_INLIST_GET(eh));
132
133 return eh;
134} 37}
135 38
136EAPI void * 39EAPI void *
137ecore_event_handler_del(Ecore_Event_Handler *event_handler) 40ecore_event_handler_del(Ecore_Event_Handler *event_handler)
138{ 41{
139 if (!event_handler) return NULL; 42 return ecore_event_message_handler_del(_event_msg_handler,
140 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 43 event_handler);
141 if (!ECORE_MAGIC_CHECK(event_handler, ECORE_MAGIC_EVENT_HANDLER))
142 {
143 ECORE_MAGIC_FAIL(event_handler, ECORE_MAGIC_EVENT_HANDLER,
144 "ecore_event_handler_del");
145 return NULL;
146 }
147 return _ecore_event_handler_del(event_handler);
148} 44}
149 45
150EAPI void * 46EAPI void *
151ecore_event_handler_data_get(Ecore_Event_Handler *eh) 47ecore_event_handler_data_get(Ecore_Event_Handler *eh)
152{ 48{
153 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 49 return ecore_event_message_handler_data_get(_event_msg_handler, eh);
154 if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER))
155 {
156 ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_get");
157 return NULL;
158 }
159 return eh->data;
160} 50}
161 51
162EAPI void * 52EAPI void *
163ecore_event_handler_data_set(Ecore_Event_Handler *eh, 53ecore_event_handler_data_set(Ecore_Event_Handler *eh,
164 const void *data) 54 const void *data)
165{ 55{
166 void *old = NULL; 56 return ecore_event_message_handler_data_set(_event_msg_handler, eh,
167 57 (void *)data);
168 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
169 if (!ECORE_MAGIC_CHECK(eh, ECORE_MAGIC_EVENT_HANDLER))
170 {
171 ECORE_MAGIC_FAIL(eh, ECORE_MAGIC_EVENT_HANDLER, "ecore_event_handler_data_set");
172 return NULL;
173 }
174 old = eh->data;
175 eh->data = (void *)data;
176
177 return old;
178}
179
180static void
181_ecore_event_generic_free(void *data EINA_UNUSED,
182 void *event)
183{ /* DO NOT MEMPOOL FREE THIS */
184 free(event);
185} 58}
186 59
187EAPI Ecore_Event * 60EAPI Ecore_Event *
@@ -190,34 +63,27 @@ ecore_event_add(int type,
190 Ecore_End_Cb func_free, 63 Ecore_End_Cb func_free,
191 void *data) 64 void *data)
192{ 65{
193 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 66 Ecore_Event_Message *msg;
194 67
195 if (type <= ECORE_EVENT_NONE) return NULL; 68 msg = ecore_event_message_handler_message_type_add(_event_msg_handler);
196 if (type >= event_id_max) return NULL; 69 ecore_event_message_data_set(msg, type, ev, func_free, data);
197 if ((ev) && (!func_free)) func_free = _ecore_event_generic_free; 70 efl_loop_message_handler_message_send(_event_msg_handler, msg);
198 return _ecore_event_add(type, ev, func_free, data); 71 return (Ecore_Event *)msg;
199} 72}
200 73
201EAPI void * 74EAPI void *
202ecore_event_del(Ecore_Event *event) 75ecore_event_del(Ecore_Event *event)
203{ 76{
204 if (!event) return NULL; 77 void *data = NULL;
205 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 78 ecore_event_message_data_get((Eo *)event, NULL, &data, NULL, NULL);
206 if (!ECORE_MAGIC_CHECK(event, ECORE_MAGIC_EVENT)) 79 _efl_loop_message_unsend((Eo *)event);
207 { 80 return data;
208 ECORE_MAGIC_FAIL(event, ECORE_MAGIC_EVENT, "ecore_event_del");
209 return NULL;
210 }
211 EINA_SAFETY_ON_TRUE_RETURN_VAL(event->delete_me, NULL);
212 event->delete_me = 1;
213 return event->data;
214} 81}
215 82
216EAPI int 83EAPI int
217ecore_event_type_new(void) 84ecore_event_type_new(void)
218{ 85{
219 EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); 86 return ecore_event_message_handler_type_new(_event_msg_handler);
220 return event_id_max++;
221} 87}
222 88
223EAPI Ecore_Event_Filter * 89EAPI Ecore_Event_Filter *
@@ -226,59 +92,27 @@ ecore_event_filter_add(Ecore_Data_Cb func_start,
226 Ecore_End_Cb func_end, 92 Ecore_End_Cb func_end,
227 const void *data) 93 const void *data)
228{ 94{
229 Ecore_Event_Filter *ef = NULL; 95 return ecore_event_message_handler_filter_add(_event_msg_handler,
230 96 func_start, func_filter,
231 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 97 func_end, (void *)data);
232 if (!func_filter) return NULL;
233 ef = ecore_event_filter_calloc(1);
234 if (!ef) return NULL;
235 ECORE_MAGIC_SET(ef, ECORE_MAGIC_EVENT_FILTER);
236 ef->func_start = func_start;
237 ef->func_filter = func_filter;
238 ef->func_end = func_end;
239 ef->data = (void *)data;
240 event_filters = (Ecore_Event_Filter *)eina_inlist_append(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
241
242 return ef;
243} 98}
244 99
245EAPI void * 100EAPI void *
246ecore_event_filter_del(Ecore_Event_Filter *ef) 101ecore_event_filter_del(Ecore_Event_Filter *ef)
247{ 102{
248 if (!ef) return NULL; 103 return ecore_event_message_handler_filter_del(_event_msg_handler, ef);
249 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
250 if (!ECORE_MAGIC_CHECK(ef, ECORE_MAGIC_EVENT_FILTER))
251 {
252 ECORE_MAGIC_FAIL(ef, ECORE_MAGIC_EVENT_FILTER, "ecore_event_filter_del");
253 return NULL;
254 }
255 EINA_SAFETY_ON_TRUE_RETURN_VAL(ef->delete_me, NULL);
256 ef->delete_me = 1;
257 event_filters_delete_me = 1;
258 return ef->data;
259} 104}
260 105
261EAPI int 106EAPI int
262ecore_event_current_type_get(void) 107ecore_event_current_type_get(void)
263{ 108{
264 EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); 109 return ecore_event_message_handler_current_type_get(_event_msg_handler);
265 return ecore_raw_event_type;
266} 110}
267 111
268EAPI void * 112EAPI void *
269ecore_event_current_event_get(void) 113ecore_event_current_event_get(void)
270{ 114{
271 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 115 return ecore_event_message_handler_current_event_get(_event_msg_handler);
272 return ecore_raw_event_event;
273}
274
275EAPI void *
276_ecore_event_handler_del(Ecore_Event_Handler *event_handler)
277{
278 EINA_SAFETY_ON_TRUE_RETURN_VAL(event_handler->delete_me, NULL);
279 event_handler->delete_me = 1;
280 event_handlers_delete_list = eina_list_append(event_handlers_delete_list, event_handler);
281 return event_handler->data;
282} 116}
283 117
284static Eina_Bool 118static Eina_Bool
@@ -294,12 +128,6 @@ static void
294ecore_future_free(void *user_data, void *func_data EINA_UNUSED) 128ecore_future_free(void *user_data, void *func_data EINA_UNUSED)
295{ 129{
296 Ecore_Future_Schedule_Entry *entry = user_data; 130 Ecore_Future_Schedule_Entry *entry = user_data;
297 /*
298 In case entry->event is not NULL, it means
299 that ecore is shutting down. In this case,
300 we must cancel the future otherwise Eina may
301 try to use it and lead to crashes.
302 */
303 if (entry->event) 131 if (entry->event)
304 { 132 {
305 eina_future_cancel(entry->future); 133 eina_future_cancel(entry->future);
@@ -355,6 +183,44 @@ _ecore_event_init(void)
355 const char *choice = getenv("EINA_MEMPOOL"); 183 const char *choice = getenv("EINA_MEMPOOL");
356 if ((!choice) || (!choice[0])) choice = "chained_mempool"; 184 if ((!choice) || (!choice[0])) choice = "chained_mempool";
357 185
186 _event_msg_handler =
187 efl_loop_message_handler_get(EFL_LOOP_CLASS,
188 _mainloop_singleton,
189 ECORE_EVENT_MESSAGE_HANDLER_CLASS);
190 if (!_event_msg_handler)
191 {
192 ERR("Cannot create legacy ecore event message handler");
193 return EINA_FALSE;
194 }
195 // init some core legacy event types in t he same order and numbering as before
196 // ECORE_EVENT_NONE 0
197 // no need to do as ev types start at 1
198
199 // ECORE_EVENT_SIGNAL_USER 1
200 ecore_event_message_handler_type_new(_event_msg_handler);
201 // ECORE_EVENT_SIGNAL_HUP 2
202 ecore_event_message_handler_type_new(_event_msg_handler);
203 // ECORE_EVENT_SIGNAL_EXIT 3
204 ecore_event_message_handler_type_new(_event_msg_handler);
205 // ECORE_EVENT_SIGNAL_POWER 4
206 ecore_event_message_handler_type_new(_event_msg_handler);
207 // ECORE_EVENT_SIGNAL_REALTIME 5
208 ecore_event_message_handler_type_new(_event_msg_handler);
209 // ECORE_EVENT_MEMORY_STATE 6
210 ecore_event_message_handler_type_new(_event_msg_handler);
211 // ECORE_EVENT_POWER_STATE 7
212 ecore_event_message_handler_type_new(_event_msg_handler);
213 // ECORE_EVENT_LOCALE_CHANGED 8
214 ecore_event_message_handler_type_new(_event_msg_handler);
215 // ECORE_EVENT_HOSTNAME_CHANGED 9
216 ecore_event_message_handler_type_new(_event_msg_handler);
217 // ECORE_EVENT_SYSTEM_TIMEDATE_CHANGED 10
218 ecore_event_message_handler_type_new(_event_msg_handler);
219 // ECORE_EVENT_COUNT 11
220 // no need to do as it was a count, nto an event
221
222 //////
223 // XXX: ecore future still using legacy...
358 shutting_down = EINA_FALSE; 224 shutting_down = EINA_FALSE;
359 ECORE_EV_FUTURE_ID = ecore_event_type_new(); 225 ECORE_EV_FUTURE_ID = ecore_event_type_new();
360 future_handler = ecore_event_handler_add(ECORE_EV_FUTURE_ID, ecore_future_dispatched, NULL); 226 future_handler = ecore_event_handler_add(ECORE_EV_FUTURE_ID, ecore_future_dispatched, NULL);
@@ -364,6 +230,8 @@ _ecore_event_init(void)
364 NULL, sizeof(Ecore_Future_Schedule_Entry), 230 NULL, sizeof(Ecore_Future_Schedule_Entry),
365 512); 231 512);
366 EINA_SAFETY_ON_NULL_GOTO(mp_future_schedule_entry, err_pool); 232 EINA_SAFETY_ON_NULL_GOTO(mp_future_schedule_entry, err_pool);
233 //
234 //////
367 235
368 return EINA_TRUE; 236 return EINA_TRUE;
369 237
@@ -378,337 +246,42 @@ _ecore_event_init(void)
378void 246void
379_ecore_event_shutdown(void) 247_ecore_event_shutdown(void)
380{ 248{
381 int i;
382 Ecore_Event_Handler *eh;
383 Ecore_Event_Filter *ef;
384
385 shutting_down = EINA_TRUE; 249 shutting_down = EINA_TRUE;
250
251 //////
252 // XXX: ecore future still using legacy...
386 ecore_event_handler_del(future_handler); 253 ecore_event_handler_del(future_handler);
387 future_handler = NULL; 254 future_handler = NULL;
388 while (events) _ecore_event_del(events);
389 event_current = NULL;
390 for (i = 0; i < event_handlers_num; i++)
391 {
392 while ((eh = event_handlers[i]))
393 {
394 event_handlers[i] = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers[i]), EINA_INLIST_GET(event_handlers[i]));
395 ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
396 if (!eh->delete_me) ecore_event_handler_mp_free(eh);
397 }
398 }
399 EINA_LIST_FREE(event_handlers_delete_list, eh)
400 ecore_event_handler_mp_free(eh);
401 if (event_handlers) free(event_handlers);
402 event_handlers = NULL;
403 event_handlers_num = 0;
404 event_handlers_alloc_num = 0;
405 while ((ef = event_filters))
406 {
407 event_filters = (Ecore_Event_Filter *)eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(event_filters));
408 ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
409 ecore_event_filter_mp_free(ef);
410 }
411 event_filters_delete_me = 0;
412 event_filter_current = NULL;
413 event_filter_event_current = NULL;
414 ECORE_EV_FUTURE_ID = -1; 255 ECORE_EV_FUTURE_ID = -1;
415} 256 //
416 257 //////
417int
418_ecore_event_exist(void)
419{
420 Ecore_Event *e;
421 EINA_INLIST_FOREACH(events, e)
422 if (!e->delete_me) return 1;
423 return 0;
424}
425
426Ecore_Event *
427_ecore_event_add(int type,
428 void *ev,
429 Ecore_End_Cb func_free,
430 void *data)
431{
432 Ecore_Event *e;
433
434 e = ecore_event_calloc(1);
435 if (!e) return NULL;
436 ECORE_MAGIC_SET(e, ECORE_MAGIC_EVENT);
437 e->type = type;
438 e->event = ev;
439 e->func_free = func_free;
440 e->data = data;
441 if (inpurge > 0)
442 {
443 purge_events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(e));
444 events_num++;
445 }
446 else
447 {
448 events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e));
449 events_num++;
450 }
451 return e;
452}
453
454void *
455_ecore_event_del(Ecore_Event *event)
456{
457 void *data;
458
459 data = event->data;
460 if (event->func_free) _ecore_call_end_cb(event->func_free, event->data, event->event);
461 events = (Ecore_Event *)eina_inlist_remove(EINA_INLIST_GET(events), EINA_INLIST_GET(event));
462 ECORE_MAGIC_SET(event, ECORE_MAGIC_NONE);
463 ecore_event_mp_free(event);
464 events_num--;
465 return data;
466}
467
468static void
469_ecore_event_purge_deleted(void)
470{
471 Ecore_Event *itr = events;
472 258
473 inpurge++; 259 efl_loop_message_handler_message_clear(_event_msg_handler);
474 while (itr) 260 _event_msg_handler = NULL;
475 {
476 Ecore_Event *next = (Ecore_Event *)EINA_INLIST_GET(itr)->next;
477 if ((!itr->references) && (itr->delete_me))
478 _ecore_event_del(itr);
479 itr = next;
480 }
481 inpurge--;
482 while (purge_events)
483 {
484 Ecore_Event *e = purge_events;
485 purge_events = (Ecore_Event *)eina_inlist_remove(EINA_INLIST_GET(purge_events), EINA_INLIST_GET(purge_events));
486 events = (Ecore_Event *)eina_inlist_append(EINA_INLIST_GET(events), EINA_INLIST_GET(e));
487 }
488}
489
490static inline void
491_ecore_event_filters_apply(void)
492{
493 if (!event_filter_current)
494 {
495 /* regular main loop, start from head */
496 event_filter_current = event_filters;
497 }
498 else
499 {
500 /* recursive main loop, continue from where we were */
501 event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
502 }
503 if ((!event_filter_current) && (!event_filters_delete_me) && (!purge_events)) return;
504 eina_evlog("+event_filter", NULL, 0.0, NULL);
505 while (event_filter_current)
506 {
507 Ecore_Event_Filter *ef = event_filter_current;
508
509 if (!ef->delete_me)
510 {
511 ef->references++;
512
513 if (ef->func_start)
514 ef->loop_data = _ecore_call_data_cb(ef->func_start, ef->data);
515
516 if (!event_filter_event_current)
517 {
518 /* regular main loop, start from head */
519 event_filter_event_current = events;
520 }
521 else
522 {
523 /* recursive main loop, continue from where we were */
524 event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next;
525 }
526
527 while (event_filter_event_current)
528 {
529 Ecore_Event *e = event_filter_event_current;
530
531 if (!_ecore_call_filter_cb(ef->func_filter, ef->data,
532 ef->loop_data, e->type, e->event))
533 {
534 ecore_event_del(e);
535 }
536
537 if (event_filter_event_current) /* may have changed in recursive main loops */
538 event_filter_event_current = (Ecore_Event *)EINA_INLIST_GET(event_filter_event_current)->next;
539 }
540 if (ef->func_end)
541 _ecore_call_end_cb(ef->func_end, ef->data, ef->loop_data);
542
543 ef->references--;
544 }
545
546 if (event_filter_current) /* may have changed in recursive main loops */
547 event_filter_current = (Ecore_Event_Filter *)EINA_INLIST_GET(event_filter_current)->next;
548 }
549 eina_evlog("-event_filter", NULL, 0.0, NULL);
550 if (event_filters_delete_me)
551 {
552 int deleted_in_use = 0;
553 Ecore_Event_Filter *l;
554 for (l = event_filters; l; )
555 {
556 Ecore_Event_Filter *ef = l;
557 l = (Ecore_Event_Filter *)EINA_INLIST_GET(l)->next;
558 if (ef->delete_me)
559 {
560 if (ef->references)
561 {
562 deleted_in_use++;
563 continue;
564 }
565
566 event_filters = (Ecore_Event_Filter *)eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
567 ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
568 ecore_event_filter_mp_free(ef);
569 }
570 }
571 if (!deleted_in_use)
572 event_filters_delete_me = 0;
573 }
574}
575
576void
577_ecore_event_call(void)
578{
579 Eina_List *l, *l_next;
580 Ecore_Event_Handler *eh;
581
582 _ecore_event_filters_apply();
583
584 if (!event_current)
585 {
586 /* regular main loop, start from head */
587 event_current = events;
588 event_handler_current = NULL;
589 }
590 if ((!event_current) && (!event_handlers_delete_list)) return;
591 eina_evlog("+events", NULL, 0.0, NULL);
592 while (event_current)
593 {
594 Ecore_Event *e = event_current;
595 int handle_count = 0;
596
597 if (e->delete_me)
598 {
599 event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
600 continue;
601 }
602
603 ecore_raw_event_type = e->type;
604 ecore_raw_event_event = e->event;
605 e->references++;
606 if ((e->type >= 0) && (e->type < event_handlers_num))
607 {
608 if (!event_handler_current)
609 {
610 /* regular main loop, start from head */
611 event_handler_current = event_handlers[e->type];
612 }
613 else
614 {
615 /* recursive main loop, continue from where we were */
616 event_handler_current = (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
617 }
618
619 while ((event_handler_current) && (!e->delete_me))
620 {
621 eh = event_handler_current;
622 if (!eh->delete_me)
623 {
624 Eina_Bool ret;
625
626 handle_count++;
627
628 eh->references++;
629 ret = _ecore_call_handler_cb(eh->func, eh->data, e->type, e->event);
630 eh->references--;
631
632 if (!ret)
633 {
634 event_handler_current = NULL;
635 break; /* 0 == "call no further handlers" */
636 }
637 }
638
639 if (event_handler_current) /* may have changed in recursive main loops */
640 event_handler_current = (Ecore_Event_Handler *)EINA_INLIST_GET(event_handler_current)->next;
641 }
642 }
643 while (event_handlers_add_list)
644 {
645 eh = event_handlers_add_list;
646 event_handlers_add_list = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers_add_list), EINA_INLIST_GET(eh));
647 event_handlers[eh->type] = (Ecore_Event_Handler *)eina_inlist_append(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
648 }
649 /* if no handlers were set for EXIT signal - then default is */
650 /* to quit the main loop */
651 if ((e->type == ECORE_EVENT_SIGNAL_EXIT) && (handle_count == 0))
652 ecore_main_loop_quit();
653 e->references--;
654 e->delete_me = 1;
655
656 if (event_current) /* may have changed in recursive main loops */
657 event_current = (Ecore_Event *)EINA_INLIST_GET(event_current)->next;
658 }
659 eina_evlog("-events", NULL, 0.0, NULL);
660
661 ecore_raw_event_type = ECORE_EVENT_NONE;
662 ecore_raw_event_event = NULL;
663
664 _ecore_event_purge_deleted();
665
666 EINA_LIST_FOREACH_SAFE(event_handlers_delete_list, l, l_next, eh)
667 {
668 if (eh->references) continue;
669
670 event_handlers_delete_list = eina_list_remove_list(event_handlers_delete_list, l);
671
672 event_handlers[eh->type] = (Ecore_Event_Handler *)eina_inlist_remove(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
673 ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
674 ecore_event_handler_mp_free(eh);
675 }
676} 261}
677 262
678void * 263void *
679_ecore_event_signal_user_new(void) 264_ecore_event_signal_user_new(void)
680{ 265{
681 Ecore_Event_Signal_User *e; 266 return calloc(1, sizeof(Ecore_Event_Signal_User));
682
683 e = calloc(1, sizeof(Ecore_Event_Signal_User));
684 return e;
685} 267}
686 268
687void * 269void *
688_ecore_event_signal_hup_new(void) 270_ecore_event_signal_hup_new(void)
689{ 271{
690 Ecore_Event_Signal_Hup *e; 272 return calloc(1, sizeof(Ecore_Event_Signal_Hup));
691
692 e = calloc(1, sizeof(Ecore_Event_Signal_Hup));
693 return e;
694} 273}
695 274
696void * 275void *
697_ecore_event_signal_exit_new(void) 276_ecore_event_signal_exit_new(void)
698{ 277{
699 Ecore_Event_Signal_Exit *e; 278 return calloc(1, sizeof(Ecore_Event_Signal_Exit));
700
701 e = calloc(1, sizeof(Ecore_Event_Signal_Exit));
702 return e;
703} 279}
704 280
705void * 281void *
706_ecore_event_signal_power_new(void) 282_ecore_event_signal_power_new(void)
707{ 283{
708 Ecore_Event_Signal_Power *e; 284 return calloc(1, sizeof(Ecore_Event_Signal_Power));
709
710 e = calloc(1, sizeof(Ecore_Event_Signal_Power));
711 return e;
712} 285}
713 286
714void * 287void *
@@ -720,58 +293,17 @@ _ecore_event_signal_realtime_new(void)
720EAPI void 293EAPI void
721ecore_event_type_flush_internal(int type, ...) 294ecore_event_type_flush_internal(int type, ...)
722{ 295{
723 Eina_Inarray types;
724 Ecore_Event *event;
725 Eina_Inlist *l;
726 int *itr;
727 va_list args; 296 va_list args;
728 Eina_Bool wrong_type = EINA_FALSE;
729 297
730 // In case of an empty list of event
731 if (type == ECORE_EVENT_NONE) return; 298 if (type == ECORE_EVENT_NONE) return;
732 299 ecore_event_message_handler_type_flush(_event_msg_handler, type);
733 eina_inarray_step_set(&types, sizeof (Eina_Inarray), sizeof (int), 4);
734
735 eina_inarray_push(&types, &type);
736 300
737 va_start(args, type); 301 va_start(args, type);
738 do 302 for (;;)
739 { 303 {
740 type = va_arg(args, int); 304 type = va_arg(args, int);
741 if (type == ECORE_EVENT_NONE) break ; 305 if (type == ECORE_EVENT_NONE) break;
742 eina_inarray_push(&types, &type); 306 ecore_event_message_handler_type_flush(_event_msg_handler, type);
743 } 307 }
744 while (1);
745 va_end(args); 308 va_end(args);
746
747 EINA_INARRAY_FOREACH(&types, itr)
748 {
749 if (*itr >= 0 && *itr < event_id_max) continue;
750
751 ERR("Invalid event flush requested: %i", *itr);
752 wrong_type = EINA_TRUE;
753 }
754
755 if (wrong_type)
756 {
757 eina_inarray_flush(&types);
758 return ;
759 }
760
761 EINA_INLIST_FOREACH_SAFE((Eina_Inlist *) events, l, event)
762 {
763 Eina_Bool found = EINA_FALSE;
764
765 EINA_INARRAY_FOREACH(&types, itr)
766 if (event->type == *itr)
767 found = EINA_TRUE;
768 if (!found) continue ;
769
770 if (event->delete_me) continue ;
771 event->delete_me = 1;
772 }
773
774 _ecore_event_purge_deleted();
775
776 eina_inarray_flush(&types);
777} 309}
diff --git a/src/lib/ecore/ecore_exe.c b/src/lib/ecore/ecore_exe.c
index 22486cd609..908f677539 100644
--- a/src/lib/ecore/ecore_exe.c
+++ b/src/lib/ecore/ecore_exe.c
@@ -38,8 +38,6 @@ EAPI int ECORE_EXE_EVENT_DEL = 0;
38EAPI int ECORE_EXE_EVENT_DATA = 0; 38EAPI int ECORE_EXE_EVENT_DATA = 0;
39EAPI int ECORE_EXE_EVENT_ERROR = 0; 39EAPI int ECORE_EXE_EVENT_ERROR = 0;
40 40
41Eina_List *_ecore_exe_exes = NULL;
42
43EAPI void 41EAPI void
44ecore_exe_run_priority_set(int pri) 42ecore_exe_run_priority_set(int pri)
45{ 43{
@@ -63,18 +61,19 @@ ecore_exe_run(const char *exe_cmd,
63} 61}
64 62
65EAPI Ecore_Exe * 63EAPI Ecore_Exe *
66ecore_exe_pipe_run(const char *exe_cmd, 64ecore_exe_pipe_run(const char *exe_cmd,
67 Ecore_Exe_Flags flags, 65 Ecore_Exe_Flags flags,
68 const void *data) 66 const void *data)
69{ 67{
70 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 68 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
71 Ecore_Exe *ret = efl_add(MY_CLASS, NULL, ecore_obj_exe_command_set(efl_added, exe_cmd, flags)); 69 Ecore_Exe *ret = efl_add(MY_CLASS, efl_loop_main_get(EFL_LOOP_CLASS),
70 ecore_obj_exe_command_set(efl_added, exe_cmd,
71 flags));
72 if (ret) 72 if (ret)
73 { 73 {
74 Ecore_Exe_Data *pd = efl_data_scope_get(ret, MY_CLASS); 74 Ecore_Exe_Data *pd = efl_data_scope_get(ret, MY_CLASS);
75 pd->data = (void *) data; 75 pd->data = (void *) data;
76 } 76 }
77
78 return ret; 77 return ret;
79} 78}
80 79
@@ -98,10 +97,7 @@ _ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe)
98{ 97{
99 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 98 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
100 obj = efl_finalize(efl_super(obj, MY_CLASS)); 99 obj = efl_finalize(efl_super(obj, MY_CLASS));
101 100 if (!obj) return obj;
102 if (!obj)
103 return obj;
104
105 return _impl_ecore_exe_efl_object_finalize(obj, exe); 101 return _impl_ecore_exe_efl_object_finalize(obj, exe);
106} 102}
107 103
@@ -111,8 +107,7 @@ ecore_exe_callback_pre_free_set(Ecore_Exe *obj,
111{ 107{
112 EINA_MAIN_LOOP_CHECK_RETURN; 108 EINA_MAIN_LOOP_CHECK_RETURN;
113 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 109 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
114 if (!efl_isa(obj, MY_CLASS)) 110 if (!efl_isa(obj, MY_CLASS)) return;
115 return;
116 exe->pre_free_cb = func; 111 exe->pre_free_cb = func;
117} 112}
118 113
@@ -123,18 +118,15 @@ ecore_exe_send(Ecore_Exe *obj,
123{ 118{
124 EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE); 119 EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE);
125 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 120 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
126 if (!efl_isa(obj, MY_CLASS)) 121 if (!efl_isa(obj, MY_CLASS)) return EINA_FALSE;
127 return EINA_FALSE;
128 122
129 EINA_SAFETY_ON_TRUE_RETURN_VAL(size == 0, EINA_TRUE); 123 EINA_SAFETY_ON_TRUE_RETURN_VAL(size == 0, EINA_TRUE);
130
131 if (exe->close_stdin) 124 if (exe->close_stdin)
132 { 125 {
133 ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p", 126 ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p",
134 exe, size, data); 127 exe, size, data);
135 return EINA_FALSE; 128 return EINA_FALSE;
136 } 129 }
137
138 return _impl_ecore_exe_send(obj, exe, data, size); 130 return _impl_ecore_exe_send(obj, exe, data, size);
139} 131}
140 132
@@ -143,9 +135,7 @@ ecore_exe_close_stdin(Ecore_Exe *obj)
143{ 135{
144 EINA_MAIN_LOOP_CHECK_RETURN; 136 EINA_MAIN_LOOP_CHECK_RETURN;
145 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 137 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
146 if (!efl_isa(obj, MY_CLASS)) 138 if (!efl_isa(obj, MY_CLASS)) return;
147 return;
148
149 exe->close_stdin = 1; 139 exe->close_stdin = 1;
150} 140}
151 141
@@ -158,10 +148,9 @@ ecore_exe_auto_limits_set(Ecore_Exe *obj,
158{ 148{
159 EINA_MAIN_LOOP_CHECK_RETURN; 149 EINA_MAIN_LOOP_CHECK_RETURN;
160 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 150 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
161 if (!efl_isa(obj, MY_CLASS)) 151 if (!efl_isa(obj, MY_CLASS)) return;
162 return; 152 _impl_ecore_exe_auto_limits_set(obj, exe, start_bytes, end_bytes,
163 153 start_lines, end_lines);
164 _impl_ecore_exe_auto_limits_set(obj, exe, start_bytes, end_bytes, start_lines, end_lines);
165} 154}
166 155
167EAPI Ecore_Exe_Event_Data * 156EAPI Ecore_Exe_Event_Data *
@@ -170,9 +159,7 @@ ecore_exe_event_data_get(Ecore_Exe *obj,
170{ 159{
171 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 160 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
172 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 161 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
173 if (!efl_isa(obj, MY_CLASS)) 162 if (!efl_isa(obj, MY_CLASS)) return NULL;
174 return NULL;
175
176 return _impl_ecore_exe_event_data_get(obj, exe, flags); 163 return _impl_ecore_exe_event_data_get(obj, exe, flags);
177} 164}
178 165
@@ -182,14 +169,10 @@ ecore_exe_tag_set(Ecore_Exe *obj,
182{ 169{
183 EINA_MAIN_LOOP_CHECK_RETURN; 170 EINA_MAIN_LOOP_CHECK_RETURN;
184 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 171 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
185 if (!efl_isa(obj, MY_CLASS)) 172 if (!efl_isa(obj, MY_CLASS)) return;
186 return;
187
188 IF_FREE(exe->tag); 173 IF_FREE(exe->tag);
189 if (tag) 174 if (tag) exe->tag = strdup(tag);
190 exe->tag = strdup(tag); 175 else exe->tag = NULL;
191 else
192 exe->tag = NULL;
193} 176}
194 177
195EAPI const char * 178EAPI const char *
@@ -197,9 +180,7 @@ ecore_exe_tag_get(const Ecore_Exe *obj)
197{ 180{
198 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 181 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
199 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 182 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
200 if (!efl_isa(obj, MY_CLASS)) 183 if (!efl_isa(obj, MY_CLASS)) return NULL;
201 return NULL;
202
203 return exe->tag; 184 return exe->tag;
204} 185}
205 186
@@ -208,12 +189,9 @@ ecore_exe_free(Ecore_Exe *obj)
208{ 189{
209 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 190 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
210 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 191 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
211 if (!efl_isa(obj, MY_CLASS)) 192 if (!efl_isa(obj, MY_CLASS)) return NULL;
212 return NULL;
213
214 void *data = exe->data; 193 void *data = exe->data;
215 efl_del(obj); 194 efl_del(obj);
216
217 return data; 195 return data;
218} 196}
219 197
@@ -221,7 +199,6 @@ EOLIAN static void
221_ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe) 199_ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe)
222{ 200{
223 efl_destructor(efl_super(obj, ECORE_EXE_CLASS)); 201 efl_destructor(efl_super(obj, ECORE_EXE_CLASS));
224
225 _impl_ecore_exe_efl_object_destructor(obj, exe); 202 _impl_ecore_exe_efl_object_destructor(obj, exe);
226} 203}
227 204
@@ -239,9 +216,7 @@ ecore_exe_pid_get(const Ecore_Exe *obj)
239{ 216{
240 EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); 217 EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
241 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 218 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
242 if (!efl_isa(obj, MY_CLASS)) 219 if (!efl_isa(obj, MY_CLASS)) return -1;
243 return -1;
244
245 return exe->pid; 220 return exe->pid;
246} 221}
247 222
@@ -250,9 +225,7 @@ ecore_exe_cmd_get(const Ecore_Exe *obj)
250{ 225{
251 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 226 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
252 const char *ret = NULL; 227 const char *ret = NULL;
253
254 ecore_obj_exe_command_get(obj, &ret, NULL); 228 ecore_obj_exe_command_get(obj, &ret, NULL);
255
256 return ret; 229 return ret;
257} 230}
258 231
@@ -261,9 +234,7 @@ ecore_exe_data_get(const Ecore_Exe *obj)
261{ 234{
262 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 235 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
263 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 236 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
264 if (!efl_isa(obj, MY_CLASS)) 237 if (!efl_isa(obj, MY_CLASS)) return NULL;
265 return NULL;
266
267 return exe->data; 238 return exe->data;
268} 239}
269 240
@@ -274,9 +245,7 @@ ecore_exe_data_set(Ecore_Exe *obj,
274 void *ret; 245 void *ret;
275 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); 246 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
276 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 247 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
277 if (!efl_isa(obj, MY_CLASS)) 248 if (!efl_isa(obj, MY_CLASS)) return NULL;
278 return NULL;
279
280 ret = exe->data; 249 ret = exe->data;
281 exe->data = data; 250 exe->data = data;
282 return ret; 251 return ret;
@@ -287,9 +256,7 @@ ecore_exe_flags_get(const Ecore_Exe *obj)
287{ 256{
288 EINA_MAIN_LOOP_CHECK_RETURN_VAL(0); 257 EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
289 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 258 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
290 if (!efl_isa(obj, MY_CLASS)) 259 if (!efl_isa(obj, MY_CLASS)) return 0;
291 return 0;
292
293 return exe->flags; 260 return exe->flags;
294} 261}
295 262
@@ -309,15 +276,8 @@ EOLIAN static void
309_ecore_exe_efl_control_suspend_set(Eo *obj EINA_UNUSED, Ecore_Exe_Data *exe, Eina_Bool suspend) 276_ecore_exe_efl_control_suspend_set(Eo *obj EINA_UNUSED, Ecore_Exe_Data *exe, Eina_Bool suspend)
310{ 277{
311 EINA_MAIN_LOOP_CHECK_RETURN; 278 EINA_MAIN_LOOP_CHECK_RETURN;
312 279 if (suspend) _impl_ecore_exe_pause(obj, exe);
313 if (suspend) 280 else _impl_ecore_exe_continue(obj, exe);
314 {
315 _impl_ecore_exe_pause(obj, exe);
316 }
317 else
318 {
319 _impl_ecore_exe_continue(obj, exe);
320 }
321} 281}
322 282
323EAPI void 283EAPI void
@@ -325,9 +285,7 @@ ecore_exe_interrupt(Ecore_Exe *obj)
325{ 285{
326 EINA_MAIN_LOOP_CHECK_RETURN; 286 EINA_MAIN_LOOP_CHECK_RETURN;
327 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 287 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
328 if (!efl_isa(obj, MY_CLASS)) 288 if (!efl_isa(obj, MY_CLASS)) return;
329 return;
330
331 _impl_ecore_exe_interrupt(obj, exe); 289 _impl_ecore_exe_interrupt(obj, exe);
332} 290}
333 291
@@ -336,9 +294,7 @@ ecore_exe_quit(Ecore_Exe *obj)
336{ 294{
337 EINA_MAIN_LOOP_CHECK_RETURN; 295 EINA_MAIN_LOOP_CHECK_RETURN;
338 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 296 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
339 if (!efl_isa(obj, MY_CLASS)) 297 if (!efl_isa(obj, MY_CLASS)) return;
340 return;
341
342 _impl_ecore_exe_quit(obj, exe); 298 _impl_ecore_exe_quit(obj, exe);
343} 299}
344 300
@@ -347,9 +303,7 @@ ecore_exe_terminate(Ecore_Exe *obj)
347{ 303{
348 EINA_MAIN_LOOP_CHECK_RETURN; 304 EINA_MAIN_LOOP_CHECK_RETURN;
349 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 305 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
350 if (!efl_isa(obj, MY_CLASS)) 306 if (!efl_isa(obj, MY_CLASS)) return;
351 return;
352
353 _impl_ecore_exe_terminate(obj, exe); 307 _impl_ecore_exe_terminate(obj, exe);
354} 308}
355 309
@@ -358,9 +312,7 @@ ecore_exe_kill(Ecore_Exe *obj)
358{ 312{
359 EINA_MAIN_LOOP_CHECK_RETURN; 313 EINA_MAIN_LOOP_CHECK_RETURN;
360 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 314 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
361 if (!efl_isa(obj, MY_CLASS)) 315 if (!efl_isa(obj, MY_CLASS)) return;
362 return;
363
364 _impl_ecore_exe_kill(obj, exe); 316 _impl_ecore_exe_kill(obj, exe);
365} 317}
366 318
@@ -370,9 +322,7 @@ ecore_exe_signal(Ecore_Exe *obj,
370{ 322{
371 EINA_MAIN_LOOP_CHECK_RETURN; 323 EINA_MAIN_LOOP_CHECK_RETURN;
372 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 324 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
373 if (!efl_isa(obj, MY_CLASS)) 325 if (!efl_isa(obj, MY_CLASS)) return;
374 return;
375
376 _impl_ecore_exe_signal(obj, exe, num); 326 _impl_ecore_exe_signal(obj, exe, num);
377} 327}
378 328
@@ -381,9 +331,7 @@ ecore_exe_hup(Ecore_Exe *obj)
381{ 331{
382 EINA_MAIN_LOOP_CHECK_RETURN; 332 EINA_MAIN_LOOP_CHECK_RETURN;
383 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 333 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
384 if (!efl_isa(obj, MY_CLASS)) 334 if (!efl_isa(obj, MY_CLASS)) return;
385 return;
386
387 _impl_ecore_exe_hup(obj, exe); 335 _impl_ecore_exe_hup(obj, exe);
388} 336}
389 337
@@ -401,7 +349,9 @@ _ecore_exe_shutdown(void)
401{ 349{
402 Ecore_Exe *exe = NULL; 350 Ecore_Exe *exe = NULL;
403 Eina_List *l1, *l2; 351 Eina_List *l1, *l2;
404 EINA_LIST_FOREACH_SAFE(_ecore_exe_exes, l1, l2, exe) 352 Efl_Loop_Data *loop = EFL_LOOP_DATA;
353
354 EINA_LIST_FOREACH_SAFE(loop->exes, l1, l2, exe)
405 ecore_exe_free(exe); 355 ecore_exe_free(exe);
406 356
407 ecore_event_type_flush(ECORE_EXE_EVENT_ADD, 357 ecore_event_type_flush(ECORE_EXE_EVENT_ADD,
@@ -415,22 +365,20 @@ _ecore_exe_find(pid_t pid)
415{ 365{
416 Eina_List *itr; 366 Eina_List *itr;
417 Ecore_Exe *obj; 367 Ecore_Exe *obj;
368 Efl_Loop_Data *loop = EFL_LOOP_DATA;
418 369
419 EINA_LIST_FOREACH(_ecore_exe_exes, itr, obj) 370 EINA_LIST_FOREACH(loop->exes, itr, obj)
420 { 371 {
421 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 372 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
422 if (exe->pid == pid) 373 if (exe->pid == pid) return obj;
423 return obj; 374 }
424 }
425 return NULL; 375 return NULL;
426} 376}
427 377
428void * 378void *
429_ecore_exe_event_del_new(void) 379_ecore_exe_event_del_new(void)
430{ 380{
431 Ecore_Exe_Event_Del *e; 381 Ecore_Exe_Event_Del *e = calloc(1, sizeof(Ecore_Exe_Event_Del));
432
433 e = calloc(1, sizeof(Ecore_Exe_Event_Del));
434 return e; 382 return e;
435} 383}
436 384
@@ -438,11 +386,8 @@ void
438_ecore_exe_event_del_free(void *data EINA_UNUSED, 386_ecore_exe_event_del_free(void *data EINA_UNUSED,
439 void *ev) 387 void *ev)
440{ 388{
441 Ecore_Exe_Event_Del *e; 389 Ecore_Exe_Event_Del *e = ev;
442 390 if (e->exe) ecore_exe_free(e->exe);
443 e = ev;
444 if (e->exe)
445 ecore_exe_free(e->exe);
446 free(e); 391 free(e);
447} 392}
448 393
@@ -450,18 +395,14 @@ void
450_ecore_exe_event_exe_data_free(void *data EINA_UNUSED, 395_ecore_exe_event_exe_data_free(void *data EINA_UNUSED,
451 void *ev) 396 void *ev)
452{ 397{
453 Ecore_Exe_Event_Data *e; 398 Ecore_Exe_Event_Data *e = ev;
454
455 e = ev;
456 ecore_exe_event_data_free(e); 399 ecore_exe_event_data_free(e);
457} 400}
458 401
459Ecore_Exe_Event_Add * 402Ecore_Exe_Event_Add *
460_ecore_exe_event_add_new(void) 403_ecore_exe_event_add_new(void)
461{ 404{
462 Ecore_Exe_Event_Add *e; 405 Ecore_Exe_Event_Add *e = calloc(1, sizeof(Ecore_Exe_Event_Add));
463
464 e = calloc(1, sizeof(Ecore_Exe_Event_Add));
465 return e; 406 return e;
466} 407}
467 408
@@ -469,9 +410,7 @@ void
469_ecore_exe_event_add_free(void *data EINA_UNUSED, 410_ecore_exe_event_add_free(void *data EINA_UNUSED,
470 void *ev) 411 void *ev)
471{ 412{
472 Ecore_Exe_Event_Add *e; 413 Ecore_Exe_Event_Add *e = ev;
473
474 e = ev;
475 free(e); 414 free(e);
476} 415}
477 416
diff --git a/src/lib/ecore/ecore_exe_posix.c b/src/lib/ecore/ecore_exe_posix.c
index bebfce26a1..21d8861ef2 100644
--- a/src/lib/ecore/ecore_exe_posix.c
+++ b/src/lib/ecore/ecore_exe_posix.c
@@ -43,60 +43,51 @@
43 * appended with a preceding space. The first is the command off course. 43 * appended with a preceding space. The first is the command off course.
44 */ 44 */
45 45
46struct _ecore_exe_dead_exe 46static inline void _ecore_exe_exec_it(const char *exe_cmd,
47{
48 pid_t pid;
49 char *cmd;
50};
51
52static inline void _ecore_exe_exec_it(const char *exe_cmd,
53 Ecore_Exe_Flags flags); 47 Ecore_Exe_Flags flags);
54static Eina_Bool _ecore_exe_data_generic_handler(void *data, 48static Eina_Bool _ecore_exe_data_generic_handler(void *data,
55 Ecore_Fd_Handler *fd_handler, 49 Ecore_Fd_Handler *fd_handler,
56 Ecore_Exe_Flags flags); 50 Ecore_Exe_Flags flags);
57static Eina_Bool _ecore_exe_data_error_handler(void *data, 51static Eina_Bool _ecore_exe_data_error_handler(void *data,
58 Ecore_Fd_Handler *fd_handler); 52 Ecore_Fd_Handler *fd_handler);
59static Eina_Bool _ecore_exe_data_read_handler(void *data, 53static Eina_Bool _ecore_exe_data_read_handler(void *data,
60 Ecore_Fd_Handler *fd_handler); 54 Ecore_Fd_Handler *fd_handler);
61static Eina_Bool _ecore_exe_data_write_handler(void *data, 55static Eina_Bool _ecore_exe_data_write_handler(void *data,
62 Ecore_Fd_Handler *fd_handler); 56 Ecore_Fd_Handler *fd_handler);
63static void _ecore_exe_flush(Ecore_Exe *obj); 57static void _ecore_exe_flush(Ecore_Exe *obj);
64static Ecore_Exe *_ecore_exe_is_it_alive(pid_t pid); 58static void _ecore_exe_make_sure_its_dead(void *data, const Efl_Event *event);
65static Eina_Bool _ecore_exe_make_sure_its_dead(void *data); 59static void _ecore_exe_make_sure_its_really_dead(void *data, const Efl_Event *event);
66static Eina_Bool _ecore_exe_make_sure_its_really_dead(void *data); 60static void _ecore_exe_dead_attach(Ecore_Exe *obj);
67static void _ecore_exe_dead_attach(Ecore_Exe *obj);
68 61
69static const char *shell = NULL; 62static const char *shell = NULL;
70 63
71/* FIXME: This errno checking stuff should be put elsewhere for everybody to use. 64/* FIXME: This errno checking stuff should be put elsewhere for everybody to use.
72 * For now it lives here though, just to make testing easier. 65 * For now it lives here though, just to make testing easier.
73 */ 66 */
74static int _ecore_exe_check_errno(int result, 67static int _ecore_exe_check_errno(int result,
75 const char *file, 68 const char *file,
76 int line); 69 int line);
77 70
78#define E_IF_NO_ERRNO(result, foo, ok) \ 71#define E_IF_NO_ERRNO(result, foo, ok) \
79 while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) \ 72 while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) sleep(1); \
80 sleep(1); \ 73 if (ok)
81 if (ok)
82 74
83#define E_NO_ERRNO(result, foo, ok) \ 75#define E_NO_ERRNO(result, foo, ok) \
84 while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) \ 76 while (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)) == -1) sleep(1)
85 sleep(1)
86 77
87#define E_IF_NO_ERRNO_NOLOOP(result, foo, ok) \ 78#define E_IF_NO_ERRNO_NOLOOP(result, foo, ok) \
88 if (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__))) 79 if (((ok) = _ecore_exe_check_errno((result) = (foo), __FILE__, __LINE__)))
89 80
90static int 81static int
91_ecore_exe_check_errno(int result, 82_ecore_exe_check_errno(int result,
92 const char *file EINA_UNUSED, 83 const char *file EINA_UNUSED,
93 int line EINA_UNUSED) 84 int line EINA_UNUSED)
94{ 85{
95 int saved_errno = errno; 86 int saved_errno = errno;
96 87
97 if (result == -1) 88 if (result == -1)
98 { 89 {
99 perror("*** errno reports "); 90 perror("*** errno reports ");
100/* What is currently supported - 91/* What is currently supported -
101 * 92 *
102 * pipe 93 * pipe
@@ -152,63 +143,63 @@ _ecore_exe_check_errno(int result,
152 * // Something failed, cleanup. 143 * // Something failed, cleanup.
153 * } 144 * }
154 */ 145 */
155 switch (saved_errno) 146 switch (saved_errno)
156 { 147 {
157 case EACCES: 148 case EACCES:
158 case EAGAIN: 149 case EAGAIN:
159 case EINTR: 150 case EINTR:
160 { /* Not now, try later. */ 151 { /* Not now, try later. */
161 ERR("*** Must try again in %s @%u.", file, line); 152 ERR("*** Must try again in %s @%u.", file, line);
162 result = -1; 153 result = -1;
163 break; 154 break;
164 } 155 }
165 156
166 case EMFILE: 157 case EMFILE:
167 case ENFILE: 158 case ENFILE:
168 case ENOLCK: 159 case ENOLCK:
169 { /* Low on resources. */ 160 { /* Low on resources. */
170 ERR("*** Low on resources in %s @%u.", file, 161 ERR("*** Low on resources in %s @%u.", file,
171 line); 162 line);
172 result = 0; 163 result = 0;
173 break; 164 break;
174 } 165 }
175 166
176 case EIO: 167 case EIO:
177 { /* I/O error. */ 168 { /* I/O error. */
178 ERR("*** I/O error in %s @%u.", file, line); 169 ERR("*** I/O error in %s @%u.", file, line);
179 result = 0; 170 result = 0;
180 break; 171 break;
181 } 172 }
182 173
183 case EFAULT: 174 case EFAULT:
184 case EBADF: 175 case EBADF:
185 case EINVAL: 176 case EINVAL:
186 case EROFS: 177 case EROFS:
187 case EISDIR: 178 case EISDIR:
188 case EDEADLK: 179 case EDEADLK:
189 case EPERM: 180 case EPERM:
190 case EBUSY: 181 case EBUSY:
191 { /* Programmer fucked up. */ 182 { /* Programmer fucked up. */
192 ERR("*** NAUGHTY PROGRAMMER!!!\n" 183 ERR("*** NAUGHTY PROGRAMMER!!!\n"
193 "*** SPANK SPANK SPANK!!!\n" 184 "*** SPANK SPANK SPANK!!!\n"
194 "*** Now go fix your code in %s @%u. Tut tut tut!", 185 "*** Now go fix your code in %s @%u. Tut tut tut!",
195 file, line); 186 file, line);
196 result = 0; 187 result = 0;
197 break; 188 break;
198 } 189 }
199 190
200 default: 191 default:
201 { /* Unsupported errno code, please add this one. */ 192 { /* Unsupported errno code, please add this one. */
202 ERR("*** NAUGHTY PROGRAMMER!!!\n" 193 ERR("*** NAUGHTY PROGRAMMER!!!\n"
203 "*** SPANK SPANK SPANK!!!\n" 194 "*** SPANK SPANK SPANK!!!\n"
204 "*** Unsupported errno code %d, please add this one.\n" 195 "*** Unsupported errno code %d, please add this one.\n"
205 "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!", 196 "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!",
206 saved_errno, __FILE__, __LINE__, file, line); 197 saved_errno, __FILE__, __LINE__, file, line);
207 result = 0; 198 result = 0;
208 break; 199 break;
209 } 200 }
210 } 201 }
211 } 202 }
212 else /* Everything is fine. */ 203 else /* Everything is fine. */
213 result = 1; 204 result = 1;
214 205
@@ -260,319 +251,327 @@ _impl_ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe)
260 251
261 /* Create some pipes. */ 252 /* Create some pipes. */
262 if (ok) 253 if (ok)
263 { 254 {
264 E_IF_NO_ERRNO_NOLOOP(result, pipe(statusPipe), ok) 255 E_IF_NO_ERRNO_NOLOOP(result, pipe(statusPipe), ok)
265 { 256 {
266 } 257 }
267 } 258 }
268 if (ok && (flags & ECORE_EXE_PIPE_ERROR)) 259 if (ok && (flags & ECORE_EXE_PIPE_ERROR))
269 { 260 {
270 E_IF_NO_ERRNO_NOLOOP(result, pipe(errorPipe), ok) 261 E_IF_NO_ERRNO_NOLOOP(result, pipe(errorPipe), ok)
271 { 262 {
272 exe->child_fd_error = errorPipe[0]; 263 exe->child_fd_error = errorPipe[0];
273 exe->child_fd_error_x = errorPipe[1]; 264 exe->child_fd_error_x = errorPipe[1];
274 } 265 }
275 } 266 }
276 if (ok && (flags & ECORE_EXE_PIPE_READ)) 267 if (ok && (flags & ECORE_EXE_PIPE_READ))
277 { 268 {
278 E_IF_NO_ERRNO_NOLOOP(result, pipe(readPipe), ok) 269 E_IF_NO_ERRNO_NOLOOP(result, pipe(readPipe), ok)
279 { 270 {
280 exe->child_fd_read = readPipe[0]; 271 exe->child_fd_read = readPipe[0];
281 exe->child_fd_read_x = readPipe[1]; 272 exe->child_fd_read_x = readPipe[1];
282 } 273 }
283 } 274 }
284 if (ok && (flags & ECORE_EXE_PIPE_WRITE)) 275 if (ok && (flags & ECORE_EXE_PIPE_WRITE))
285 { 276 {
286 E_IF_NO_ERRNO_NOLOOP(result, pipe(writePipe), ok) 277 E_IF_NO_ERRNO_NOLOOP(result, pipe(writePipe), ok)
287 { 278 {
288 exe->child_fd_write = writePipe[1]; 279 exe->child_fd_write = writePipe[1];
289 exe->child_fd_write_x = writePipe[0]; 280 exe->child_fd_write_x = writePipe[0];
290 } 281 }
291 } 282 }
292 if (ok) 283 if (ok)
293 { 284 {
294 pid_t pid = 0; 285 pid_t pid = 0;
295 volatile int vfork_exec_errno = 0; 286 volatile int vfork_exec_errno = 0;
296 287
297 /* FIXME: I should double check this. After a quick look around, this is already done, but via a more modern method. */ 288 /* FIXME: I should double check this. After a quick look around, this is already done, but via a more modern method. */
298 /* signal(SIGPIPE, SIG_IGN); We only want EPIPE on errors */ 289 /* signal(SIGPIPE, SIG_IGN); We only want EPIPE on errors */
299 pid = fork(); 290 pid = fork();
300 291
301 if (pid == -1) 292 if (pid == -1)
302 { 293 {
303 ERR("Failed to fork process"); 294 ERR("Failed to fork process");
304 pid = 0; 295 pid = 0;
305 } 296 }
306 else if (pid == 0) /* child */ 297 else if (pid == 0) /* child */
307 { 298 {
308#ifdef HAVE_SYSTEMD 299#ifdef HAVE_SYSTEMD
309 unsetenv("NOTIFY_SOCKET"); 300 unsetenv("NOTIFY_SOCKET");
310#endif 301#endif
311 if (run_pri != ECORE_EXE_PRIORITY_INHERIT) 302 if (run_pri != ECORE_EXE_PRIORITY_INHERIT)
312 { 303 {
313#ifdef PRIO_PROCESS 304#ifdef PRIO_PROCESS
314 if ((run_pri >= -20) && (run_pri <= 19)) 305 if ((run_pri >= -20) && (run_pri <= 19))
315 setpriority(PRIO_PROCESS, 0, run_pri); 306 setpriority(PRIO_PROCESS, 0, run_pri);
316#else 307#else
317#warning "Your OS/libc does not provide PRIO_PROCESS (and possibly setpriority())" 308#warning "Your OS/libc does not provide PRIO_PROCESS (and possibly setpriority())"
318#warning "This is a POSIX-1.2001 standard and it is highly encouraged that you" 309#warning "This is a POSIX-1.2001 standard and it is highly encouraged that you"
319#warning "Have support for this" 310#warning "Have support for this"
320#endif 311#endif
321 } 312 }
322 if (ok && (flags & ECORE_EXE_ISOLATE_IO)) 313 if (ok && (flags & ECORE_EXE_ISOLATE_IO))
323 { 314 {
324 int devnull; 315 int devnull;
325 316
326 /* we want to isolatie the stdin/out/err of the process so 317 /* we want to isolatie the stdin/out/err of the process so
327 * it can't share those of the parent, so close and replace with 318 * it can't share those of the parent, so close and replace with
328 * /dev/null */ 319 * /dev/null */
329 devnull = open("/dev/null", O_RDONLY); 320 devnull = open("/dev/null", O_RDONLY);
330 if (devnull >= 0) 321 if (devnull >= 0)
331 { 322 {
332 E_NO_ERRNO(result, close(STDIN_FILENO), ok); 323 E_NO_ERRNO(result, close(STDIN_FILENO), ok);
333 E_NO_ERRNO(result, dup2(devnull, STDIN_FILENO), ok); 324 E_NO_ERRNO(result, dup2(devnull, STDIN_FILENO), ok);
334 E_NO_ERRNO(result, close(devnull), ok); 325 E_NO_ERRNO(result, close(devnull), ok);
335 } 326 }
336 327
337 devnull = open("/dev/null", O_WRONLY); 328 devnull = open("/dev/null", O_WRONLY);
338 if (devnull >= 0) 329 if (devnull >= 0)
339 { 330 {
340 E_NO_ERRNO(result, close(STDOUT_FILENO), ok); 331 E_NO_ERRNO(result, close(STDOUT_FILENO), ok);
341 E_NO_ERRNO(result, dup2(devnull, STDOUT_FILENO), ok); 332 E_NO_ERRNO(result, dup2(devnull, STDOUT_FILENO), ok);
342 E_NO_ERRNO(result, close(devnull), ok); 333 E_NO_ERRNO(result, close(devnull), ok);
343 } 334 }
344 335
345 devnull = open("/dev/null", O_WRONLY); 336 devnull = open("/dev/null", O_WRONLY);
346 if (devnull >= 0) 337 if (devnull >= 0)
347 { 338 {
348 E_NO_ERRNO(result, close(STDERR_FILENO), ok); 339 E_NO_ERRNO(result, close(STDERR_FILENO), ok);
349 E_NO_ERRNO(result, dup2(devnull, STDERR_FILENO), ok); 340 E_NO_ERRNO(result, dup2(devnull, STDERR_FILENO), ok);
350 E_NO_ERRNO(result, close(devnull), ok); 341 E_NO_ERRNO(result, close(devnull), ok);
351 } 342 }
352 } 343 }
353 else 344 else
354 { 345 {
355 /* dup2 STDERR, STDIN, and STDOUT. dup2() allegedly closes the 346 /* dup2 STDERR, STDIN, and STDOUT. dup2() allegedly closes the
356 * second pipe if it's open. On the other hand, there was the 347 * second pipe if it's open. On the other hand, there was the
357 * Great FD Leak Scare of '06, so let's be paranoid. */ 348 * Great FD Leak Scare of '06, so let's be paranoid. */
358 if (ok && (flags & ECORE_EXE_PIPE_ERROR)) 349 if (ok && (flags & ECORE_EXE_PIPE_ERROR))
359 { 350 {
360 E_NO_ERRNO(result, close(STDERR_FILENO), ok); 351 E_NO_ERRNO(result, close(STDERR_FILENO), ok);
361 E_NO_ERRNO(result, dup2(errorPipe[1], STDERR_FILENO), ok); 352 E_NO_ERRNO(result, dup2(errorPipe[1], STDERR_FILENO), ok);
362 } 353 }
363 if (ok && (flags & ECORE_EXE_PIPE_READ)) 354 if (ok && (flags & ECORE_EXE_PIPE_READ))
364 { 355 {
365 E_NO_ERRNO(result, close(STDOUT_FILENO), ok); 356 E_NO_ERRNO(result, close(STDOUT_FILENO), ok);
366 E_NO_ERRNO(result, dup2(readPipe[1], STDOUT_FILENO), ok); 357 E_NO_ERRNO(result, dup2(readPipe[1], STDOUT_FILENO), ok);
367 } 358 }
368 if (ok && (flags & ECORE_EXE_PIPE_WRITE)) 359 if (ok && (flags & ECORE_EXE_PIPE_WRITE))
369 { 360 {
370 E_NO_ERRNO(result, close(STDIN_FILENO), ok); 361 E_NO_ERRNO(result, close(STDIN_FILENO), ok);
371 E_NO_ERRNO(result, dup2(writePipe[0], STDIN_FILENO), ok); 362 E_NO_ERRNO(result, dup2(writePipe[0], STDIN_FILENO), ok);
372 } 363 }
373 } 364 }
374
375 if (ok)
376 {
377 /* Setup the status pipe. */
378 E_NO_ERRNO(result, close(statusPipe[0]), ok);
379 E_IF_NO_ERRNO(result, eina_file_close_on_exec(statusPipe[1], EINA_TRUE), ok) /* close on exec shows success */
380 {
381 /* Run the actual command. */
382 _ecore_exe_exec_it(exe_cmd, flags); /* no return */
383 }
384 }
385
386 /* Something went 'orribly wrong. */
387 vfork_exec_errno = errno;
388
389 /* Close the pipes. */
390 if (flags & ECORE_EXE_PIPE_ERROR)
391 E_NO_ERRNO(result, close(errorPipe[1]), ok);
392 if (flags & ECORE_EXE_PIPE_READ)
393 E_NO_ERRNO(result, close(readPipe[1]), ok);
394 if (flags & ECORE_EXE_PIPE_WRITE)
395 E_NO_ERRNO(result, close(writePipe[0]), ok);
396 E_NO_ERRNO(result, close(statusPipe[1]), ok);
397
398 _exit(-1);
399 }
400 else /* parent */
401 {
402 /* Close the unused pipes. */
403 E_NO_ERRNO(result, close(statusPipe[1]), ok);
404
405 /* FIXME: after having a good look at the current e fd
406 * handling, investigate fcntl(dataPipe[x], F_SETSIG, ...) */
407 /* FIXME: above F_SETSIG etc. - this is async SIGIO based IO
408 * which is also linux specific so we probably don't want to
409 * do this as long as select() is working fine. the only time
410 * we really want to think of SIGIO async IO is when it all
411 * actually works basically everywhere and we can turn all
412 * IO into DMA async activities (i.e. you do a read() then
413 * the read is complete not on return but when you get a
414 * SIGIO - the read() just starts the transfer and it is
415 * completed in the background by DMA (or whatever mechanism
416 * the kernel choses)) */
417
418 /* Wait for it to start executing. */
419 /* FIXME: this doesn't seem very nice - we sit and block
420 * waiting on a child process... even though it's just
421 * the segment between the fork() and the exec) it just feels
422 * wrong */
423 for (;; )
424 {
425 char buf;
426
427 E_NO_ERRNO(result, read(statusPipe[0], &buf, 1), ok);
428 if (result == 0)
429 {
430 if (vfork_exec_errno != 0)
431 {
432 n = vfork_exec_errno;
433 ERR("Could not start \"%s\"", exe_cmd);
434 pid = 0;
435 }
436 break;
437 }
438 }
439 365
440 /* Close the status pipe. */ 366 if (ok)
367 {
368 /* Setup the status pipe. */
441 E_NO_ERRNO(result, close(statusPipe[0]), ok); 369 E_NO_ERRNO(result, close(statusPipe[0]), ok);
370 E_IF_NO_ERRNO(result, eina_file_close_on_exec(statusPipe[1], EINA_TRUE), ok) /* close on exec shows success */
371 {
372 /* Run the actual command. */
373 _ecore_exe_exec_it(exe_cmd, flags); /* no return */
374 }
375 }
376
377 /* Something went 'orribly wrong. */
378 vfork_exec_errno = errno;
379
380 /* Close the pipes. */
381 if (flags & ECORE_EXE_PIPE_ERROR)
382 E_NO_ERRNO(result, close(errorPipe[1]), ok);
383 if (flags & ECORE_EXE_PIPE_READ)
384 E_NO_ERRNO(result, close(readPipe[1]), ok);
385 if (flags & ECORE_EXE_PIPE_WRITE)
386 E_NO_ERRNO(result, close(writePipe[0]), ok);
387 E_NO_ERRNO(result, close(statusPipe[1]), ok);
388
389 _exit(-1);
390 }
391 else /* parent */
392 {
393 /* Close the unused pipes. */
394 E_NO_ERRNO(result, close(statusPipe[1]), ok);
395
396 /* FIXME: after having a good look at the current e fd
397 * handling, investigate fcntl(dataPipe[x], F_SETSIG, ...) */
398 /* FIXME: above F_SETSIG etc. - this is async SIGIO based IO
399 * which is also linux specific so we probably don't want to
400 * do this as long as select() is working fine. the only time
401 * we really want to think of SIGIO async IO is when it all
402 * actually works basically everywhere and we can turn all
403 * IO into DMA async activities (i.e. you do a read() then
404 * the read is complete not on return but when you get a
405 * SIGIO - the read() just starts the transfer and it is
406 * completed in the background by DMA (or whatever mechanism
407 * the kernel choses)) */
408
409 /* Wait for it to start executing. */
410 /* FIXME: this doesn't seem very nice - we sit and block
411 * waiting on a child process... even though it's just
412 * the segment between the fork() and the exec) it just feels
413 * wrong */
414 for (;; )
415 {
416 char buf;
417
418 E_NO_ERRNO(result, read(statusPipe[0], &buf, 1), ok);
419 if (result == 0)
420 {
421 if (vfork_exec_errno != 0)
422 {
423 n = vfork_exec_errno;
424 ERR("Could not start \"%s\"", exe_cmd);
425 pid = 0;
426 }
427 break;
428 }
442 } 429 }
443 430
444 if (pid) 431 /* Close the status pipe. */
432 E_NO_ERRNO(result, close(statusPipe[0]), ok);
433 }
434
435 if (pid)
436 {
437 /* Setup the exe structure. */
438 exe->start_bytes = -1;
439 exe->end_bytes = -1;
440 exe->start_lines = -1;
441 exe->end_lines = -1;
442 exe->pid = pid;
443 exe->flags = flags;
444 if (exe->cmd)
445 { 445 {
446 /* Setup the exe structure. */ 446 if (flags & ECORE_EXE_PIPE_ERROR) /* Setup the error stuff. */
447 exe->start_bytes = -1; 447 {
448 exe->end_bytes = -1; 448 E_IF_NO_ERRNO(result,
449 exe->start_lines = -1; 449 fcntl(exe->child_fd_error, F_SETFL,
450 exe->end_lines = -1; 450 O_NONBLOCK), ok) {
451 exe->pid = pid; 451 }
452 exe->flags = flags; 452 E_IF_NO_ERRNO(result,
453 if (exe->cmd) 453 eina_file_close_on_exec(exe->child_fd_error, EINA_TRUE),
454 { 454 ok) {
455 if (flags & ECORE_EXE_PIPE_ERROR) /* Setup the error stuff. */ 455 }
456 { 456 E_IF_NO_ERRNO(result,
457 E_IF_NO_ERRNO(result, 457 eina_file_close_on_exec(exe->child_fd_error_x, EINA_TRUE),
458 fcntl(exe->child_fd_error, F_SETFL, 458 ok) {
459 O_NONBLOCK), ok) { 459 }
460 } 460 {
461 E_IF_NO_ERRNO(result, 461 // XXX: eoify ecore fd handlers
462 eina_file_close_on_exec(exe->child_fd_error, EINA_TRUE), 462 exe->error_fd_handler =
463 ok) { 463 ecore_main_fd_handler_add(exe->child_fd_error,
464 } 464 ECORE_FD_READ,
465 E_IF_NO_ERRNO(result, 465 _ecore_exe_data_error_handler,
466 eina_file_close_on_exec(exe->child_fd_error_x, EINA_TRUE), 466 obj, NULL, NULL);
467 ok) { 467 if (!exe->error_fd_handler)
468 } 468 ok = 0;
469 { 469 }
470 exe->error_fd_handler = 470 }
471 ecore_main_fd_handler_add(exe->child_fd_error, 471 if (ok && (flags & ECORE_EXE_PIPE_READ)) /* Setup the read stuff. */
472 ECORE_FD_READ, 472 {
473 _ecore_exe_data_error_handler, 473 E_IF_NO_ERRNO(result,
474 obj, NULL, NULL); 474 fcntl(exe->child_fd_read, F_SETFL,
475 if (!exe->error_fd_handler) 475 O_NONBLOCK), ok) {
476 ok = 0; 476 }
477 } 477 E_IF_NO_ERRNO(result,
478 } 478 eina_file_close_on_exec(exe->child_fd_read, EINA_TRUE),
479 if (ok && (flags & ECORE_EXE_PIPE_READ)) /* Setup the read stuff. */ 479 ok) {
480 { 480 }
481 E_IF_NO_ERRNO(result, 481 E_IF_NO_ERRNO(result,
482 fcntl(exe->child_fd_read, F_SETFL, 482 eina_file_close_on_exec(exe->child_fd_read_x, EINA_TRUE),
483 O_NONBLOCK), ok) { 483 ok) {
484 } 484 }
485 E_IF_NO_ERRNO(result, 485 {
486 eina_file_close_on_exec(exe->child_fd_read, EINA_TRUE), 486 // XXX: eoify ecore fd handlers
487 ok) { 487 exe->read_fd_handler =
488 } 488 ecore_main_fd_handler_add(exe->child_fd_read,
489 E_IF_NO_ERRNO(result, 489 ECORE_FD_READ,
490 eina_file_close_on_exec(exe->child_fd_read_x, EINA_TRUE), 490 _ecore_exe_data_read_handler,
491 ok) { 491 obj, NULL, NULL);
492 } 492 if (!exe->read_fd_handler)
493 { 493 ok = 0;
494 exe->read_fd_handler = 494 }
495 ecore_main_fd_handler_add(exe->child_fd_read, 495 }
496 ECORE_FD_READ, 496 if (ok && (flags & ECORE_EXE_PIPE_WRITE)) /* Setup the write stuff. */
497 _ecore_exe_data_read_handler, 497 {
498 obj, NULL, NULL); 498 E_IF_NO_ERRNO(result,
499 if (!exe->read_fd_handler) 499 fcntl(exe->child_fd_write, F_SETFL,
500 ok = 0; 500 O_NONBLOCK), ok) {
501 } 501 }
502 } 502 E_IF_NO_ERRNO(result,
503 if (ok && (flags & ECORE_EXE_PIPE_WRITE)) /* Setup the write stuff. */ 503 eina_file_close_on_exec(exe->child_fd_write, EINA_TRUE),
504 { 504 ok) {
505 E_IF_NO_ERRNO(result, 505 }
506 fcntl(exe->child_fd_write, F_SETFL, 506 E_IF_NO_ERRNO(result,
507 O_NONBLOCK), ok) { 507 eina_file_close_on_exec(exe->child_fd_write_x, EINA_TRUE),
508 } 508 ok) {
509 E_IF_NO_ERRNO(result, 509 }
510 eina_file_close_on_exec(exe->child_fd_write, EINA_TRUE), 510 {
511 ok) { 511 // XXX: eoify ecore fd handlers
512 } 512 exe->write_fd_handler =
513 E_IF_NO_ERRNO(result, 513 ecore_main_fd_handler_add(exe->child_fd_write,
514 eina_file_close_on_exec(exe->child_fd_write_x, EINA_TRUE), 514 ECORE_FD_WRITE,
515 ok) { 515 _ecore_exe_data_write_handler,
516 } 516 obj, NULL, NULL);
517 { 517 // XXX: eoify ecore fd handlers
518 exe->write_fd_handler = 518 if (exe->write_fd_handler)
519 ecore_main_fd_handler_add(exe->child_fd_write, 519 ecore_main_fd_handler_active_set(exe->write_fd_handler, 0); /* Nothing to write to start with. */
520 ECORE_FD_WRITE, 520 else
521 _ecore_exe_data_write_handler, 521 ok = 0;
522 obj, NULL, NULL); 522 }
523 if (exe->write_fd_handler) 523 }
524 ecore_main_fd_handler_active_set(exe->write_fd_handler, 0); /* Nothing to write to start with. */ 524
525 else 525 exe->loop = efl_provider_find(obj, EFL_LOOP_CLASS);
526 ok = 0; 526 Efl_Loop_Data *loop = efl_data_scope_get(exe->loop, EFL_LOOP_CLASS);
527 } 527 if (loop) loop->exes = eina_list_append(loop->exes, obj);
528 } 528 n = 0;
529
530 _ecore_exe_exes = eina_list_append(_ecore_exe_exes, obj);
531 n = 0;
532 }
533 else
534 ok = 0;
535 } 529 }
536 else 530 else
537 ok = 0; 531 ok = 0;
538 } 532 }
533 else
534 ok = 0;
535 }
539 536
540 if (!ok) /* Something went wrong, so pull down everything. */ 537 if (!ok) /* Something went wrong, so pull down everything. */
541 { 538 {
542 if (exe->pid) ecore_exe_terminate(obj); 539 // XXX: eoify terminate method
543 obj = NULL; 540 if (exe->pid) ecore_exe_terminate(obj);
544 } 541 obj = NULL;
542 }
545 else 543 else
546 { 544 {
547 Ecore_Exe_Event_Add *e; 545 Ecore_Exe_Event_Add *e;
548 546
549 e = _ecore_exe_event_add_new(); 547 e = _ecore_exe_event_add_new();
550 if (e) 548 if (e)
551 { 549 {
552 e->exe = obj; 550 e->exe = obj;
553 /* Send the event. */ 551 // XXX: eoify ecore_event_add
554 ecore_event_add(ECORE_EXE_EVENT_ADD, e, 552 /* Send the event. */
555 _ecore_exe_event_add_free, NULL); 553 ecore_event_add(ECORE_EXE_EVENT_ADD, e,
556 } 554 _ecore_exe_event_add_free, NULL);
557 /* INF("Running as %d for %s.\n", exe->pid, exe->cmd); */ 555 }
558 } 556 /* INF("Running as %d for %s.\n", exe->pid, exe->cmd); */
557 }
559 558
560 errno = n; 559 errno = n;
561 return obj; 560 return obj;
562} 561}
563 562
564Eina_Bool 563Eina_Bool
565_impl_ecore_exe_send(Ecore_Exe *obj EINA_UNUSED, 564_impl_ecore_exe_send(Ecore_Exe *obj EINA_UNUSED,
566 Ecore_Exe_Data *exe, 565 Ecore_Exe_Data *exe,
567 const void *data, 566 const void *data,
568 int size) 567 int size)
569{ 568{
570 void *buf; 569 void *buf;
571 570
572 if (exe->child_fd_write == -1) 571 if (exe->child_fd_write == -1)
573 { 572 {
574 ERR("Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! " 573 ERR("Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! "
575 "Cannot send %d bytes from %p", exe, size, data); 574 "Cannot send %d bytes from %p", exe, size, data);
576 return EINA_FALSE; 575 return EINA_FALSE;
577 } 576 }
578 577
@@ -583,19 +582,20 @@ _impl_ecore_exe_send(Ecore_Exe *obj EINA_UNUSED,
583 memcpy((char *)exe->write_data_buf + exe->write_data_size, data, size); 582 memcpy((char *)exe->write_data_buf + exe->write_data_size, data, size);
584 exe->write_data_size += size; 583 exe->write_data_size += size;
585 584
585 // XXX: eoify ecore_fd_handlers
586 if (exe->write_fd_handler) 586 if (exe->write_fd_handler)
587 ecore_main_fd_handler_active_set(exe->write_fd_handler, ECORE_FD_WRITE); 587 ecore_main_fd_handler_active_set(exe->write_fd_handler, ECORE_FD_WRITE);
588 588
589 return EINA_TRUE; 589 return EINA_TRUE;
590} 590}
591 591
592void 592void
593_impl_ecore_exe_auto_limits_set(Ecore_Exe *obj EINA_UNUSED, 593_impl_ecore_exe_auto_limits_set(Ecore_Exe *obj EINA_UNUSED,
594 Ecore_Exe_Data *exe, 594 Ecore_Exe_Data *exe,
595 int start_bytes, 595 int start_bytes,
596 int end_bytes, 596 int end_bytes,
597 int start_lines, 597 int start_lines,
598 int end_lines) 598 int end_lines)
599{ 599{
600 /* FIXME: sanitize the input. */ 600 /* FIXME: sanitize the input. */
601 exe->start_bytes = start_bytes; 601 exe->start_bytes = start_bytes;
@@ -644,9 +644,9 @@ _impl_ecore_exe_auto_limits_set(Ecore_Exe *obj EINA_UNUSED,
644} 644}
645 645
646Ecore_Exe_Event_Data * 646Ecore_Exe_Event_Data *
647_impl_ecore_exe_event_data_get(Ecore_Exe *obj, 647_impl_ecore_exe_event_data_get(Ecore_Exe *obj,
648 Ecore_Exe_Data *exe, 648 Ecore_Exe_Data *exe,
649 Ecore_Exe_Flags flags) 649 Ecore_Exe_Flags flags)
650{ 650{
651 Ecore_Exe_Event_Data *e = NULL; 651 Ecore_Exe_Event_Data *e = NULL;
652 int is_buffered = 0; 652 int is_buffered = 0;
@@ -655,130 +655,130 @@ _impl_ecore_exe_event_data_get(Ecore_Exe *obj,
655 655
656 /* Sort out what sort of event we are. */ 656 /* Sort out what sort of event we are. */
657 if (flags & ECORE_EXE_PIPE_READ) 657 if (flags & ECORE_EXE_PIPE_READ)
658 { 658 {
659 flags = ECORE_EXE_PIPE_READ; 659 flags = ECORE_EXE_PIPE_READ;
660 if (exe->flags & ECORE_EXE_PIPE_READ_LINE_BUFFERED) 660 if (exe->flags & ECORE_EXE_PIPE_READ_LINE_BUFFERED)
661 is_buffered = 1; 661 is_buffered = 1;
662 } 662 }
663 else 663 else
664 { 664 {
665 flags = ECORE_EXE_PIPE_ERROR; 665 flags = ECORE_EXE_PIPE_ERROR;
666 if (exe->flags & ECORE_EXE_PIPE_ERROR_LINE_BUFFERED) 666 if (exe->flags & ECORE_EXE_PIPE_ERROR_LINE_BUFFERED)
667 is_buffered = 1; 667 is_buffered = 1;
668 } 668 }
669 669
670 /* Get the data. */ 670 /* Get the data. */
671 if (flags & ECORE_EXE_PIPE_READ) 671 if (flags & ECORE_EXE_PIPE_READ)
672 { 672 {
673 inbuf = exe->read_data_buf; 673 inbuf = exe->read_data_buf;
674 inbuf_num = exe->read_data_size; 674 inbuf_num = exe->read_data_size;
675 exe->read_data_buf = NULL; 675 exe->read_data_buf = NULL;
676 exe->read_data_size = 0; 676 exe->read_data_size = 0;
677 } 677 }
678 else 678 else
679 { 679 {
680 inbuf = exe->error_data_buf; 680 inbuf = exe->error_data_buf;
681 inbuf_num = exe->error_data_size; 681 inbuf_num = exe->error_data_size;
682 exe->error_data_buf = NULL; 682 exe->error_data_buf = NULL;
683 exe->error_data_size = 0; 683 exe->error_data_size = 0;
684 } 684 }
685 685
686 e = calloc(1, sizeof(Ecore_Exe_Event_Data)); 686 e = calloc(1, sizeof(Ecore_Exe_Event_Data));
687 if (e) 687 if (e)
688 { 688 {
689 e->exe = obj; 689 e->exe = obj;
690 e->data = inbuf; 690 e->data = inbuf;
691 e->size = inbuf_num; 691 e->size = inbuf_num;
692 692
693 if (is_buffered) /* Deal with line buffering. */ 693 if (is_buffered) /* Deal with line buffering. */
694 { 694 {
695 int max = 0; 695 int max = 0;
696 int count = 0; 696 int count = 0;
697 int i; 697 int i;
698 int last = 0; 698 int last = 0;
699 char *c; 699 char *c;
700 700
701 c = (char *)inbuf; 701 c = (char *)inbuf;
702 for (i = 0; i < inbuf_num; i++) /* Find the lines. */ 702 for (i = 0; i < inbuf_num; i++) /* Find the lines. */
703 { 703 {
704 if (inbuf[i] == '\n') 704 if (inbuf[i] == '\n')
705 { 705 {
706 if (count >= max) 706 if (count >= max)
707 {
708 Ecore_Exe_Event_Data_Line *lines;
709
710 /* In testing, the lines seem to arrive in batches of 500 to 1000 lines at most, roughly speaking. */
711 max += 10; /* FIXME: Maybe keep track of the largest number of lines ever sent, and add half that many instead of 10. */
712 lines = realloc(e->lines, sizeof(Ecore_Exe_Event_Data_Line) * (max + 1)); /* Allow room for the NULL termination. */
713 if (!lines)
714 {
715 ERR("Out of memory adding exe data lines to event");
716 break;
717 }
718 e->lines = lines;
719 }
720 /* raster said to leave the line endings as line endings, however -
721 * This is line buffered mode, we are not dealing with binary here, but lines.
722 * If we are not dealing with binary, we must be dealing with ASCII, unicode, or some other text format.
723 * Thus the user is most likely gonna deal with this text as strings.
724 * Thus the user is most likely gonna pass this data to str functions.
725 * rasters way - the endings are always gonna be '\n'; onefangs way - they will always be '\0'
726 * We are handing them the string length as a convenience.
727 * Thus if they really want it in raw format, they can e->lines[i].line[e->lines[i].size - 1] = '\n'; easily enough.
728 * In the default case, we can do this conversion quicker than the user can, as we already have the index and pointer.
729 * Let's make it easy on them to use these as standard C strings.
730 *
731 * onefang is proud to announce that he has just set a new personal record for the
732 * most over documentation of a simple assignment statement. B-)
733 */
734 inbuf[i] = '\0';
735 e->lines[count].line = c;
736 e->lines[count].size = i - last;
737 last = i + 1;
738 c = (char *)&inbuf[last];
739 count++;
740 }
741 }
742 if (i > last) /* Partial line left over, save it for next time. */
743 {
744 if (count != 0) e->size = last;
745 if (flags & ECORE_EXE_PIPE_READ)
746 {
747 exe->read_data_size = i - last;
748 exe->read_data_buf = malloc(exe->read_data_size);
749 if (exe->read_data_buf)
750 memcpy(exe->read_data_buf, c, exe->read_data_size);
751 else
752 {
753 exe->read_data_size = 0;
754 ERR("Out of memory in allocating exe pipe data");
755 }
756 }
757 else
758 {
759 exe->error_data_size = i - last;
760 exe->error_data_buf = malloc(exe->error_data_size);
761 if (exe->error_data_buf)
762 memcpy(exe->error_data_buf, c, exe->error_data_size);
763 else
764 {
765 exe->error_data_size = 0;
766 ERR("Out of memory in allocating exe pipe data");
767 }
768 }
769 }
770 if (count == 0) /* No lines to send, cancel the event. */
771 {
772 _ecore_exe_event_exe_data_free(NULL, e);
773 e = NULL;
774 }
775 else /* NULL terminate the array, so that people know where the end is. */
776 { 707 {
777 e->lines[count].line = NULL; 708 Ecore_Exe_Event_Data_Line *lines;
778 e->lines[count].size = 0; 709
710 /* In testing, the lines seem to arrive in batches of 500 to 1000 lines at most, roughly speaking. */
711 max += 10; /* FIXME: Maybe keep track of the largest number of lines ever sent, and add half that many instead of 10. */
712 lines = realloc(e->lines, sizeof(Ecore_Exe_Event_Data_Line) * (max + 1)); /* Allow room for the NULL termination. */
713 if (!lines)
714 {
715 ERR("Out of memory adding exe data lines to event");
716 break;
717 }
718 e->lines = lines;
779 } 719 }
780 } 720 /* raster said to leave the line endings as line endings, however -
781 } 721 * This is line buffered mode, we are not dealing with binary here, but lines.
722 * If we are not dealing with binary, we must be dealing with ASCII, unicode, or some other text format.
723 * Thus the user is most likely gonna deal with this text as strings.
724 * Thus the user is most likely gonna pass this data to str functions.
725 * rasters way - the endings are always gonna be '\n'; onefangs way - they will always be '\0'
726 * We are handing them the string length as a convenience.
727 * Thus if they really want it in raw format, they can e->lines[i].line[e->lines[i].size - 1] = '\n'; easily enough.
728 * In the default case, we can do this conversion quicker than the user can, as we already have the index and pointer.
729 * Let's make it easy on them to use these as standard C strings.
730 *
731 * onefang is proud to announce that he has just set a new personal record for the
732 * most over documentation of a simple assignment statement. B-)
733 */
734 inbuf[i] = '\0';
735 e->lines[count].line = c;
736 e->lines[count].size = i - last;
737 last = i + 1;
738 c = (char *)&inbuf[last];
739 count++;
740 }
741 }
742 if (i > last) /* Partial line left over, save it for next time. */
743 {
744 if (count != 0) e->size = last;
745 if (flags & ECORE_EXE_PIPE_READ)
746 {
747 exe->read_data_size = i - last;
748 exe->read_data_buf = malloc(exe->read_data_size);
749 if (exe->read_data_buf)
750 memcpy(exe->read_data_buf, c, exe->read_data_size);
751 else
752 {
753 exe->read_data_size = 0;
754 ERR("Out of memory in allocating exe pipe data");
755 }
756 }
757 else
758 {
759 exe->error_data_size = i - last;
760 exe->error_data_buf = malloc(exe->error_data_size);
761 if (exe->error_data_buf)
762 memcpy(exe->error_data_buf, c, exe->error_data_size);
763 else
764 {
765 exe->error_data_size = 0;
766 ERR("Out of memory in allocating exe pipe data");
767 }
768 }
769 }
770 if (count == 0) /* No lines to send, cancel the event. */
771 {
772 _ecore_exe_event_exe_data_free(NULL, e);
773 e = NULL;
774 }
775 else /* NULL terminate the array, so that people know where the end is. */
776 {
777 e->lines[count].line = NULL;
778 e->lines[count].size = 0;
779 }
780 }
781 }
782 782
783 return e; 783 return e;
784} 784}
@@ -795,20 +795,9 @@ _impl_ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe)
795 if (exe->pre_free_cb) 795 if (exe->pre_free_cb)
796 exe->pre_free_cb(data, obj); 796 exe->pre_free_cb(data, obj);
797 797
798 if (exe->doomsday_clock) 798 exe->doomsday_clock = NULL;
799 {
800 struct _ecore_exe_dead_exe *dead;
801 799
802 ecore_timer_del(exe->doomsday_clock); 800 // XXX: eoify ecore fd handlers
803 exe->doomsday_clock = NULL;
804 dead = exe->doomsday_clock_dead;
805 if (dead)
806 {
807 IF_FREE(dead->cmd);
808 free(dead);
809 exe->doomsday_clock_dead = NULL;
810 }
811 }
812 IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler); 801 IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler);
813 IF_FN_DEL(ecore_main_fd_handler_del, exe->read_fd_handler); 802 IF_FN_DEL(ecore_main_fd_handler_del, exe->read_fd_handler);
814 IF_FN_DEL(ecore_main_fd_handler_del, exe->error_fd_handler); 803 IF_FN_DEL(ecore_main_fd_handler_del, exe->error_fd_handler);
@@ -829,7 +818,8 @@ _impl_ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe)
829 IF_FREE(exe->error_data_buf); 818 IF_FREE(exe->error_data_buf);
830 IF_FREE(exe->cmd); 819 IF_FREE(exe->cmd);
831 820
832 _ecore_exe_exes = eina_list_remove(_ecore_exe_exes, obj); 821 Efl_Loop_Data *loop = efl_data_scope_get(exe->loop, EFL_LOOP_CLASS);
822 if (loop) loop->exes = eina_list_remove(loop->exes, obj);
833 IF_FREE(exe->tag); 823 IF_FREE(exe->tag);
834} 824}
835 825
@@ -870,25 +860,21 @@ _impl_ecore_exe_terminate(Ecore_Exe *obj, Ecore_Exe_Data *exe)
870void 860void
871_impl_ecore_exe_kill(Ecore_Exe *obj EINA_UNUSED, Ecore_Exe_Data *exe) 861_impl_ecore_exe_kill(Ecore_Exe *obj EINA_UNUSED, Ecore_Exe_Data *exe)
872{ 862{
873 struct _ecore_exe_dead_exe *dead; 863 efl_del(exe->doomsday_clock);
874 dead = calloc(1, sizeof(struct _ecore_exe_dead_exe)); 864 exe->doomsday_clock = efl_add(EFL_LOOP_TIMER_CLASS, obj,
875 if (dead) 865 efl_event_callback_add(efl_added,
876 { 866 EFL_LOOP_TIMER_EVENT_TICK,
877 dead->pid = exe->pid; 867 _ecore_exe_make_sure_its_really_dead,
878 dead->cmd = strdup(exe->cmd); 868 obj),
879 IF_FN_DEL(ecore_timer_del, exe->doomsday_clock); 869 efl_loop_timer_interval_set(efl_added, 10.0));
880 exe->doomsday_clock =
881 ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead, dead);
882 }
883
884 INF("Sending KILL signal to %s (%d).", exe->cmd, exe->pid); 870 INF("Sending KILL signal to %s (%d).", exe->cmd, exe->pid);
885 kill(exe->pid, SIGKILL); 871 kill(exe->pid, SIGKILL);
886} 872}
887 873
888void 874void
889_impl_ecore_exe_signal(Ecore_Exe *obj EINA_UNUSED, 875_impl_ecore_exe_signal(Ecore_Exe *obj EINA_UNUSED,
890 Ecore_Exe_Data *exe, 876 Ecore_Exe_Data *exe,
891 int num) 877 int num)
892{ 878{
893 if (num == 1) 879 if (num == 1)
894 kill(exe->pid, SIGUSR1); 880 kill(exe->pid, SIGUSR1);
@@ -902,102 +888,41 @@ _impl_ecore_exe_hup(Ecore_Exe *obj EINA_UNUSED, Ecore_Exe_Data *exe)
902 kill(exe->pid, SIGHUP); 888 kill(exe->pid, SIGHUP);
903} 889}
904 890
905static Ecore_Exe * 891static void
906_ecore_exe_is_it_alive(pid_t pid) 892_ecore_exe_make_sure_its_dead(void *data, const Efl_Event *event EINA_UNUSED)
907{
908 Ecore_Exe *exe = NULL;
909
910 /* FIXME: There is no nice, safe, OS independent way to tell if a
911 * particular PID is still alive. I have written code to do so
912 * for my urunlevel busybox applet (http://urunlevel.sourceforge.net/),
913 * but it's for linux only, and still not guaranteed.
914 *
915 * So for now, we just check that a valid Ecore_Exe structure
916 * exists for it. Even that is not a guarantee, as the structure
917 * can be freed without killing the process.
918 *
919 * I think we can safely put exe's into two categories, those users
920 * that care about the life of the exe, and the run and forget type.
921 * The run and forget type starts up the exe, then free's the
922 * Ecore_Exe structure straight away. They can never call any of
923 * the functions that can call this, so we don't worry about them.
924 *
925 * Those user's that care about the life of exe's will keep the
926 * Ecore_Exe structure around, terminate them eventually, or
927 * register for exit events. For these ones the assumption
928 * that valid Ecore_Exe struct == live exe is almost valid.
929 *
930 * I will probably copy my urunlevel code into here someday.
931 */
932 exe = _ecore_exe_find(pid);
933
934 return exe;
935}
936
937static Eina_Bool
938_ecore_exe_make_sure_its_dead(void *data)
939{ 893{
940 struct _ecore_exe_dead_exe *dead; 894 Eo *exe_obj = data;
941 895 Ecore_Exe_Data *exe = efl_data_scope_get(exe_obj, MY_CLASS);
942 dead = data; 896 if (exe)
943 if (dead)
944 { 897 {
945 Ecore_Exe *obj = NULL; 898 if (exe->cmd)
946 899 INF("Sending KILL signal to allegedly dead %s (%d).", exe->cmd, exe->pid);
947 if ((obj = _ecore_exe_is_it_alive(dead->pid)))
948 {
949 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
950 if (exe)
951 {
952 if (dead->cmd)
953 INF("Sending KILL signal to allegedly dead %s (%d).",
954 dead->cmd, dead->pid);
955 else
956 INF("Sending KILL signal to allegedly dead PID %d.",
957 dead->pid);
958 exe->doomsday_clock =
959 ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead,
960 dead);
961 kill(dead->pid, SIGKILL);
962 }
963 }
964 else 900 else
965 { 901 INF("Sending KILL signal to allegedly dead PID %d.", exe->pid);
966 IF_FREE(dead->cmd); 902 exe->doomsday_clock = efl_add(EFL_LOOP_TIMER_CLASS, exe_obj,
967 free(dead); 903 efl_event_callback_add(efl_added,
968 } 904 EFL_LOOP_TIMER_EVENT_TICK,
905 _ecore_exe_make_sure_its_really_dead,
906 exe_obj),
907 efl_loop_timer_interval_set(efl_added, 10.0));
908 kill(exe->pid, SIGKILL);
969 } 909 }
970 return ECORE_CALLBACK_CANCEL;
971} 910}
972 911
973static Eina_Bool 912static void
974_ecore_exe_make_sure_its_really_dead(void *data) 913_ecore_exe_make_sure_its_really_dead(void *data, const Efl_Event *event EINA_UNUSED)
975{ 914{
976 struct _ecore_exe_dead_exe *dead; 915 Eo *exe_obj = data;
977 916 Ecore_Exe_Data *exe = efl_data_scope_get(exe_obj, MY_CLASS);
978 dead = data; 917 if (exe)
979 if (dead)
980 { 918 {
981 Ecore_Exe *obj = NULL; 919 ERR("RUN! The zombie wants to eat your brains! And your CPU!");
982 920 if (exe->cmd)
983 if ((obj = _ecore_exe_is_it_alive(dead->pid))) 921 INF("%s (%d) is not really dead.", exe->cmd, exe->pid);
984 { 922 else
985 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 923 INF("PID %d is not really dead.", exe->pid);
986 924 exe->doomsday_clock = NULL;
987 if (exe)
988 {
989 ERR("RUN! The zombie wants to eat your brains! And your CPU!");
990 if (dead->cmd)
991 INF("%s (%d) is not really dead.", dead->cmd, dead->pid);
992 else
993 INF("PID %d is not really dead.", dead->pid);
994 exe->doomsday_clock = NULL;
995 }
996 IF_FREE(dead->cmd);
997 free(dead);
998 }
999 } 925 }
1000 return ECORE_CALLBACK_CANCEL;
1001} 926}
1002 927
1003Ecore_Timer * 928Ecore_Timer *
@@ -1009,7 +934,7 @@ _ecore_exe_doomsday_clock_get(Ecore_Exe *obj)
1009} 934}
1010 935
1011void 936void
1012_ecore_exe_doomsday_clock_set(Ecore_Exe *obj, 937_ecore_exe_doomsday_clock_set(Ecore_Exe *obj,
1013 Ecore_Timer *dc) 938 Ecore_Timer *dc)
1014{ 939{
1015 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS); 940 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
@@ -1018,7 +943,7 @@ _ecore_exe_doomsday_clock_set(Ecore_Exe *obj,
1018} 943}
1019 944
1020static inline void 945static inline void
1021_ecore_exe_exec_it(const char *exe_cmd, 946_ecore_exe_exec_it(const char *exe_cmd,
1022 Ecore_Exe_Flags flags) 947 Ecore_Exe_Flags flags)
1023{ 948{
1024 char use_sh = 1; 949 char use_sh = 1;
@@ -1033,55 +958,55 @@ _ecore_exe_exec_it(const char *exe_cmd,
1033 * If we don't find them, we can call the exe directly. 958 * If we don't find them, we can call the exe directly.
1034 */ 959 */
1035 if (!strpbrk(exe_cmd, "|&;<>()$`\\\"'*?#")) 960 if (!strpbrk(exe_cmd, "|&;<>()$`\\\"'*?#"))
1036 { 961 {
1037 char *token; 962 char *token;
1038 char pre_command = 1; 963 char pre_command = 1;
1039 int num_tokens = 0; 964 int num_tokens = 0;
1040 int len; 965 int len;
1041 966
1042 len = strlen(exe_cmd); 967 len = strlen(exe_cmd);
1043 buf = alloca(len + 1); 968 buf = alloca(len + 1);
1044 strcpy(buf, exe_cmd); 969 strcpy(buf, exe_cmd);
1045 buf[len] = 0; 970 buf[len] = 0;
1046 971
1047 token = strtok(buf, " \t\n\v"); 972 token = strtok(buf, " \t\n\v");
1048 while (token) 973 while (token)
1049 { 974 {
1050 if (token[0] == '~') 975 if (token[0] == '~')
1051 break; 976 break;
1052 if (pre_command) 977 if (pre_command)
1053 { 978 {
1054 if (token[0] == '[') 979 if (token[0] == '[')
1055 break; 980 break;
1056 if (strchr(token, '=')) 981 if (strchr(token, '='))
1057 break; 982 break;
1058 else 983 else
1059 pre_command = 0; 984 pre_command = 0;
1060 } 985 }
1061 num_tokens++; 986 num_tokens++;
1062 token = strtok(NULL, " \t\n\v"); 987 token = strtok(NULL, " \t\n\v");
1063 } 988 }
1064 if ((!token) && (num_tokens)) 989 if ((!token) && (num_tokens))
1065 { 990 {
1066 int i = 0; 991 int i = 0;
1067 992
1068 len = strlen(exe_cmd); 993 len = strlen(exe_cmd);
1069 buf = alloca(len + 1); 994 buf = alloca(len + 1);
1070 strcpy(buf, exe_cmd); 995 strcpy(buf, exe_cmd);
1071 buf[len] = 0; 996 buf[len] = 0;
1072 997
1073 token = strtok(buf, " \t\n\v"); 998 token = strtok(buf, " \t\n\v");
1074 use_sh = 0; 999 use_sh = 0;
1075 args = alloca((num_tokens + 1) * sizeof(char *)); 1000 args = alloca((num_tokens + 1) * sizeof(char *));
1076 for (i = 0; i < num_tokens; i++) 1001 for (i = 0; i < num_tokens; i++)
1077 { 1002 {
1078 if (token) 1003 if (token)
1079 args[i] = token; 1004 args[i] = token;
1080 token = strtok(NULL, " \t\n\v"); 1005 token = strtok(NULL, " \t\n\v");
1081 } 1006 }
1082 args[num_tokens] = NULL; 1007 args[num_tokens] = NULL;
1083 } 1008 }
1084 } 1009 }
1085 1010
1086#ifdef HAVE_PRCTL 1011#ifdef HAVE_PRCTL
1087 if ((flags & ECORE_EXE_TERM_WITH_PARENT)) 1012 if ((flags & ECORE_EXE_TERM_WITH_PARENT))
@@ -1092,34 +1017,34 @@ _ecore_exe_exec_it(const char *exe_cmd,
1092 1017
1093 if (!(flags & ECORE_EXE_NOT_LEADER)) setsid(); 1018 if (!(flags & ECORE_EXE_NOT_LEADER)) setsid();
1094 if ((flags & ECORE_EXE_USE_SH)) 1019 if ((flags & ECORE_EXE_USE_SH))
1095 { 1020 {
1096 errno = 0; 1021 errno = 0;
1097 execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *)NULL); 1022 execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *)NULL);
1098 } 1023 }
1099 else if (use_sh) /* We have to use a shell to run this. */ 1024 else if (use_sh) /* We have to use a shell to run this. */
1100 { 1025 {
1101 if (!shell) /* Find users preferred shell. */ 1026 if (!shell) /* Find users preferred shell. */
1102 { 1027 {
1103#if defined(HAVE_GETUID) && defined(HAVE_GETEUID) 1028#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
1104 if (getuid() == geteuid()) 1029 if (getuid() == geteuid())
1105#endif 1030#endif
1106 shell = getenv("SHELL"); 1031 shell = getenv("SHELL");
1107 if (!shell) 1032 if (!shell)
1108 shell = "/bin/sh"; 1033 shell = "/bin/sh";
1109 } 1034 }
1110 errno = 0; 1035 errno = 0;
1111 execl(shell, shell, "-c", exe_cmd, (char *)NULL); 1036 execl(shell, shell, "-c", exe_cmd, (char *)NULL);
1112 } 1037 }
1113 else /* We can run this directly. */ 1038 else
1114 { 1039 { /* We can run this directly. */
1115 if (!args) 1040 if (!args)
1116 { 1041 {
1117 ERR("arg[0] is NULL!"); 1042 ERR("arg[0] is NULL!");
1118 return; 1043 return;
1119 } 1044 }
1120 errno = 0; 1045 errno = 0;
1121 if (args[0]) execvp(args[0], args); 1046 if (args[0]) execvp(args[0], args);
1122 } 1047 }
1123 1048
1124 save_errno = errno; 1049 save_errno = errno;
1125 errno = save_errno; 1050 errno = save_errno;
@@ -1127,9 +1052,9 @@ _ecore_exe_exec_it(const char *exe_cmd,
1127} 1052}
1128 1053
1129static Eina_Bool 1054static Eina_Bool
1130_ecore_exe_data_generic_handler(void *data, 1055_ecore_exe_data_generic_handler(void *data,
1131 Ecore_Fd_Handler *fd_handler, 1056 Ecore_Fd_Handler *fd_handler,
1132 Ecore_Exe_Flags flags) 1057 Ecore_Exe_Flags flags)
1133{ 1058{
1134 Ecore_Exe *obj = data; 1059 Ecore_Exe *obj = data;
1135 int child_fd; 1060 int child_fd;
@@ -1141,139 +1066,142 @@ _ecore_exe_data_generic_handler(void *data,
1141 1066
1142 /* Sort out what sort of handler we are. */ 1067 /* Sort out what sort of handler we are. */
1143 if (flags & ECORE_EXE_PIPE_READ) 1068 if (flags & ECORE_EXE_PIPE_READ)
1144 { 1069 {
1145 flags = ECORE_EXE_PIPE_READ; 1070 flags = ECORE_EXE_PIPE_READ;
1146 event_type = ECORE_EXE_EVENT_DATA; 1071 event_type = ECORE_EXE_EVENT_DATA;
1147 eo_event = ECORE_EXE_EVENT_DATA_GET; 1072 eo_event = ECORE_EXE_EVENT_DATA_GET;
1148 child_fd = exe->child_fd_read; 1073 child_fd = exe->child_fd_read;
1149 } 1074 }
1150 else 1075 else
1151 { 1076 {
1152 flags = ECORE_EXE_PIPE_ERROR; 1077 flags = ECORE_EXE_PIPE_ERROR;
1153 event_type = ECORE_EXE_EVENT_ERROR; 1078 event_type = ECORE_EXE_EVENT_ERROR;
1154 eo_event = ECORE_EXE_EVENT_DATA_ERROR; 1079 eo_event = ECORE_EXE_EVENT_DATA_ERROR;
1155 child_fd = exe->child_fd_error; 1080 child_fd = exe->child_fd_error;
1156 } 1081 }
1157 1082
1158 if ((fd_handler) 1083 if ((fd_handler)
1159 && (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))) 1084 && (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)))
1160 { 1085 {
1161 unsigned char *inbuf, *temp; 1086 unsigned char *inbuf, *temp;
1162 int inbuf_num; 1087 int inbuf_num;
1163 1088
1164 /* Get any left over data from last time. */ 1089 /* Get any left over data from last time. */
1165 if (flags & ECORE_EXE_PIPE_READ) 1090 if (flags & ECORE_EXE_PIPE_READ)
1166 { 1091 {
1167 inbuf = exe->read_data_buf; 1092 inbuf = exe->read_data_buf;
1168 inbuf_num = exe->read_data_size; 1093 inbuf_num = exe->read_data_size;
1169 exe->read_data_buf = NULL; 1094 exe->read_data_buf = NULL;
1170 exe->read_data_size = 0; 1095 exe->read_data_size = 0;
1171 } 1096 }
1172 else 1097 else
1173 { 1098 {
1174 inbuf = exe->error_data_buf; 1099 inbuf = exe->error_data_buf;
1175 inbuf_num = exe->error_data_size; 1100 inbuf_num = exe->error_data_size;
1176 exe->error_data_buf = NULL; 1101 exe->error_data_buf = NULL;
1177 exe->error_data_size = 0; 1102 exe->error_data_size = 0;
1178 } 1103 }
1179 1104
1180 for (;; ) 1105 for (;; )
1181 { 1106 {
1182 int num, lost_exe; 1107 int num, lost_exe;
1183 char buf[READBUFSIZ]; 1108 char buf[READBUFSIZ];
1184 1109
1185 lost_exe = 0; 1110 lost_exe = 0;
1186 errno = 0; 1111 errno = 0;
1187 if ((num = read(child_fd, buf, READBUFSIZ)) < 1) 1112 if ((num = read(child_fd, buf, READBUFSIZ)) < 1)
1113 {
1114 /* FIXME: SPEED/SIZE TRADE OFF - add a smaller READBUFSIZE
1115 * (currently 64k) to inbuf, use that instead of buf, and
1116 * save ourselves a memcpy(). */
1117 lost_exe = ((errno == EIO) ||
1118 (errno == EBADF) ||
1119 (errno == EPIPE) ||
1120 (errno == EINVAL) || (errno == ENOSPC));
1121 if ((errno != EAGAIN) && (errno != EINTR))
1122 perror("_ecore_exe_generic_handler() read problem ");
1123 }
1124 if (num > 0) /* data got read. */
1125 {
1126 temp = inbuf;
1127 inbuf = realloc(inbuf, inbuf_num + num);
1128 if (inbuf)
1129 {
1130 memcpy(inbuf + inbuf_num, buf, num);
1131 inbuf_num += num;
1132 }
1133 else // realloc fails and returns NULL.
1134 {
1135 ERR("Out of memory in exe generic data handler");
1136 inbuf = temp;
1137 }
1138 }
1139 else
1140 { /* No more data to read. */
1141 if (inbuf)
1142 {
1143 Ecore_Exe_Event_Data *e;
1144
1145 /* Stash the data away for later. */
1146 if (flags & ECORE_EXE_PIPE_READ)
1188 { 1147 {
1189 /* FIXME: SPEED/SIZE TRADE OFF - add a smaller READBUFSIZE 1148 exe->read_data_buf = inbuf;
1190 * (currently 64k) to inbuf, use that instead of buf, and 1149 exe->read_data_size = inbuf_num;
1191 * save ourselves a memcpy(). */
1192 lost_exe = ((errno == EIO) ||
1193 (errno == EBADF) ||
1194 (errno == EPIPE) ||
1195 (errno == EINVAL) || (errno == ENOSPC));
1196 if ((errno != EAGAIN) && (errno != EINTR))
1197 perror("_ecore_exe_generic_handler() read problem ");
1198 } 1150 }
1199 if (num > 0) /* data got read. */ 1151 else
1200 { 1152 {
1201 temp = inbuf; 1153 exe->error_data_buf = inbuf;
1202 inbuf = realloc(inbuf, inbuf_num + num); 1154 exe->error_data_size = inbuf_num;
1203 if (inbuf)
1204 {
1205 memcpy(inbuf + inbuf_num, buf, num);
1206 inbuf_num += num;
1207 }
1208 else // realloc fails and returns NULL.
1209 {
1210 ERR("Out of memory in exe generic data handler");
1211 inbuf = temp;
1212 }
1213 } 1155 }
1214 else /* No more data to read. */ 1156
1157 if (!(exe->flags & ECORE_EXE_PIPE_AUTO))
1215 { 1158 {
1216 if (inbuf) 1159 // XXX: use eo method
1217 { 1160 e = ecore_exe_event_data_get(obj, flags);
1218 Ecore_Exe_Event_Data *e; 1161 if (e) /* Send the event. */
1219
1220 /* Stash the data away for later. */
1221 if (flags & ECORE_EXE_PIPE_READ)
1222 {
1223 exe->read_data_buf = inbuf;
1224 exe->read_data_size = inbuf_num;
1225 }
1226 else
1227 {
1228 exe->error_data_buf = inbuf;
1229 exe->error_data_size = inbuf_num;
1230 }
1231
1232 if (!(exe->flags & ECORE_EXE_PIPE_AUTO))
1233 {
1234 e = ecore_exe_event_data_get(obj, flags);
1235 if (e) /* Send the event. */
1236 {
1237 ecore_event_add(event_type, e,
1238 _ecore_exe_event_exe_data_free,
1239 NULL);
1240 efl_event_callback_call(obj, eo_event, e);
1241 }
1242 }
1243 }
1244 if (lost_exe)
1245 { 1162 {
1246 if (flags & ECORE_EXE_PIPE_READ) 1163 // XXX: eoify ecore event
1247 { 1164 ecore_event_add(event_type, e,
1248 if (exe->read_data_size) 1165 _ecore_exe_event_exe_data_free,
1249 INF("There are %d bytes left unsent from the dead exe %s.", 1166 NULL);
1250 exe->read_data_size, exe->cmd); 1167 efl_event_callback_call(obj, eo_event, e);
1251 }
1252 else
1253 {
1254 if (exe->error_data_size)
1255 INF("There are %d bytes left unsent from the dead exe %s.",
1256 exe->error_data_size, exe->cmd);
1257 }
1258 /* Thought about this a bit. If the exe has actually
1259 * died, this won't do any harm as it must have died
1260 * recently and the pid has not had a chance to recycle.
1261 * It is also a paranoid catchall, coz the usual ecore_signal
1262 * mechanism should kick in. But let's give it a good
1263 * kick in the head anyway.
1264 */
1265 ecore_exe_terminate(obj);
1266 } 1168 }
1267 break;
1268 } 1169 }
1269 } 1170 }
1270 } 1171 if (lost_exe)
1172 {
1173 if (flags & ECORE_EXE_PIPE_READ)
1174 {
1175 if (exe->read_data_size)
1176 INF("There are %d bytes left unsent from the dead exe %s.",
1177 exe->read_data_size, exe->cmd);
1178 }
1179 else
1180