1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8
9 #include <Efl.h>
10
11 #include "Ecore.h"
12 #include "ecore_private.h"
13
14 #define MY_CLASS ECORE_EXE_CLASS
15
16 #include "ecore_exe_private.h"
17
18 /* TODO: Something to let people build a command line and does auto escaping -
19 *
20 * ecore_exe_snprintf()
21 *
22 * OR
23 *
24 * cmd = ecore_exe_comand_parameter_append(cmd, "firefox");
25 * cmd = ecore_exe_comand_parameter_append(cmd, "http://www.foo.com/bar.html?baz=yes");
26 * each parameter appended is one argument, and it gets escaped, quoted, and
27 * appended with a preceding space. The first is the command off course.
28 */
29
30 struct _ecore_exe_dead_exe
31 {
32 pid_t pid;
33 char *cmd;
34 };
35
36 EAPI int ECORE_EXE_EVENT_ADD = 0;
37 EAPI int ECORE_EXE_EVENT_DEL = 0;
38 EAPI int ECORE_EXE_EVENT_DATA = 0;
39 EAPI int ECORE_EXE_EVENT_ERROR = 0;
40
41 EAPI void
ecore_exe_run_priority_set(int pri)42 ecore_exe_run_priority_set(int pri)
43 {
44 EINA_MAIN_LOOP_CHECK_RETURN;
45 _impl_ecore_exe_run_priority_set(pri);
46 }
47
48 EAPI int
ecore_exe_run_priority_get(void)49 ecore_exe_run_priority_get(void)
50 {
51 EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
52 return _impl_ecore_exe_run_priority_get();
53 }
54
55 EAPI Ecore_Exe *
ecore_exe_run(const char * exe_cmd,const void * data)56 ecore_exe_run(const char *exe_cmd,
57 const void *data)
58 {
59 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
60 return ecore_exe_pipe_run(exe_cmd, 0, data);
61 }
62
63 EAPI Ecore_Exe *
ecore_exe_pipe_run(const char * exe_cmd,Ecore_Exe_Flags flags,const void * data)64 ecore_exe_pipe_run(const char *exe_cmd,
65 Ecore_Exe_Flags flags,
66 const void *data)
67 {
68 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
69 Ecore_Exe *ret = efl_add(MY_CLASS, efl_main_loop_get(),
70 ecore_obj_exe_command_set(efl_added, exe_cmd,
71 flags));
72 if (ret)
73 {
74 Ecore_Exe_Data *pd = efl_data_scope_get(ret, MY_CLASS);
75 pd->data = (void *) data;
76 }
77 return ret;
78 }
79
80 EOLIAN static void
_ecore_exe_command_set(Eo * obj EINA_UNUSED,Ecore_Exe_Data * pd,const char * cmd,Ecore_Exe_Flags flags)81 _ecore_exe_command_set(Eo *obj EINA_UNUSED, Ecore_Exe_Data *pd, const char *cmd, Ecore_Exe_Flags flags)
82 {
83 if (!cmd) return;
84 pd->cmd = strdup(cmd);
85 pd->flags = flags;
86 }
87
88 EOLIAN static void
_ecore_exe_command_get(const Eo * obj EINA_UNUSED,Ecore_Exe_Data * pd,const char ** cmd,Ecore_Exe_Flags * flags)89 _ecore_exe_command_get(const Eo *obj EINA_UNUSED, Ecore_Exe_Data *pd, const char **cmd, Ecore_Exe_Flags *flags)
90 {
91 if (cmd) *cmd = pd->cmd;
92 if (flags) *flags = pd->flags;
93 }
94
95 EOLIAN static Eo *
_ecore_exe_efl_object_finalize(Eo * obj,Ecore_Exe_Data * exe)96 _ecore_exe_efl_object_finalize(Eo *obj, Ecore_Exe_Data *exe)
97 {
98 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
99 obj = efl_finalize(efl_super(obj, MY_CLASS));
100 if (!obj) return obj;
101 return _impl_ecore_exe_efl_object_finalize(obj, exe);
102 }
103
104 EAPI void
ecore_exe_callback_pre_free_set(Ecore_Exe * obj,Ecore_Exe_Cb func)105 ecore_exe_callback_pre_free_set(Ecore_Exe *obj,
106 Ecore_Exe_Cb func)
107 {
108 EINA_MAIN_LOOP_CHECK_RETURN;
109 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
110 if (!efl_isa(obj, MY_CLASS)) return;
111 exe->pre_free_cb = func;
112 }
113
114 EAPI Eina_Bool
ecore_exe_send(Ecore_Exe * obj,const void * data,int size)115 ecore_exe_send(Ecore_Exe *obj,
116 const void *data,
117 int size)
118 {
119 EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE);
120 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
121 if (!efl_isa(obj, MY_CLASS)) return EINA_FALSE;
122
123 EINA_SAFETY_ON_TRUE_RETURN_VAL(size == 0, EINA_TRUE);
124 if (exe->close_stdin)
125 {
126 ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p",
127 exe, size, data);
128 return EINA_FALSE;
129 }
130 return _impl_ecore_exe_send(obj, exe, data, size);
131 }
132
133 EAPI void
ecore_exe_close_stdin(Ecore_Exe * obj)134 ecore_exe_close_stdin(Ecore_Exe *obj)
135 {
136 EINA_MAIN_LOOP_CHECK_RETURN;
137 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
138 if (!efl_isa(obj, MY_CLASS)) return;
139 exe->close_stdin = 1;
140 }
141
142 EAPI void
ecore_exe_auto_limits_set(Ecore_Exe * obj,int start_bytes,int end_bytes,int start_lines,int end_lines)143 ecore_exe_auto_limits_set(Ecore_Exe *obj,
144 int start_bytes,
145 int end_bytes,
146 int start_lines,
147 int end_lines)
148 {
149 EINA_MAIN_LOOP_CHECK_RETURN;
150 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
151 if (!efl_isa(obj, MY_CLASS)) return;
152 _impl_ecore_exe_auto_limits_set(obj, exe, start_bytes, end_bytes,
153 start_lines, end_lines);
154 }
155
156 EAPI Ecore_Exe_Event_Data *
ecore_exe_event_data_get(Ecore_Exe * obj,Ecore_Exe_Flags flags)157 ecore_exe_event_data_get(Ecore_Exe *obj,
158 Ecore_Exe_Flags flags)
159 {
160 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
161 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
162 if (!efl_isa(obj, MY_CLASS)) return NULL;
163 return _impl_ecore_exe_event_data_get(obj, exe, flags);
164 }
165
166 EAPI void
ecore_exe_tag_set(Ecore_Exe * obj,const char * tag)167 ecore_exe_tag_set(Ecore_Exe *obj,
168 const char *tag)
169 {
170 EINA_MAIN_LOOP_CHECK_RETURN;
171 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
172 if (!efl_isa(obj, MY_CLASS)) return;
173 IF_FREE(exe->tag);
174 if (tag) exe->tag = strdup(tag);
175 else exe->tag = NULL;
176 }
177
178 EAPI const char *
ecore_exe_tag_get(const Ecore_Exe * obj)179 ecore_exe_tag_get(const Ecore_Exe *obj)
180 {
181 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
182 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
183 if (!efl_isa(obj, MY_CLASS)) return NULL;
184 return exe->tag;
185 }
186
187 EAPI void *
ecore_exe_free(Ecore_Exe * obj)188 ecore_exe_free(Ecore_Exe *obj)
189 {
190 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
191 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
192 if (!efl_isa(obj, MY_CLASS)) return NULL;
193 void *data = exe->data;
194 efl_del(obj);
195 return data;
196 }
197
198 EOLIAN static void
_ecore_exe_efl_object_destructor(Eo * obj,Ecore_Exe_Data * exe)199 _ecore_exe_efl_object_destructor(Eo *obj, Ecore_Exe_Data *exe)
200 {
201 efl_destructor(efl_super(obj, ECORE_EXE_CLASS));
202 _impl_ecore_exe_efl_object_destructor(obj, exe);
203 }
204
205 EAPI void
ecore_exe_event_data_free(Ecore_Exe_Event_Data * e)206 ecore_exe_event_data_free(Ecore_Exe_Event_Data *e)
207 {
208 if (!e) return;
209 IF_FREE(e->lines);
210 IF_FREE(e->data);
211 free(e);
212 }
213
214 EAPI pid_t
ecore_exe_pid_get(const Ecore_Exe * obj)215 ecore_exe_pid_get(const Ecore_Exe *obj)
216 {
217 EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
218 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
219 if (!efl_isa(obj, MY_CLASS)) return -1;
220 return exe->pid;
221 }
222
223 EAPI const char *
ecore_exe_cmd_get(const Ecore_Exe * obj)224 ecore_exe_cmd_get(const Ecore_Exe *obj)
225 {
226 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
227 const char *ret = NULL;
228 ecore_obj_exe_command_get(obj, &ret, NULL);
229 return ret;
230 }
231
232 EAPI void *
ecore_exe_data_get(const Ecore_Exe * obj)233 ecore_exe_data_get(const Ecore_Exe *obj)
234 {
235 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
236 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
237 if (!efl_isa(obj, MY_CLASS)) return NULL;
238 return exe->data;
239 }
240
241 EAPI void *
ecore_exe_data_set(Ecore_Exe * obj,void * data)242 ecore_exe_data_set(Ecore_Exe *obj,
243 void *data)
244 {
245 void *ret;
246 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
247 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
248 if (!efl_isa(obj, MY_CLASS)) return NULL;
249 ret = exe->data;
250 exe->data = data;
251 return ret;
252 }
253
254 EAPI Ecore_Exe_Flags
ecore_exe_flags_get(const Ecore_Exe * obj)255 ecore_exe_flags_get(const Ecore_Exe *obj)
256 {
257 EINA_MAIN_LOOP_CHECK_RETURN_VAL(0);
258 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
259 if (!efl_isa(obj, MY_CLASS)) return 0;
260 return exe->flags;
261 }
262
263 EAPI void
ecore_exe_pause(Ecore_Exe * obj)264 ecore_exe_pause(Ecore_Exe *obj)
265 {
266 efl_control_suspend_set(obj, EINA_TRUE);
267 }
268
269 EAPI void
ecore_exe_continue(Ecore_Exe * obj)270 ecore_exe_continue(Ecore_Exe *obj)
271 {
272 efl_control_suspend_set(obj, EINA_FALSE);
273 }
274
275 EOLIAN static void
_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)
277 {
278 EINA_MAIN_LOOP_CHECK_RETURN;
279 if (suspend) _impl_ecore_exe_pause(obj, exe);
280 else _impl_ecore_exe_continue(obj, exe);
281 }
282
283 EAPI void
ecore_exe_interrupt(Ecore_Exe * obj)284 ecore_exe_interrupt(Ecore_Exe *obj)
285 {
286 EINA_MAIN_LOOP_CHECK_RETURN;
287 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
288 if (!efl_isa(obj, MY_CLASS)) return;
289 _impl_ecore_exe_interrupt(obj, exe);
290 }
291
292 EAPI void
ecore_exe_quit(Ecore_Exe * obj)293 ecore_exe_quit(Ecore_Exe *obj)
294 {
295 EINA_MAIN_LOOP_CHECK_RETURN;
296 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
297 if (!efl_isa(obj, MY_CLASS)) return;
298 _impl_ecore_exe_quit(obj, exe);
299 }
300
301 EAPI void
ecore_exe_terminate(Ecore_Exe * obj)302 ecore_exe_terminate(Ecore_Exe *obj)
303 {
304 EINA_MAIN_LOOP_CHECK_RETURN;
305 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
306 if (!efl_isa(obj, MY_CLASS)) return;
307 _impl_ecore_exe_terminate(obj, exe);
308 }
309
310 EAPI void
ecore_exe_kill(Ecore_Exe * obj)311 ecore_exe_kill(Ecore_Exe *obj)
312 {
313 EINA_MAIN_LOOP_CHECK_RETURN;
314 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
315 if (!efl_isa(obj, MY_CLASS)) return;
316 _impl_ecore_exe_kill(obj, exe);
317 }
318
319 EAPI void
ecore_exe_signal(Ecore_Exe * obj,int num)320 ecore_exe_signal(Ecore_Exe *obj,
321 int num)
322 {
323 EINA_MAIN_LOOP_CHECK_RETURN;
324 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
325 if (!efl_isa(obj, MY_CLASS)) return;
326 _impl_ecore_exe_signal(obj, exe, num);
327 }
328
329 EAPI void
ecore_exe_hup(Ecore_Exe * obj)330 ecore_exe_hup(Ecore_Exe *obj)
331 {
332 EINA_MAIN_LOOP_CHECK_RETURN;
333 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
334 if (!efl_isa(obj, MY_CLASS)) return;
335 _impl_ecore_exe_hup(obj, exe);
336 }
337
338 void
_ecore_exe_init(void)339 _ecore_exe_init(void)
340 {
341 ECORE_EXE_EVENT_ADD = ecore_event_type_new();
342 ECORE_EXE_EVENT_DEL = ecore_event_type_new();
343 ECORE_EXE_EVENT_DATA = ecore_event_type_new();
344 ECORE_EXE_EVENT_ERROR = ecore_event_type_new();
345 }
346
347 void
_ecore_exe_shutdown(void)348 _ecore_exe_shutdown(void)
349 {
350 Ecore_Exe *exe = NULL;
351 Eina_List *l1, *l2;
352 Efl_Loop_Data *loop = EFL_LOOP_DATA;
353
354 EINA_LIST_FOREACH_SAFE(loop->exes, l1, l2, exe)
355 ecore_exe_free(exe);
356
357 ecore_event_type_flush(ECORE_EXE_EVENT_ADD,
358 ECORE_EXE_EVENT_DEL,
359 ECORE_EXE_EVENT_DATA,
360 ECORE_EXE_EVENT_ERROR);
361 }
362
363 Ecore_Exe *
_ecore_exe_find(pid_t pid)364 _ecore_exe_find(pid_t pid)
365 {
366 Eina_List *itr;
367 Ecore_Exe *obj;
368 Efl_Loop_Data *loop = EFL_LOOP_DATA;
369
370 EINA_LIST_FOREACH(loop->exes, itr, obj)
371 {
372 Ecore_Exe_Data *exe = efl_data_scope_get(obj, MY_CLASS);
373 if (exe->pid == pid) return obj;
374 }
375 return NULL;
376 }
377
378 void *
_ecore_exe_event_del_new(void)379 _ecore_exe_event_del_new(void)
380 {
381 Ecore_Exe_Event_Del *e = calloc(1, sizeof(Ecore_Exe_Event_Del));
382 return e;
383 }
384
385 void
_ecore_exe_event_del_free(void * data EINA_UNUSED,void * ev)386 _ecore_exe_event_del_free(void *data EINA_UNUSED,
387 void *ev)
388 {
389 Ecore_Exe_Event_Del *e = ev;
390 if (e->exe) ecore_exe_free(e->exe);
391 free(e);
392 }
393
394 void
_ecore_exe_event_exe_data_free(void * data EINA_UNUSED,void * ev)395 _ecore_exe_event_exe_data_free(void *data EINA_UNUSED,
396 void *ev)
397 {
398 Ecore_Exe_Event_Data *e = ev;
399 ecore_exe_event_data_free(e);
400 }
401
402 Ecore_Exe_Event_Add *
_ecore_exe_event_add_new(void)403 _ecore_exe_event_add_new(void)
404 {
405 Ecore_Exe_Event_Add *e = calloc(1, sizeof(Ecore_Exe_Event_Add));
406 return e;
407 }
408
409 void
_ecore_exe_event_add_free(void * data EINA_UNUSED,void * ev)410 _ecore_exe_event_add_free(void *data EINA_UNUSED,
411 void *ev)
412 {
413 Ecore_Exe_Event_Add *e = ev;
414 free(e);
415 }
416
417 #include "ecore_exe_eo.c"
418