Bug Summary

File:tests/suite/ecore/src/lib/ecore_exe.c
Location:line 528, column 14
Description:Value stored to 'vfork_exec_errno' is never read

Annotated Source Code

1#ifdef HAVE_CONFIG_H1
2# include <config.h>
3#endif
4
5#include <sys/time.h>
6#include <sys/resource.h>
7
8#include <stdlib.h>
9#include <stdio.h>
10#include <string.h>
11#include <errno(*__errno_location ()).h>
12#include <sys/types.h>
13#include <unistd.h>
14#include <fcntl.h>
15
16#ifdef HAVE_SYS_WAIT_H1
17# include <sys/wait.h>
18#endif
19
20#include "Ecore.h"
21#include "ecore_private.h"
22
23
24 /* FIXME: Getting respawn to work
25 *
26 * There is no way that we can do anything about the internal state info of
27 * an external exe. The same can be said about the state of user code. User
28 * code in this context means the code that is using ecore_exe to manage exe's
29 * for it.
30 *
31 * Document that the exe must be respawnable, in other words, there is no
32 * state that it cannot regenerate by just killing it and starting it again.
33 * This includes state that the user code knows about, as the respawn is
34 * transparent to that code. On the other hand, maybe a respawn event might
35 * be useful, or maybe resend the currently non existent add event. For
36 * consistancy with ecore_con, an add event is good anyway.
37 *
38 * The Ecore_exe structure is reused for respawning, so that the (opaque)
39 * pointer held by the user remains valid. This means that the Ecore_Exe
40 * init and del functions may need to be split into two parts each to avoid
41 * duplicating code - common code part, and the rest. This implies that
42 * the unchanging members mentioned next should NEVER change.
43 *
44 * These structure members don't need to change -
45 * __list_data - we stay on the list
46 * ECORE_MAGIC - this is a constant
47 * data - passed in originally
48 * cmd - passed in originally
49 * flags - passed in originally
50 *
51 * These structure members need to change -
52 * tag - state that must be regenerated, zap it
53 * pid - it will be different
54 * child_fd_write - it will be different
55 * child_fd_read - it will be different
56 * child_fd_error - it will be different
57 * write_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
58 * read_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
59 * error_fd_handler - we cannot change the fd used by a handler, this changes coz the fd changes.
60 *
61 * Hmm, the read, write, and error buffers could be tricky.
62 * They are not atomic, and could be in a semi complete state.
63 * They fall into the "state must be regenerated" mentioned above.
64 * A respawn/add event should take care of it.
65 *
66 * These structure members need to change -
67 * write_data_buf - state that must be regenerated, zap it
68 * write_data_size - state that must be regenerated, zap it
69 * write_data_offset - state that must be regenerated, zap it
70 * read_data_buf - state that must be regenerated, zap it
71 * read_data_size - state that must be regenerated, zap it
72 * error_data_buf - state that must be regenerated, zap it
73 * error_data_size - state that must be regenerated, zap it
74 * close_write - state that must be regenerated, zap it
75 *
76 * There is the problem that an exe that fell over and needs respawning
77 * might keep falling over, keep needing to be respawned, and tie up system
78 * resources with the constant respawning. An exponentially increasing
79 * timeout (with maximum timeout) between respawns should take care of that.
80 * Although this is not a "contention for a resource" problem, the exe falling
81 * over may be, so a random element added to the timeout may help, and won't
82 * hurt. The user code may need to be informed that a timeout is in progress.
83 */
84
85struct _Ecore_Exe
86{
87 EINA_INLISTEina_Inlist __in_list;
88 ECORE_MAGICEcore_Magic __magic;
89 pid_t pid;
90 void *data;
91 char *tag, *cmd;
92 Ecore_Exe_Flags flags;
93 Ecore_Fd_Handler *write_fd_handler; /* the fd_handler to handle write to child - if this was used, or NULL if not */
94 Ecore_Fd_Handler *read_fd_handler; /* the fd_handler to handle read from child - if this was used, or NULL if not */
95 Ecore_Fd_Handler *error_fd_handler; /* the fd_handler to handle errors from child - if this was used, or NULL if not */
96 void *write_data_buf; /* a data buffer for data to write to the child -
97 * realloced as needed for more data and flushed when the fd handler says writes are possible
98 */
99 int write_data_size; /* the size in bytes of the data buffer */
100 int write_data_offset; /* the offset in bytes in the data buffer */
101 void *read_data_buf; /* data read from the child awating delivery to an event */
102 int read_data_size; /* data read from child in bytes */
103 void *error_data_buf; /* errors read from the child awating delivery to an event */
104 int error_data_size; /* errors read from child in bytes */
105 int child_fd_write; /* fd to write TO to send data to the child */
106 int child_fd_read; /* fd to read FROM when child has sent us (the parent) data */
107 int child_fd_error; /* fd to read FROM when child has sent us (the parent) errors */
108 int child_fd_write_x; /* fd to write TO to send data to the child */
109 int child_fd_read_x; /* fd to read FROM when child has sent us (the parent) data */
110 int child_fd_error_x; /* fd to read FROM when child has sent us (the parent) errors */
111 Eina_Bool close_stdin : 1;
112
113 int start_bytes, end_bytes, start_lines, end_lines; /* Number of bytes/lines to auto pipe at start/end of stdout/stderr. */
114
115 Ecore_Timer *doomsday_clock; /* The Timer of Death. Muahahahaha. */
116 void *doomsday_clock_dead; /* data for the doomsday clock */
117
118 Ecore_Exe_Cb pre_free_cb;
119};
120
121
122/* TODO: Something to let people build a command line and does auto escaping -
123 *
124 * ecore_exe_snprintf()
125 *
126 * OR
127 *
128 * cmd = ecore_exe_comand_parameter_append(cmd, "firefox");
129 * cmd = ecore_exe_comand_parameter_append(cmd, "http://www.foo.com/bar.html?baz=yes");
130 * each parameter appended is one argument, and it gets escaped, quoted, and
131 * appended with a preceding space. The first is the command off course.
132 */
133
134struct _ecore_exe_dead_exe
135{
136 pid_t pid;
137 char *cmd;
138};
139
140static inline void _ecore_exe_exec_it(const char *exe_cmd, Ecore_Exe_Flags flags);
141static Eina_Bool _ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_Exe_Flags flags);
142static Eina_Bool _ecore_exe_data_error_handler(void *data, Ecore_Fd_Handler *fd_handler);
143static Eina_Bool _ecore_exe_data_read_handler(void *data, Ecore_Fd_Handler *fd_handler);
144static Eina_Bool _ecore_exe_data_write_handler(void *data, Ecore_Fd_Handler *fd_handler);
145static void _ecore_exe_flush(Ecore_Exe * exe);
146static void _ecore_exe_event_exe_data_free(void *data __UNUSED__, void *ev);
147static Ecore_Exe *_ecore_exe_is_it_alive(pid_t pid);
148static Eina_Bool _ecore_exe_make_sure_its_dead(void *data);
149static Eina_Bool _ecore_exe_make_sure_its_really_dead(void *data);
150static Ecore_Exe_Event_Add *_ecore_exe_event_add_new(void);
151static void _ecore_exe_event_add_free(void *data, void *ev);
152static void _ecore_exe_dead_attach(Ecore_Exe *exe);
153
154EAPI__attribute__ ((visibility("default"))) int ECORE_EXE_EVENT_ADD = 0;
155EAPI__attribute__ ((visibility("default"))) int ECORE_EXE_EVENT_DEL = 0;
156EAPI__attribute__ ((visibility("default"))) int ECORE_EXE_EVENT_DATA = 0;
157EAPI__attribute__ ((visibility("default"))) int ECORE_EXE_EVENT_ERROR = 0;
158
159static Ecore_Exe *exes = NULL((void*)0);
160static const char *shell = NULL((void*)0);
161
162/* FIXME: This errno checking stuff should be put elsewhere for everybody to use.
163 * For now it lives here though, just to make testing easier.
164 */
165static int _ecore_exe_check_errno(int result, const char *file, int line);
166
167#define E_IF_NO_ERRNO(result, foo, ok)while (((ok) = _ecore_exe_check_errno( (result) = (foo), "ecore/src/lib/ecore_exe.c"
, 167)) == -1) sleep(1); if (ok)
\
168 while (((ok) = _ecore_exe_check_errno( (result) = (foo), __FILE__"ecore/src/lib/ecore_exe.c", __LINE__168)) == -1) sleep(1); \
169 if (ok)
170
171#define E_NO_ERRNO(result, foo, ok)while (((ok) = _ecore_exe_check_errno( (result) = (foo), "ecore/src/lib/ecore_exe.c"
, 171)) == -1) sleep(1)
\
172 while (((ok) = _ecore_exe_check_errno( (result) = (foo), __FILE__"ecore/src/lib/ecore_exe.c", __LINE__172)) == -1) sleep(1)
173
174#define E_IF_NO_ERRNO_NOLOOP(result, foo, ok)if (((ok) = _ecore_exe_check_errno( (result) = (foo), "ecore/src/lib/ecore_exe.c"
, 174)))
\
175 if (((ok) = _ecore_exe_check_errno( (result) = (foo), __FILE__"ecore/src/lib/ecore_exe.c", __LINE__175)))
176
177static int
178_ecore_exe_check_errno(int result, const char *file, int line)
179{
180 int saved_errno = errno(*__errno_location ());
181
182 if (result == -1)
183 {
184 perror("*** errno reports ");
185/* What is currently supported -
186 *
187 * pipe
188 * EFAULT Argument is not valid.
189 * EMFILE Too many file descriptors used by process.
190 * ENFILE Too many open files by system.
191 * read
192 * EAGAIN No data now, try again.
193 * EBADF This is not an fd that can be read.
194 * EFAULT This is not a valid buffer.
195 * EINTR Interupted by signal, try again.
196 * EINVAL This is not an fd that can be read.
197 * EIO I/O error.
198 * EISDIR This is a directory, and cannot be read.
199 * others Depending on what sort of thing we are reading from.
200 * close
201 * EBADF This is not an fd that can be closed.
202 * EINTR Interupted by signal, try again.
203 * EIO I/O error.
204 * dup2
205 * EBADF This is not an fd that can be dup2'ed.
206 * EBUSY Race condition between open() and dup()
207 * EINTR Interupted by signal, try again.
208 * EMFILE Too many file descriptors used by process.
209 * fcntl
210 * EACCES, EAGAIN Locked or mapped by something else, try again later.
211 * EBADF This is not an fd that can be fcntl'ed.
212 * EDEADLK This will cause a deadlock.
213 * EFAULT This is not a valid lock.
214 * EINTR Interupted by signal, try again.
215 * EINVAL This is not a valid arg.
216 * EMFILE Too many file descriptors used by process.
217 * ENOLCK Problem getting a lock.
218 * EPERM Not allowed to do that.
219 * fsync
220 * EBADF This is not an fd that is open for writing.
221 * EINVAL, EROFS This is not an fd that can be fsynced.
222 * EIO I/O error.
223 *
224 * How to use it -
225 * int ok = 0;
226 * int result;
227 *
228 * E_IF_NO_ERRNO(result, foo(bar), ok)
229 * {
230 * E_IF_NO_ERRNO_NOLOOP(result, foo(bar), ok)
231 * {
232 * }
233 * }
234 *
235 * if (!ok)
236 * {
237 * // Something failed, cleanup.
238 * }
239 */
240 switch (saved_errno)
241 {
242 case EACCES13:
243 case EAGAIN11:
244 case EINTR4:
245 { /* Not now, try later. */
246 ERR("*** Must try again in %s @%u.", file, line)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 246, "*** Must try again in %s @%u.", file, line
)
;
247 result = -1;
248 break;
249 }
250 case EMFILE24:
251 case ENFILE23:
252 case ENOLCK37:
253 { /* Low on resources. */
254 ERR("*** Low on resources in %s @%u.", file,eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 255, "*** Low on resources in %s @%u.", file,
line)
255 line)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 255, "*** Low on resources in %s @%u.", file,
line)
;
256 result = 0;
257 break;
258 }
259 case EIO5:
260 { /* I/O error. */
261 ERR("*** I/O error in %s @%u.", file, line)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 261, "*** I/O error in %s @%u.", file, line)
;
262 result = 0;
263 break;
264 }
265 case EFAULT14:
266 case EBADF9:
267 case EINVAL22:
268 case EROFS30:
269 case EISDIR21:
270 case EDEADLK35:
271 case EPERM1:
272 case EBUSY16:
273 { /* Programmer fucked up. */
274 ERR("*** NAUGHTY PROGRAMMER!!!\n"eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 277, "*** NAUGHTY PROGRAMMER!!!\n" "*** SPANK SPANK SPANK!!!\n"
"*** Now go fix your code in %s @%u. Tut tut tut!", file, line
)
275 "*** SPANK SPANK SPANK!!!\n"eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 277, "*** NAUGHTY PROGRAMMER!!!\n" "*** SPANK SPANK SPANK!!!\n"
"*** Now go fix your code in %s @%u. Tut tut tut!", file, line
)
276 "*** Now go fix your code in %s @%u. Tut tut tut!",eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 277, "*** NAUGHTY PROGRAMMER!!!\n" "*** SPANK SPANK SPANK!!!\n"
"*** Now go fix your code in %s @%u. Tut tut tut!", file, line
)
277 file, line)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 277, "*** NAUGHTY PROGRAMMER!!!\n" "*** SPANK SPANK SPANK!!!\n"
"*** Now go fix your code in %s @%u. Tut tut tut!", file, line
)
;
278 result = 0;
279 break;
280 }
281 default:
282 { /* Unsupported errno code, please add this one. */
283 ERR("*** NAUGHTY PROGRAMMER!!!\n"eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 287, "*** NAUGHTY PROGRAMMER!!!\n" "*** SPANK SPANK SPANK!!!\n"
"*** Unsupported errno code %d, please add this one.\n" "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!"
, saved_errno, "ecore/src/lib/ecore_exe.c", 287, file, line)
284 "*** SPANK SPANK SPANK!!!\n"eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 287, "*** NAUGHTY PROGRAMMER!!!\n" "*** SPANK SPANK SPANK!!!\n"
"*** Unsupported errno code %d, please add this one.\n" "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!"
, saved_errno, "ecore/src/lib/ecore_exe.c", 287, file, line)
285 "*** Unsupported errno code %d, please add this one.\n"eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 287, "*** NAUGHTY PROGRAMMER!!!\n" "*** SPANK SPANK SPANK!!!\n"
"*** Unsupported errno code %d, please add this one.\n" "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!"
, saved_errno, "ecore/src/lib/ecore_exe.c", 287, file, line)
286 "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!",eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 287, "*** NAUGHTY PROGRAMMER!!!\n" "*** SPANK SPANK SPANK!!!\n"
"*** Unsupported errno code %d, please add this one.\n" "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!"
, saved_errno, "ecore/src/lib/ecore_exe.c", 287, file, line)
287 saved_errno, __FILE__, __LINE__, file, line)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 287, "*** NAUGHTY PROGRAMMER!!!\n" "*** SPANK SPANK SPANK!!!\n"
"*** Unsupported errno code %d, please add this one.\n" "*** Now go fix your code in %s @%u, from %s @%u. Tut tut tut!"
, saved_errno, "ecore/src/lib/ecore_exe.c", 287, file, line)
;
288 result = 0;
289 break;
290 }
291 }
292 }
293 else /* Everything is fine. */
294 result = 1;
295
296 errno(*__errno_location ()) = saved_errno;
297 return result;
298}
299
300/**
301 * @defgroup Ecore_Exe_Basic_Group Process Spawning Functions
302 *
303 * Functions that deal with spawned processes.
304 */
305
306static int run_pri = ECORE_EXE_PRIORITY_INHERIT9999;
307
308/**
309 * Sets the priority at which to launch processes
310 *
311 * This sets the priority of processes run by ecore_exe_run() and
312 * ecore_exe_pipe_run().
313 * @li On Windows, the child process is created by default with the
314 * #ECORE_EXE_WIN32_PRIORITY_NORMAL priority, unless the calling
315 * process is in #ECORE_EXE_WIN32_PRIORITY_IDLE or
316 * #ECORE_EXE_WIN32_PRIORITY_BELOW_NORMAL priority. In that case, the
317 * child process inherits this priority.
318 * @li On other platforms, if set to #ECORE_EXE_PRIORITY_INHERIT child
319 * processes inherits the priority of their parent. This is the default.
320 *
321 * @param pri value a Ecore_Exe_Win32_Priority value on Windows, -20
322 * to 19 or ECORE_EXE_PRIORITY_INHERIT on other OS.
323 * @ingroup Ecore_Exe_Basic_Group
324 */
325EAPI__attribute__ ((visibility("default"))) void
326ecore_exe_run_priority_set(int pri)
327{
328 run_pri = pri;
329}
330
331/**
332 * Gets the priority at which to launch processes
333 *
334 * This gets ths priority of launched processes. See
335 * ecore_exe_run_priority_set() for details. This just returns the value set
336 * by this call.
337 *
338 * @return the value set by ecore_exe_run_priority_set()
339 * @ingroup Ecore_Exe_Basic_Group
340 */
341EAPI__attribute__ ((visibility("default"))) int
342ecore_exe_run_priority_get(void)
343{
344 return run_pri;
345}
346
347/**
348 * Spawns a child process.
349 *
350 * This is now just a thin wrapper around ecore_exe_pipe_run()
351 *
352 * @param exe_cmd The command to run with @c /bin/sh.
353 * @param data Data to attach to the returned process handle.
354 * @return A process handle to the spawned process.
355 * @ingroup Ecore_Exe_Basic_Group
356 */
357EAPI__attribute__ ((visibility("default"))) Ecore_Exe *
358ecore_exe_run(const char *exe_cmd, const void *data)
359{
360/* I'm just being paranoid again, leaving in the original code in case there is a problem. */
361#if 0
362 Ecore_Exe *exe;
363 pid_t pid;
364
365 if (!exe_cmd)
366 return NULL((void*)0);
367 pid = fork();
368 if (pid)
369 {
370 exe = calloc(1, sizeof(Ecore_Exe));
371 if (!exe)
372 {
373 kill(pid, SIGKILL9);
374 return NULL((void*)0);
375 }
376 ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE)(exe)->__magic = (0xf7e812f5);
377 exe->pid = pid;
378 exe->data = (void *)data;
379 exe->cmd = strdup(exe_cmd);
380 exes = _ecore_list2_append(exes, exe);
381 return exe;
382 }
383 _ecore_exe_exec_it(exe_cmd, 0);
384 exit(127);
385 return NULL((void*)0);
386#else
387 return ecore_exe_pipe_run(exe_cmd, 0, data);
388#endif
389}
390
391/**
392 * Spawns a child process with its stdin/out available for communication.
393 *
394 * This function forks and runs the given command using @c /bin/sh.
395 *
396 * Note that the process handle is only valid until a child process
397 * terminated event is received. After all handlers for the child process
398 * terminated event have been called, the handle will be freed by Ecore.
399 *
400 * This function does the same thing as ecore_exe_run(), but also makes the
401 * standard in and/or out as well as stderr from the child process available
402 * for reading or writing. To write use ecore_exe_send(). To read listen to
403 * ECORE_EXE_EVENT_DATA or ECORE_EXE_EVENT_ERROR events (set up handlers).
404 * Ecore may buffer read and error data until a newline character if asked
405 * for with the @p flags. All data will be included in the events (newlines
406 * will be replaced with NULLS if line buffered). ECORE_EXE_EVENT_DATA events
407 * will only happen if the process is run with ECORE_EXE_PIPE_READ enabled
408 * in the flags. The same with the error version. Writing will only be
409 * allowed with ECORE_EXE_PIPE_WRITE enabled in the flags.
410 *
411 * @param exe_cmd The command to run with @c /bin/sh.
412 * @param flags The flag parameters for how to deal with inter-process I/O
413 * @param data Data to attach to the returned process handle.
414 * @return A process handle to the spawned process.
415 * @ingroup Ecore_Exe_Basic_Group
416 */
417EAPI__attribute__ ((visibility("default"))) Ecore_Exe *
418ecore_exe_pipe_run(const char *exe_cmd, Ecore_Exe_Flags flags, const void *data)
419{
420 Ecore_Exe *exe = NULL((void*)0);
421 int statusPipe[2] = { -1, -1 };
422 int errorPipe[2] = { -1, -1 };
423 int readPipe[2] = { -1, -1 };
424 int writePipe[2] = { -1, -1 };
425 int n = 0;
426 int ok = 1;
427 int result;
428
429 if (!exe_cmd) return NULL((void*)0);
430 exe = calloc(1, sizeof(Ecore_Exe));
431 if (!exe) return NULL((void*)0);
432
433 if ((flags & ECORE_EXE_PIPE_AUTO) && (!(flags & ECORE_EXE_PIPE_ERROR))
434 && (!(flags & ECORE_EXE_PIPE_READ)))
435 /* We need something to auto pipe. */
436 flags |= ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR;
437
438 exe->child_fd_error = -1;
439 exe->child_fd_read = -1;
440 exe->child_fd_write = -1;
441 exe->child_fd_error_x = -1;
442 exe->child_fd_read_x = -1;
443 exe->child_fd_write_x = -1;
444
445 /* Create some pipes. */
446 if (ok)
447 {
448 E_IF_NO_ERRNO_NOLOOP(result, pipe(statusPipe), ok)if (((ok) = _ecore_exe_check_errno( (result) = (pipe(statusPipe
)), "ecore/src/lib/ecore_exe.c", 448)))
449 {
450 }
451 }
452 if (ok && (flags & ECORE_EXE_PIPE_ERROR))
453 {
454 E_IF_NO_ERRNO_NOLOOP(result, pipe(errorPipe), ok)if (((ok) = _ecore_exe_check_errno( (result) = (pipe(errorPipe
)), "ecore/src/lib/ecore_exe.c", 454)))
455 {
456 exe->child_fd_error = errorPipe[0];
457 exe->child_fd_error_x = errorPipe[1];
458 }
459 }
460 if (ok && (flags & ECORE_EXE_PIPE_READ))
461 {
462 E_IF_NO_ERRNO_NOLOOP(result, pipe(readPipe), ok)if (((ok) = _ecore_exe_check_errno( (result) = (pipe(readPipe
)), "ecore/src/lib/ecore_exe.c", 462)))
463 {
464 exe->child_fd_read = readPipe[0];
465 exe->child_fd_read_x = readPipe[1];
466 }
467 }
468 if (ok && (flags & ECORE_EXE_PIPE_WRITE))
469 {
470 E_IF_NO_ERRNO_NOLOOP(result, pipe(writePipe), ok)if (((ok) = _ecore_exe_check_errno( (result) = (pipe(writePipe
)), "ecore/src/lib/ecore_exe.c", 470)))
471 {
472 exe->child_fd_write = writePipe[1];
473 exe->child_fd_write_x = writePipe[0];
474 }
475 }
476 if (ok)
477 {
478 pid_t pid = 0;
479 volatile int vfork_exec_errno = 0;
480
481 /* FIXME: I should double check this. After a quick look around, this is already done, but via a more modern method. */
482 /* signal(SIGPIPE, SIG_IGN); We only want EPIPE on errors */
483 pid = fork();
484
485 if (pid == -1)
486 {
487 ERR("Failed to fork process")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 487, "Failed to fork process")
;
488 pid = 0;
489 }
490 else if (pid == 0) /* child */
491 {
492 if (run_pri != ECORE_EXE_PRIORITY_INHERIT9999)
493 {
494 if ((run_pri >= -20) && (run_pri <= 19))
495 setpriority(PRIO_PROCESSPRIO_PROCESS, 0, run_pri);
496 }
497 /* dup2 STDERR, STDIN, and STDOUT. dup2() allegedly closes the
498 * second pipe if it's open. On the other hand, there was the
499 * Great FD Leak Scare of '06, so let's be paranoid. */
500 if (ok && (flags & ECORE_EXE_PIPE_ERROR))
501 {
502 E_NO_ERRNO(result, close(STDERR_FILENO), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(2)),
"ecore/src/lib/ecore_exe.c", 502)) == -1) sleep(1)
;
503 E_NO_ERRNO(result, dup2(errorPipe[1], STDERR_FILENO), ok)while (((ok) = _ecore_exe_check_errno( (result) = (dup2(errorPipe
[1], 2)), "ecore/src/lib/ecore_exe.c", 503)) == -1) sleep(1)
;
504 }
505 if (ok && (flags & ECORE_EXE_PIPE_READ))
506 {
507 E_NO_ERRNO(result, close(STDOUT_FILENO), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(1)),
"ecore/src/lib/ecore_exe.c", 507)) == -1) sleep(1)
;
508 E_NO_ERRNO(result, dup2(readPipe[1], STDOUT_FILENO), ok)while (((ok) = _ecore_exe_check_errno( (result) = (dup2(readPipe
[1], 1)), "ecore/src/lib/ecore_exe.c", 508)) == -1) sleep(1)
;
509 }
510 if (ok && (flags & ECORE_EXE_PIPE_WRITE))
511 {
512 E_NO_ERRNO(result, close(STDIN_FILENO), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(0)),
"ecore/src/lib/ecore_exe.c", 512)) == -1) sleep(1)
;
513 E_NO_ERRNO(result, dup2(writePipe[0], STDIN_FILENO), ok)while (((ok) = _ecore_exe_check_errno( (result) = (dup2(writePipe
[0], 0)), "ecore/src/lib/ecore_exe.c", 513)) == -1) sleep(1)
;
514 }
515
516 if (ok)
517 {
518 /* Setup the status pipe. */
519 E_NO_ERRNO(result, close(statusPipe[0]), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(statusPipe
[0])), "ecore/src/lib/ecore_exe.c", 519)) == -1) sleep(1)
;
520 E_IF_NO_ERRNO(result, fcntl(statusPipe[1], F_SETFD, FD_CLOEXEC), ok)while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(statusPipe
[1], 2, 1)), "ecore/src/lib/ecore_exe.c", 520)) == -1) sleep(
1); if (ok)
/* close on exec shows success */
521 {
522 /* Run the actual command. */
523 _ecore_exe_exec_it(exe_cmd, flags); /* no return */
524 }
525 }
526
527 /* Something went 'orribly wrong. */
528 vfork_exec_errno = errno(*__errno_location ());
Value stored to 'vfork_exec_errno' is never read
529
530 /* Close the pipes. */
531 if (flags & ECORE_EXE_PIPE_ERROR)
532 E_NO_ERRNO(result, close(errorPipe[1]), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(errorPipe
[1])), "ecore/src/lib/ecore_exe.c", 532)) == -1) sleep(1)
;
533 if (flags & ECORE_EXE_PIPE_READ)
534 E_NO_ERRNO(result, close(readPipe[1]), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(readPipe
[1])), "ecore/src/lib/ecore_exe.c", 534)) == -1) sleep(1)
;
535 if (flags & ECORE_EXE_PIPE_WRITE)
536 E_NO_ERRNO(result, close(writePipe[0]), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(writePipe
[0])), "ecore/src/lib/ecore_exe.c", 536)) == -1) sleep(1)
;
537 E_NO_ERRNO(result, close(statusPipe[1]), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(statusPipe
[1])), "ecore/src/lib/ecore_exe.c", 537)) == -1) sleep(1)
;
538
539 _exit(-1);
540 }
541 else /* parent */
542 {
543 /* Close the unused pipes. */
544 E_NO_ERRNO(result, close(statusPipe[1]), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(statusPipe
[1])), "ecore/src/lib/ecore_exe.c", 544)) == -1) sleep(1)
;
545
546 /* FIXME: after having a good look at the current e fd
547 * handling, investigate fcntl(dataPipe[x], F_SETSIG, ...) */
548 /* FIXME: above F_SETSIG etc. - this is async SIGIO based IO
549 * which is also linux specific so we probably don't want to
550 * do this as long as select() is working fine. the only time
551 * we really want to think of SIGIO async IO is when it all
552 * actually works basically everywhere and we can turn all
553 * IO into DMA async activities (i.e. you do a read() then
554 * the read is complete not on return but when you get a
555 * SIGIO - the read() just starts the transfer and it is
556 * completed in the background by DMA (or whatever mechanism
557 * the kernel choses)) */
558
559 /* Wait for it to start executing. */
560 /* FIXME: this doesn't seem very nice - we sit and block
561 * waiting on a child process... even though it's just
562 * the segment between the fork() and the exec) it just feels
563 * wrong */
564 for (;;)
565 {
566 char buf;
567
568 E_NO_ERRNO(result, read(statusPipe[0], &buf, 1), ok)while (((ok) = _ecore_exe_check_errno( (result) = (read(statusPipe
[0], &buf, 1)), "ecore/src/lib/ecore_exe.c", 568)) == -1)
sleep(1)
;
569 if (result == 0)
570 {
571 if (vfork_exec_errno != 0)
572 {
573 n = vfork_exec_errno;
574 ERR("Could not start \"%s\"", exe_cmd)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 574, "Could not start \"%s\"", exe_cmd)
;
575 pid = 0;
576 }
577 break;
578 }
579 }
580
581 /* Close the status pipe. */
582 E_NO_ERRNO(result, close(statusPipe[0]), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(statusPipe
[0])), "ecore/src/lib/ecore_exe.c", 582)) == -1) sleep(1)
;
583 }
584
585 if (pid)
586 {
587 /* Setup the exe structure. */
588 ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE)(exe)->__magic = (0xf7e812f5);
589 exe->start_bytes = -1;
590 exe->end_bytes = -1;
591 exe->start_lines = -1;
592 exe->end_lines = -1;
593 exe->pid = pid;
594 exe->flags = flags;
595 exe->data = (void *)data;
596 if ((exe->cmd = strdup(exe_cmd)))
597 {
598 if (flags & ECORE_EXE_PIPE_ERROR)
599 { /* Setup the error stuff. */
600 E_IF_NO_ERRNO(result,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_error, 4, 04000)), "ecore/src/lib/ecore_exe.c", 602)
) == -1) sleep(1); if (ok)
601 fcntl(exe->child_fd_error, F_SETFL,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_error, 4, 04000)), "ecore/src/lib/ecore_exe.c", 602)
) == -1) sleep(1); if (ok)
602 O_NONBLOCK), ok)while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_error, 4, 04000)), "ecore/src/lib/ecore_exe.c", 602)
) == -1) sleep(1); if (ok)
{}
603 E_IF_NO_ERRNO(result,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_error, 2, 1)), "ecore/src/lib/ecore_exe.c", 605)) ==
-1) sleep(1); if (ok)
604 fcntl(exe->child_fd_error, F_SETFD,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_error, 2, 1)), "ecore/src/lib/ecore_exe.c", 605)) ==
-1) sleep(1); if (ok)
605 FD_CLOEXEC), ok)while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_error, 2, 1)), "ecore/src/lib/ecore_exe.c", 605)) ==
-1) sleep(1); if (ok)
{}
606 E_IF_NO_ERRNO(result,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_error_x, 2, 1)), "ecore/src/lib/ecore_exe.c", 608)) ==
-1) sleep(1); if (ok)
607 fcntl(exe->child_fd_error_x, F_SETFD,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_error_x, 2, 1)), "ecore/src/lib/ecore_exe.c", 608)) ==
-1) sleep(1); if (ok)
608 FD_CLOEXEC), ok)while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_error_x, 2, 1)), "ecore/src/lib/ecore_exe.c", 608)) ==
-1) sleep(1); if (ok)
{}
609 {
610 exe->error_fd_handler =
611 ecore_main_fd_handler_add(exe->child_fd_error,
612 ECORE_FD_READ,
613 _ecore_exe_data_error_handler,
614 exe, NULL((void*)0), NULL((void*)0));
615 if (!exe->error_fd_handler)
616 ok = 0;
617 }
618 }
619 if (ok && (flags & ECORE_EXE_PIPE_READ))
620 { /* Setup the read stuff. */
621 E_IF_NO_ERRNO(result,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_read, 4, 04000)), "ecore/src/lib/ecore_exe.c", 623))
== -1) sleep(1); if (ok)
622 fcntl(exe->child_fd_read, F_SETFL,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_read, 4, 04000)), "ecore/src/lib/ecore_exe.c", 623))
== -1) sleep(1); if (ok)
623 O_NONBLOCK), ok)while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_read, 4, 04000)), "ecore/src/lib/ecore_exe.c", 623))
== -1) sleep(1); if (ok)
{}
624 E_IF_NO_ERRNO(result,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_read, 2, 1)), "ecore/src/lib/ecore_exe.c", 626)) == -
1) sleep(1); if (ok)
625 fcntl(exe->child_fd_read, F_SETFD,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_read, 2, 1)), "ecore/src/lib/ecore_exe.c", 626)) == -
1) sleep(1); if (ok)
626 FD_CLOEXEC), ok)while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_read, 2, 1)), "ecore/src/lib/ecore_exe.c", 626)) == -
1) sleep(1); if (ok)
{}
627 E_IF_NO_ERRNO(result,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_read_x, 2, 1)), "ecore/src/lib/ecore_exe.c", 629)) ==
-1) sleep(1); if (ok)
628 fcntl(exe->child_fd_read_x, F_SETFD,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_read_x, 2, 1)), "ecore/src/lib/ecore_exe.c", 629)) ==
-1) sleep(1); if (ok)
629 FD_CLOEXEC), ok)while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_read_x, 2, 1)), "ecore/src/lib/ecore_exe.c", 629)) ==
-1) sleep(1); if (ok)
{}
630 {
631 exe->read_fd_handler =
632 ecore_main_fd_handler_add(exe->child_fd_read,
633 ECORE_FD_READ,
634 _ecore_exe_data_read_handler,
635 exe, NULL((void*)0), NULL((void*)0));
636 if (!exe->read_fd_handler)
637 ok = 0;
638 }
639 }
640 if (ok && (flags & ECORE_EXE_PIPE_WRITE))
641 { /* Setup the write stuff. */
642 E_IF_NO_ERRNO(result,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_write, 4, 04000)), "ecore/src/lib/ecore_exe.c", 644)
) == -1) sleep(1); if (ok)
643 fcntl(exe->child_fd_write, F_SETFL,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_write, 4, 04000)), "ecore/src/lib/ecore_exe.c", 644)
) == -1) sleep(1); if (ok)
644 O_NONBLOCK), ok)while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_write, 4, 04000)), "ecore/src/lib/ecore_exe.c", 644)
) == -1) sleep(1); if (ok)
{}
645 E_IF_NO_ERRNO(result,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_write, 2, 1)), "ecore/src/lib/ecore_exe.c", 647)) ==
-1) sleep(1); if (ok)
646 fcntl(exe->child_fd_write, F_SETFD,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_write, 2, 1)), "ecore/src/lib/ecore_exe.c", 647)) ==
-1) sleep(1); if (ok)
647 FD_CLOEXEC), ok)while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_write, 2, 1)), "ecore/src/lib/ecore_exe.c", 647)) ==
-1) sleep(1); if (ok)
{}
648 E_IF_NO_ERRNO(result,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_write_x, 2, 1)), "ecore/src/lib/ecore_exe.c", 650)) ==
-1) sleep(1); if (ok)
649 fcntl(exe->child_fd_write_x, F_SETFD,while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_write_x, 2, 1)), "ecore/src/lib/ecore_exe.c", 650)) ==
-1) sleep(1); if (ok)
650 FD_CLOEXEC), ok)while (((ok) = _ecore_exe_check_errno( (result) = (fcntl(exe->
child_fd_write_x, 2, 1)), "ecore/src/lib/ecore_exe.c", 650)) ==
-1) sleep(1); if (ok)
{}
651 {
652 exe->write_fd_handler =
653 ecore_main_fd_handler_add(exe->child_fd_write,
654 ECORE_FD_WRITE,
655 _ecore_exe_data_write_handler,
656 exe, NULL((void*)0), NULL((void*)0));
657 if (exe->write_fd_handler)
658 ecore_main_fd_handler_active_set(exe->write_fd_handler, 0); /* Nothing to write to start with. */
659 else
660 ok = 0;
661 }
662 }
663
664 exes = (Ecore_Exe *) eina_inlist_append(EINA_INLIST_GET(exes)(& ((exes)->__in_list)), EINA_INLIST_GET(exe)(& ((exe)->__in_list)));
665 n = 0;
666 }
667 else
668 ok = 0;
669 }
670 else
671 ok = 0;
672 }
673
674 if (!ok)
675 { /* Something went wrong, so pull down everything. */
676 if (exe->pid) ecore_exe_terminate(exe);
677 IF_FN_DEL(ecore_exe_free, exe)if (exe) { ecore_exe_free(exe); exe = ((void*)0); };
678 }
679 else
680 {
681 Ecore_Exe_Event_Add *e;
682
683 e = _ecore_exe_event_add_new();
684 e->exe = exe;
685 if (e) /* Send the event. */
686 ecore_event_add(ECORE_EXE_EVENT_ADD, e,
687 _ecore_exe_event_add_free, NULL((void*)0));
688 /* INF("Running as %d for %s.\n", exe->pid, exe->cmd); */
689 }
690
691 errno(*__errno_location ()) = n;
692 return exe;
693}
694
695/**
696 * Defines a function to be called before really freeing the handle data.
697 *
698 * This might be useful for language bindings such as Python and Perl
699 * that need to deallocate wrappers associated with this handle.
700 *
701 * This handle should never be modified by this call. It should be
702 * considered informative only. All getters are valid when the given
703 * function is called back.
704 *
705 * @param exe The child process to attach the pre_free function.
706 * @param func The function to call before @a exe is freed.
707 */
708EAPI__attribute__ ((visibility("default"))) void
709ecore_exe_callback_pre_free_set(Ecore_Exe *exe, Ecore_Exe_Cb func)
710{
711 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
712 {
713 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE,_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_callback_pre_free_set"));
714 "ecore_exe_callback_pre_free_set")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_callback_pre_free_set"));
;
715 return;
716 }
717 exe->pre_free_cb = func;
718}
719
720/**
721 * Sends data to the given child process which it receives on stdin.
722 *
723 * This function writes to a child processes standard in, with unlimited
724 * buffering. This call will never block. It may fail if the system runs out
725 * of memory.
726 *
727 * @param exe The child process to send to
728 * @param data The data to send
729 * @param size The size of the data to send, in bytes
730 * @return EINA_TRUE if successful, EINA_FALSE on failure.
731 * @ingroup Ecore_Exe_Basic_Group
732 */
733EAPI__attribute__ ((visibility("default"))) Eina_Bool
734ecore_exe_send(Ecore_Exe * exe, const void *data, int size)
735{
736 void *buf;
737
738 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
739 {
740 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_send")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_send"));
;
741 return EINA_FALSE((Eina_Bool)0);
742 }
743
744 if (exe->close_stdin)
745 {
746 ERR("Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p",eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 747, "Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p"
, exe, size, data)
747 exe, size, data)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 747, "Ecore_Exe %p stdin is closed! Cannot send %d bytes from %p"
, exe, size, data)
;
748 return EINA_FALSE((Eina_Bool)0);
749 }
750
751 if (exe->child_fd_write == -1)
752 {
753 ERR("Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! "eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 754, "Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! "
"Cannot send %d bytes from %p", exe, size, data)
754 "Cannot send %d bytes from %p", exe, size, data)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 754, "Ecore_Exe %p created without ECORE_EXE_PIPE_WRITE! "
"Cannot send %d bytes from %p", exe, size, data)
;
755 return EINA_FALSE((Eina_Bool)0);
756 }
757
758 buf = realloc(exe->write_data_buf, exe->write_data_size + size);
759 if (!buf) return EINA_FALSE((Eina_Bool)0);
760
761 exe->write_data_buf = buf;
762 memcpy((char *)exe->write_data_buf + exe->write_data_size, data, size);
763 exe->write_data_size += size;
764
765 if (exe->write_fd_handler)
766 ecore_main_fd_handler_active_set(exe->write_fd_handler, ECORE_FD_WRITE);
767
768 return EINA_TRUE((Eina_Bool)1);
769}
770
771/**
772 * The stdin of the given child process will close when the write buffer is empty.
773 *
774 * @param exe The child process
775 * @ingroup Ecore_Exe_Basic_Group
776 */
777EAPI__attribute__ ((visibility("default"))) void
778ecore_exe_close_stdin(Ecore_Exe *exe)
779{
780 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
781 {
782 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_close_stdin")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_close_stdin"));
;
783 return;
784 }
785 exe->close_stdin = 1;
786}
787
788/**
789 * Sets the auto pipe limits for the given process handle. On Windows
790 * this function does nothing.
791 *
792 * @param exe The given process handle.
793 * @param start_bytes limit of bytes at start of output to buffer.
794 * @param end_bytes limit of bytes at end of output to buffer.
795 * @param start_lines limit of lines at start of output to buffer.
796 * @param end_lines limit of lines at end of output to buffer.
797 * @ingroup Ecore_Exe_Basic_Group
798 */
799EAPI__attribute__ ((visibility("default"))) void
800ecore_exe_auto_limits_set(Ecore_Exe *exe, int start_bytes, int end_bytes, int start_lines, int end_lines)
801{
802 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
803 {
804 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_auto_limits_set")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_auto_limits_set"));
;
805 return;
806 }
807 /* FIXME: sanitize the input. */
808 exe->start_bytes = start_bytes;
809 exe->end_bytes = end_bytes;
810 exe->start_lines = start_lines;
811 exe->end_lines = end_lines;
812
813 /* FIXME: get this can of worms working.
814 *
815 * capture stderr & stdout internally
816 *
817 * raster and onefang keep moving the goal posts on this one. It started out as
818 * "show users the error output if an exe fails" and is rapidly approaching
819 * "alternative method of getting the data, poll vs event driven". Some serious
820 * thinking needs to be applied to this. Do we really want to go that far? If
821 * so, we should change the names. The basic design will probably remain the
822 * same which ever way we go. The constant goal post moving is probably due to
823 * generic design methods leading to feature creep as we inspired each other to
824 * more generic designs. It does seem like the closer we get to poll driven,
825 * the more issues and corner cases there are.
826 *
827 * Instead of doing the usual register an event handler thing, we are ecore_exe,
828 * we can take some short cuts. Don't send the events, just leave the exe buffers
829 * as is until the user asks for them, then return the event.
830 *
831 * start = 0, end = 0; clogged arteries get flushed, everything is ignored.
832 * start = -1, end = -1; clogged arteries get transferred to internal buffers. Actually, either == -1 means buffer everything.
833 * start = X, end = 0; buffer first X out of clogged arteries, flush and ignore rest.
834 * start = 0, end = X; circular buffer X
835 * start = X, end = Y; buffer first X out of clogged arteries, circular buffer Y from beginning.
836 *
837 * bytes vs lines, which ever one reaches the limit first.
838 * Before we go beyond the start+end limit, leave the end buffer empty, and store both in the start buffer, coz they overlap.
839 * After we pass the the start+end limit, insert "\n...\n" at the end of the start buffer, copy the rest to the end buffer, then store in the end buffer.
840 *
841 * Other issues -
842 * Spank programmer for polling data if polling is not turned on.
843 * Spank programmer for setting up event callbacks if polling is turned on.
844 * Spank programmer for freeing the event data if it came from the event system, as that autofrees.
845 * Spank the programmer if they try to set the limits bigger than what has been gathered & ignored already, coz they just lost data.
846 * Spank onefang and raster for opening this can of worms.
847 * Should we have separate out/err limits?
848 * Should we remove from the internal buffer the data that was delivered already?
849 * If so, what to do about limits, start, and end? They could loose their meaning.
850 */
851}
852
853/**
854 * Gets the auto pipe data for the given process handle
855 *
856 * @param exe The given process handle.
857 * @param flags Is this a ECORE_EXE_PIPE_READ or ECORE_EXE_PIPE_ERROR?
858 * @ingroup Ecore_Exe_Basic_Group
859 */
860EAPI__attribute__ ((visibility("default"))) Ecore_Exe_Event_Data *
861ecore_exe_event_data_get(Ecore_Exe *exe, Ecore_Exe_Flags flags)
862{
863 Ecore_Exe_Event_Data *e = NULL((void*)0);
864 int is_buffered = 0;
865 unsigned char *inbuf;
866 int inbuf_num;
867
868 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
869 {
870 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_event_data_get")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_event_data_get"));
;
871 return NULL((void*)0);
872 }
873
874 /* Sort out what sort of event we are. */
875 if (flags & ECORE_EXE_PIPE_READ)
876 {
877 flags = ECORE_EXE_PIPE_READ;
878 if (exe->flags & ECORE_EXE_PIPE_READ_LINE_BUFFERED)
879 is_buffered = 1;
880 }
881 else
882 {
883 flags = ECORE_EXE_PIPE_ERROR;
884 if (exe->flags & ECORE_EXE_PIPE_ERROR_LINE_BUFFERED)
885 is_buffered = 1;
886 }
887
888 /* Get the data. */
889 if (flags & ECORE_EXE_PIPE_READ)
890 {
891 inbuf = exe->read_data_buf;
892 inbuf_num = exe->read_data_size;
893 exe->read_data_buf = NULL((void*)0);
894 exe->read_data_size = 0;
895 }
896 else
897 {
898 inbuf = exe->error_data_buf;
899 inbuf_num = exe->error_data_size;
900 exe->error_data_buf = NULL((void*)0);
901 exe->error_data_size = 0;
902 }
903
904 e = calloc(1, sizeof(Ecore_Exe_Event_Data));
905 if (e)
906 {
907 e->exe = exe;
908 e->data = inbuf;
909 e->size = inbuf_num;
910
911 if (is_buffered)
912 { /* Deal with line buffering. */
913 int max = 0;
914 int count = 0;
915 int i;
916 int last = 0;
917 char *c;
918
919 c = (char *)inbuf;
920 for (i = 0; i < inbuf_num; i++) /* Find the lines. */
921 {
922 if (inbuf[i] == '\n')
923 {
924 if (count >= max)
925 {
926 /* In testing, the lines seem to arrive in batches of 500 to 1000 lines at most, roughly speaking. */
927 max += 10; /* FIXME: Maybe keep track of the largest number of lines ever sent, and add half that many instead of 10. */
928 e->lines = realloc(e->lines, sizeof(Ecore_Exe_Event_Data_Line) * (max + 1)); /* Allow room for the NULL termination. */
929 }
930 /* raster said to leave the line endings as line endings, however -
931 * This is line buffered mode, we are not dealing with binary here, but lines.
932 * If we are not dealing with binary, we must be dealing with ASCII, unicode, or some other text format.
933 * Thus the user is most likely gonna deal with this text as strings.
934 * Thus the user is most likely gonna pass this data to str functions.
935 * rasters way - the endings are always gonna be '\n'; onefangs way - they will always be '\0'
936 * We are handing them the string length as a convenience.
937 * Thus if they really want it in raw format, they can e->lines[i].line[e->lines[i].size - 1] = '\n'; easily enough.
938 * In the default case, we can do this conversion quicker than the user can, as we already have the index and pointer.
939 * Let's make it easy on them to use these as standard C strings.
940 *
941 * onefang is proud to announce that he has just set a new personal record for the
942 * most over documentation of a simple assignment statement. B-)
943 */
944 inbuf[i] = '\0';
945 e->lines[count].line = c;
946 e->lines[count].size = i - last;
947 last = i + 1;
948 c = (char *)&inbuf[last];
949 count++;
950 }
951 }
952 if (count == 0) /* No lines to send, cancel the event. */
953 {
954 _ecore_exe_event_exe_data_free(NULL((void*)0), e);
955 e = NULL((void*)0);
956 }
957 else /* NULL terminate the array, so that people know where the end is. */
958 {
959 e->lines[count].line = NULL((void*)0);
960 e->lines[count].size = 0;
961 }
962 if (i > last) /* Partial line left over, save it for next time. */
963 {
964 if (e) e->size = last;
965 if (flags & ECORE_EXE_PIPE_READ)
966 {
967 exe->read_data_size = i - last;
968 exe->read_data_buf = malloc(exe->read_data_size);
969 memcpy(exe->read_data_buf, c, exe->read_data_size);
970 }
971 else
972 {
973 exe->error_data_size = i - last;
974 exe->error_data_buf = malloc(exe->error_data_size);
975 memcpy(exe->error_data_buf, c, exe->error_data_size);
976 }
977 }
978 }
979 }
980
981 return e;
982}
983
984/**
985 * Sets the string tag for the given process handle
986 *
987 * @param exe The given process handle.
988 * @param tag The string tag to set on the process handle.
989 * @ingroup Ecore_Exe_Basic_Group
990 */
991EAPI__attribute__ ((visibility("default"))) void
992ecore_exe_tag_set(Ecore_Exe *exe, const char *tag)
993{
994 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
995 {
996 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_set")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_tag_set"));
;
997 return;
998 }
999 IF_FREE(exe->tag)if (exe->tag) free(exe->tag); exe->tag = ((void*)0);;
1000 if (tag)
1001 exe->tag = strdup(tag);
1002 else
1003 exe->tag = NULL((void*)0);
1004}
1005
1006/**
1007 * Retrieves the tag attached to the given process handle. There is no need to
1008 * free it as it just returns the internal pointer value. This value is only
1009 * valid as long as the @p exe is valid or until the tag is set to something
1010 * else on this @p exe.
1011 *
1012 * @param exe The given process handle.
1013 * @return The string attached to @p exe. It is a handle to existing
1014 * internal string and should not be modified, use
1015 * ecore_exe_tag_set() to change it. It might be @c NULL.
1016 * @ingroup Ecore_Exe_Basic_Group
1017 */
1018EAPI__attribute__ ((visibility("default"))) const char *
1019ecore_exe_tag_get(const Ecore_Exe *exe)
1020{
1021 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1022 {
1023 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_tag_get")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_tag_get"));
;
1024 return NULL((void*)0);
1025 }
1026 return exe->tag;
1027}
1028
1029/**
1030 * Frees the given process handle.
1031 *
1032 * Note that the process that the handle represents is unaffected by this
1033 * function.
1034 *
1035 * @param exe The given process handle.
1036 * @return The data attached to the handle when @ref ecore_exe_run was
1037 * called.
1038 * @ingroup Ecore_Exe_Basic_Group
1039 */
1040EAPI__attribute__ ((visibility("default"))) void *
1041ecore_exe_free(Ecore_Exe *exe)
1042{
1043 void *data;
1044 int ok = 0;
1045 int result;
1046
1047 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1048 {
1049 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_free")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_free"));
;
1050 return NULL((void*)0);
1051 }
1052
1053 data = exe->data;
1054
1055 if (exe->pre_free_cb)
1056 exe->pre_free_cb(data, exe);
1057
1058 if (exe->doomsday_clock)
1059 {
1060 struct _ecore_exe_dead_exe *dead;
1061
1062 ecore_timer_del(exe->doomsday_clock);
1063 exe->doomsday_clock = NULL((void*)0);
1064 dead = exe->doomsday_clock_dead;
1065 if (dead)
1066 {
1067 IF_FREE(dead->cmd)if (dead->cmd) free(dead->cmd); dead->cmd = ((void*)
0);
;
1068 free(dead);
1069 exe->doomsday_clock_dead = NULL((void*)0);
1070 }
1071 }
1072 IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler)if (exe->write_fd_handler) { ecore_main_fd_handler_del(exe
->write_fd_handler); exe->write_fd_handler = ((void*)0)
; }
;
1073 IF_FN_DEL(ecore_main_fd_handler_del, exe->read_fd_handler)if (exe->read_fd_handler) { ecore_main_fd_handler_del(exe->
read_fd_handler); exe->read_fd_handler = ((void*)0); }
;
1074 IF_FN_DEL(ecore_main_fd_handler_del, exe->error_fd_handler)if (exe->error_fd_handler) { ecore_main_fd_handler_del(exe
->error_fd_handler); exe->error_fd_handler = ((void*)0)
; }
;
1075 if (exe->child_fd_write_x != -1)
1076 E_NO_ERRNO(result, close(exe->child_fd_write_x), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(exe->
child_fd_write_x)), "ecore/src/lib/ecore_exe.c", 1076)) == -1
) sleep(1)
;
1077 if (exe->child_fd_read_x != -1)
1078 E_NO_ERRNO(result, close(exe->child_fd_read_x), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(exe->
child_fd_read_x)), "ecore/src/lib/ecore_exe.c", 1078)) == -1)
sleep(1)
;
1079 if (exe->child_fd_error_x != -1)
1080 E_NO_ERRNO(result, close(exe->child_fd_error_x), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(exe->
child_fd_error_x)), "ecore/src/lib/ecore_exe.c", 1080)) == -1
) sleep(1)
;
1081 if (exe->child_fd_write != -1)
1082 E_NO_ERRNO(result, close(exe->child_fd_write), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(exe->
child_fd_write)), "ecore/src/lib/ecore_exe.c", 1082)) == -1) sleep
(1)
;
1083 if (exe->child_fd_read != -1)
1084 E_NO_ERRNO(result, close(exe->child_fd_read), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(exe->
child_fd_read)), "ecore/src/lib/ecore_exe.c", 1084)) == -1) sleep
(1)
;
1085 if (exe->child_fd_error != -1)
1086 E_NO_ERRNO(result, close(exe->child_fd_error), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(exe->
child_fd_error)), "ecore/src/lib/ecore_exe.c", 1086)) == -1) sleep
(1)
;
1087 IF_FREE(exe->write_data_buf)if (exe->write_data_buf) free(exe->write_data_buf); exe
->write_data_buf = ((void*)0);
;
1088 IF_FREE(exe->read_data_buf)if (exe->read_data_buf) free(exe->read_data_buf); exe->
read_data_buf = ((void*)0);
;
1089 IF_FREE(exe->error_data_buf)if (exe->error_data_buf) free(exe->error_data_buf); exe
->error_data_buf = ((void*)0);
;
1090 IF_FREE(exe->cmd)if (exe->cmd) free(exe->cmd); exe->cmd = ((void*)0);;
1091
1092 exes = (Ecore_Exe *) eina_inlist_remove(EINA_INLIST_GET(exes)(& ((exes)->__in_list)), EINA_INLIST_GET(exe)(& ((exe)->__in_list)));
1093 ECORE_MAGIC_SET(exe, ECORE_MAGIC_NONE)(exe)->__magic = (0x1234fedc);
1094 IF_FREE(exe->tag)if (exe->tag) free(exe->tag); exe->tag = ((void*)0);;
1095 free(exe);
1096 return data;
1097}
1098
1099/**
1100 * Frees the given event data.
1101 *
1102 * @param e The given event data.
1103 * @ingroup Ecore_Exe_Basic_Group
1104 */
1105EAPI__attribute__ ((visibility("default"))) void
1106ecore_exe_event_data_free(Ecore_Exe_Event_Data *e)
1107{
1108 if (!e) return;
1109 IF_FREE(e->lines)if (e->lines) free(e->lines); e->lines = ((void*)0);;
1110 IF_FREE(e->data)if (e->data) free(e->data); e->data = ((void*)0);;
1111 free(e);
1112}
1113
1114/**
1115 * Retrieves the process ID of the given spawned process.
1116 * @param exe Handle to the given spawned process.
1117 * @return The process ID on success. @c -1 otherwise.
1118 * @ingroup Ecore_Exe_Basic_Group
1119 */
1120EAPI__attribute__ ((visibility("default"))) pid_t
1121ecore_exe_pid_get(const Ecore_Exe *exe)
1122{
1123 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1124 {
1125 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pid_get")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_pid_get"));
;
1126 return -1;
1127 }
1128 return exe->pid;
1129}
1130
1131/**
1132 * Retrieves the command of the given spawned process.
1133 * @param exe Handle to the given spawned process.
1134 * @return The command on success. NULL otherwise. This string is the
1135 * pointer to the internal value and must not be modified in
1136 * any way.
1137 * @ingroup Ecore_Exe_Basic_Group
1138 */
1139EAPI__attribute__ ((visibility("default"))) const char *
1140ecore_exe_cmd_get(const Ecore_Exe *exe)
1141{
1142 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1143 {
1144 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_cmd_get")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_cmd_get"));
;
1145 return NULL((void*)0);
1146 }
1147 return exe->cmd;
1148}
1149
1150/**
1151 * Retrieves the data attached to the given process handle.
1152 * @param exe The given process handle.
1153 * @return The data pointer attached to @p exe Given to
1154 * ecore_exe_run() or ecore_exe_pipe_run()
1155 * @ingroup Ecore_Exe_Basic_Group
1156 */
1157EAPI__attribute__ ((visibility("default"))) void *
1158ecore_exe_data_get(const Ecore_Exe *exe)
1159{
1160 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1161 {
1162 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_data_get"));
;
1163 return NULL((void*)0);
1164 }
1165 return exe->data;
1166}
1167
1168/**
1169 * Retrieves the flags attached to the given process handle.
1170 * @param exe The given process handle.
1171 * @return The flags attached to @p exe.
1172 * @ingroup Ecore_Exe_Basic_Group
1173 */
1174EAPI__attribute__ ((visibility("default"))) Ecore_Exe_Flags
1175ecore_exe_flags_get(const Ecore_Exe *exe)
1176{
1177 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1178 {
1179 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_data_get")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_data_get"));
;
1180 return 0;
1181 }
1182 return exe->flags;
1183}
1184
1185/**
1186 * @defgroup Ecore_Exe_Signal_Group Spawned Process Signal Functions
1187 *
1188 * Functions that send signals to spawned processes.
1189 */
1190
1191/**
1192 * Pauses the given process by sending it a @c SIGSTOP signal.
1193 * @param exe Process handle to the given process.
1194 * @ingroup Ecore_Exe_Signal_Group
1195 */
1196EAPI__attribute__ ((visibility("default"))) void
1197ecore_exe_pause(Ecore_Exe *exe)
1198{
1199 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1200 {
1201 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_pause")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_pause"));
;
1202 return;
1203 }
1204 kill(exe->pid, SIGSTOP19);
1205}
1206
1207/**
1208 * Continues the given paused process by sending it a @c SIGCONT signal.
1209 * @param exe Process handle to the given process.
1210 * @ingroup Ecore_Exe_Signal_Group
1211 */
1212EAPI__attribute__ ((visibility("default"))) void
1213ecore_exe_continue(Ecore_Exe *exe)
1214{
1215 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1216 {
1217 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_continue")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_continue"));
;
1218 return;
1219 }
1220 kill(exe->pid, SIGCONT18);
1221}
1222
1223/**
1224 * Sends the given spawned process a interrupt (@c SIGINT) signal.
1225 * @param exe Process handle to the given process.
1226 * @ingroup Ecore_Exe_Signal_Group
1227 */
1228EAPI__attribute__ ((visibility("default"))) void
1229ecore_exe_interrupt(Ecore_Exe *exe)
1230{
1231 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1232 {
1233 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_interrupt")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_interrupt"));
;
1234 return;
1235 }
1236 _ecore_exe_dead_attach(exe);
1237 kill(exe->pid, SIGINT2);
1238}
1239
1240/**
1241 * Sends the given spawned process a quit (@c SIGQUIT) signal.
1242 * @param exe Process handle to the given process.
1243 * @ingroup Ecore_Exe_Signal_Group
1244 */
1245EAPI__attribute__ ((visibility("default"))) void
1246ecore_exe_quit(Ecore_Exe *exe)
1247{
1248 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1249 {
1250 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_quit")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_quit"));
;
1251 return;
1252 }
1253 _ecore_exe_dead_attach(exe);
1254 kill(exe->pid, SIGQUIT3);
1255}
1256
1257/**
1258 * Sends the given spawned process a terminate (@c SIGTERM) signal.
1259 * @param exe Process handle to the given process.
1260 * @ingroup Ecore_Exe_Signal_Group
1261 */
1262EAPI__attribute__ ((visibility("default"))) void
1263ecore_exe_terminate(Ecore_Exe *exe)
1264{
1265 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1266 {
1267 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_terminate")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_terminate"));
;
1268 return;
1269 }
1270 _ecore_exe_dead_attach(exe);
1271 INF("Sending TERM signal to %s (%d).", exe->cmd, exe->pid)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1271, "Sending TERM signal to %s (%d).", exe->
cmd, exe->pid)
;
1272 kill(exe->pid, SIGTERM15);
1273}
1274
1275/**
1276 * Kills the given spawned process by sending it a @c SIGKILL signal.
1277 * @param exe Process handle to the given process.
1278 * @ingroup Ecore_Exe_Signal_Group
1279 */
1280EAPI__attribute__ ((visibility("default"))) void
1281ecore_exe_kill(Ecore_Exe *exe)
1282{
1283 struct _ecore_exe_dead_exe *dead;
1284
1285 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1286 {
1287 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_kill")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_kill"));
;
1288 return;
1289 }
1290
1291 dead = calloc(1, sizeof(struct _ecore_exe_dead_exe));
1292 if (dead)
1293 {
1294 dead->pid = exe->pid;
1295 dead->cmd = strdup(exe->cmd);
1296 IF_FN_DEL(ecore_timer_del, exe->doomsday_clock)if (exe->doomsday_clock) { ecore_timer_del(exe->doomsday_clock
); exe->doomsday_clock = ((void*)0); }
;
1297 exe->doomsday_clock =
1298 ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead, dead);
1299 }
1300
1301 INF("Sending KILL signal to %s (%d).", exe->cmd, exe->pid)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1301, "Sending KILL signal to %s (%d).", exe->
cmd, exe->pid)
;
1302 kill(exe->pid, SIGKILL9);
1303}
1304
1305/**
1306 * Sends a @c SIGUSR signal to the given spawned process.
1307 * @param exe Process handle to the given process.
1308 * @param num The number user signal to send. Must be either 1 or 2, or
1309 * the signal will be ignored.
1310 * @ingroup Ecore_Exe_Signal_Group
1311 */
1312EAPI__attribute__ ((visibility("default"))) void
1313ecore_exe_signal(Ecore_Exe *exe, int num)
1314{
1315 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1316 {
1317 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_signal")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_signal"));
;
1318 return;
1319 }
1320 if (num == 1)
1321 kill(exe->pid, SIGUSR110);
1322 else if (num == 2)
1323 kill(exe->pid, SIGUSR212);
1324}
1325
1326/**
1327 * Sends a @c SIGHUP signal to the given spawned process.
1328 * @param exe Process handle to the given process.
1329 * @ingroup Ecore_Exe_Signal_Group
1330 */
1331EAPI__attribute__ ((visibility("default"))) void
1332ecore_exe_hup(Ecore_Exe *exe)
1333{
1334 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1335 {
1336 ECORE_MAGIC_FAIL(exe, ECORE_MAGIC_EXE, "ecore_exe_hup")_ecore_magic_fail((exe), (exe) ? (exe)->__magic : 0, (0xf7e812f5
), ("ecore_exe_hup"));
;
1337 return;
1338 }
1339 kill(exe->pid, SIGHUP1);
1340}
1341
1342static Ecore_Exe *
1343_ecore_exe_is_it_alive(pid_t pid)
1344{
1345 Ecore_Exe *exe = NULL((void*)0);
1346
1347 /* FIXME: There is no nice, safe, OS independent way to tell if a
1348 * particular PID is still alive. I have written code to do so
1349 * for my urunlevel busybox applet (http://urunlevel.sourceforge.net/),
1350 * but it's for linux only, and still not guaranteed.
1351 *
1352 * So for now, we just check that a valid Ecore_Exe structure
1353 * exists for it. Even that is not a guarantee, as the structure
1354 * can be freed without killing the process.
1355 *
1356 * I think we can safely put exe's into two categories, those users
1357 * that care about the life of the exe, and the run and forget type.
1358 * The run and forget type starts up the exe, then free's the
1359 * Ecore_Exe structure straight away. They can never call any of
1360 * the functions that can call this, so we don't worry about them.
1361 *
1362 * Those user's that care about the life of exe's will keep the
1363 * Ecore_Exe structure around, terminate them eventually, or
1364 * register for exit events. For these ones the assumption
1365 * that valid Ecore_Exe struct == live exe is almost valid.
1366 *
1367 * I will probably copy my urunlevel code into here someday.
1368 */
1369 exe = _ecore_exe_find(pid);
1370 if (exe)
1371 {
1372 if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)((exe) && ((exe)->__magic == (0xf7e812f5))))
1373 exe = NULL((void*)0);
1374 }
1375
1376 return exe;
1377}
1378
1379static Eina_Bool
1380_ecore_exe_make_sure_its_dead(void *data)
1381{
1382 struct _ecore_exe_dead_exe *dead;
1383
1384 dead = data;
1385 if (dead)
1386 {
1387 Ecore_Exe *exe = NULL((void*)0);
1388
1389 if ((exe = _ecore_exe_is_it_alive(dead->pid)))
1390 {
1391 if (dead->cmd)
1392 INF("Sending KILL signal to allegedly dead %s (%d).",eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1393, "Sending KILL signal to allegedly dead %s (%d)."
, dead->cmd, dead->pid)
1393 dead->cmd, dead->pid)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1393, "Sending KILL signal to allegedly dead %s (%d)."
, dead->cmd, dead->pid)
;
1394 else
1395 INF("Sending KILL signal to allegedly dead PID %d.",eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1396, "Sending KILL signal to allegedly dead PID %d."
, dead->pid)
1396 dead->pid)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1396, "Sending KILL signal to allegedly dead PID %d."
, dead->pid)
;
1397 exe->doomsday_clock =
1398 ecore_timer_add(10.0, _ecore_exe_make_sure_its_really_dead,
1399 dead);
1400 kill(dead->pid, SIGKILL9);
1401 }
1402 else
1403 {
1404 IF_FREE(dead->cmd)if (dead->cmd) free(dead->cmd); dead->cmd = ((void*)
0);
;
1405 free(dead);
1406 }
1407 }
1408 return ECORE_CALLBACK_CANCEL((Eina_Bool)0);
1409}
1410
1411static Eina_Bool
1412_ecore_exe_make_sure_its_really_dead(void *data)
1413{
1414 struct _ecore_exe_dead_exe *dead;
1415
1416 dead = data;
1417 if (dead)
1418 {
1419 Ecore_Exe *exe = NULL((void*)0);
1420
1421 if ((exe = _ecore_exe_is_it_alive(dead->pid)))
1422 {
1423 ERR("RUN! The zombie wants to eat your brains! And your CPU!")eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_ERR, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1423, "RUN! The zombie wants to eat your brains! And your CPU!"
)
;
1424 if (dead->cmd)
1425 INF("%s (%d) is not really dead.", dead->cmd, dead->pid)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1425, "%s (%d) is not really dead.", dead->
cmd, dead->pid)
;
1426 else
1427 INF("PID %d is not really dead.", dead->pid)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1427, "PID %d is not really dead.", dead->
pid)
;
1428 exe->doomsday_clock = NULL((void*)0);
1429 }
1430 IF_FREE(dead->cmd)if (dead->cmd) free(dead->cmd); dead->cmd = ((void*)
0);
;
1431 free(dead);
1432 }
1433 return ECORE_CALLBACK_CANCEL((Eina_Bool)0);
1434}
1435
1436void
1437_ecore_exe_init(void)
1438{
1439 ECORE_EXE_EVENT_ADD = ecore_event_type_new();
1440 ECORE_EXE_EVENT_DEL = ecore_event_type_new();
1441 ECORE_EXE_EVENT_DATA = ecore_event_type_new();
1442 ECORE_EXE_EVENT_ERROR = ecore_event_type_new();
1443}
1444
1445void
1446_ecore_exe_shutdown(void)
1447{
1448 while (exes)
1449 ecore_exe_free(exes);
1450}
1451
1452Ecore_Exe *
1453_ecore_exe_find(pid_t pid)
1454{
1455 Ecore_Exe *exe;
1456
1457 EINA_INLIST_FOREACH(exes, exe)for (exe = ((void*)0), exe = (exes ? (void *)((char *)(exes) -
((char *)&(exe)->__in_list - (char *)(exe))) : ((void
*)0)); exe; exe = ((& ((exe)->__in_list))->next ? (
void *)((char *)((& ((exe)->__in_list))->next) - ((
char *)&(exe)->__in_list - (char *)(exe))) : ((void*)0
)))
1458 {
1459 if (exe->pid == pid)
1460 return exe;
1461 }
1462 return NULL((void*)0);
1463}
1464
1465Ecore_Timer *
1466_ecore_exe_doomsday_clock_get(Ecore_Exe *exe)
1467{
1468 return exe->doomsday_clock;
1469}
1470
1471void
1472_ecore_exe_doomsday_clock_set(Ecore_Exe *exe, Ecore_Timer *dc)
1473{
1474 exe->doomsday_clock = dc;
1475}
1476
1477static inline void
1478_ecore_exe_exec_it(const char *exe_cmd, Ecore_Exe_Flags flags)
1479{
1480 char use_sh = 1;
1481 char *buf = NULL((void*)0);
1482 char **args = NULL((void*)0);
1483 int save_errno = 0;
1484
1485 /* So what is this doing?
1486 *
1487 * We are trying to avoid wrapping the exe call with /bin/sh -c.
1488 * We conservatively search for certain shell meta characters,
1489 * If we don't find them, we can call the exe directly.
1490 */
1491 if (!strpbrk(exe_cmd, "|&;<>()$`\\\"'*?#"))
1492 {
1493 char *token;
1494 char pre_command = 1;
1495 int num_tokens = 0;
1496
1497 if (!(buf = strdup(exe_cmd)))
1498 return;
1499
1500 token = strtok(buf, " \t\n\v");
1501 while (token)
1502 {
1503 if (token[0] == '~')
1504 break;
1505 if (pre_command)
1506 {
1507 if (token[0] == '[')
1508 break;
1509 if (strchr(token, '='))
1510 break;
1511 else
1512 pre_command = 0;
1513 }
1514 num_tokens++;
1515 token = strtok(NULL((void*)0), " \t\n\v");
1516 }
1517 IF_FREE(buf)if (buf) free(buf); buf = ((void*)0);;
1518 if ((!token) && (num_tokens))
1519 {
1520 int i = 0;
1521
1522 if (!(buf = strdup(exe_cmd)))
1523 return;
1524
1525 token = strtok(buf, " \t\n\v");
1526 use_sh = 0;
1527 if (!(args = (char **)calloc(num_tokens + 1, sizeof(char *))))
1528 {
1529 IF_FREE(buf)if (buf) free(buf); buf = ((void*)0);;
1530 return;
1531 }
1532 for (i = 0; i < num_tokens; i++)
1533 {
1534 if (token)
1535 args[i] = token;
1536 token = strtok(NULL((void*)0), " \t\n\v");
1537 }
1538 args[num_tokens] = NULL((void*)0);
1539 }
1540 }
1541
1542 if (!(flags & ECORE_EXE_NOT_LEADER)) setsid();
1543 if ((flags & ECORE_EXE_USE_SH))
1544 {
1545 errno(*__errno_location ()) = 0;
1546 execl("/bin/sh", "/bin/sh", "-c", exe_cmd, (char *)NULL((void*)0));
1547 }
1548 else if (use_sh)
1549 { /* We have to use a shell to run this. */
1550 if (!shell)
1551 { /* Find users preferred shell. */
1552 shell = getenv("SHELL");
1553 if (!shell)
1554 shell = "/bin/sh";
1555 }
1556 errno(*__errno_location ()) = 0;
1557 execl(shell, shell, "-c", exe_cmd, (char *)NULL((void*)0));
1558 }
1559 else
1560 { /* We can run this directly. */
1561 errno(*__errno_location ()) = 0;
1562 execvp(args[0], args);
1563 }
1564
1565 save_errno = errno(*__errno_location ());
1566 IF_FREE(buf)if (buf) free(buf); buf = ((void*)0);;
1567 IF_FREE(args)if (args) free(args); args = ((void*)0);;
1568 errno(*__errno_location ()) = save_errno;
1569 return;
1570}
1571
1572static Eina_Bool
1573_ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_Exe_Flags flags)
1574{
1575 Ecore_Exe *exe;
1576 int child_fd;
1577 int event_type;
1578
1579 exe = data;
1580
1581 /* Sort out what sort of handler we are. */
1582 if (flags & ECORE_EXE_PIPE_READ)
1583 {
1584 flags = ECORE_EXE_PIPE_READ;
1585 event_type = ECORE_EXE_EVENT_DATA;
1586 child_fd = exe->child_fd_read;
1587 }
1588 else
1589 {
1590 flags = ECORE_EXE_PIPE_ERROR;
1591 event_type = ECORE_EXE_EVENT_ERROR;
1592 child_fd = exe->child_fd_error;
1593 }
1594
1595 if ((fd_handler)
1596 && (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)))
1597 {
1598 unsigned char *inbuf;
1599 int inbuf_num;
1600
1601 /* Get any left over data from last time. */
1602 if (flags & ECORE_EXE_PIPE_READ)
1603 {
1604 inbuf = exe->read_data_buf;
1605 inbuf_num = exe->read_data_size;
1606 exe->read_data_buf = NULL((void*)0);
1607 exe->read_data_size = 0;
1608 }
1609 else
1610 {
1611 inbuf = exe->error_data_buf;
1612 inbuf_num = exe->error_data_size;
1613 exe->error_data_buf = NULL((void*)0);
1614 exe->error_data_size = 0;
1615 }
1616
1617 for (;;)
1618 {
1619 int num, lost_exe;
1620 char buf[READBUFSIZ65536];
1621
1622 lost_exe = 0;
1623 errno(*__errno_location ()) = 0;
1624 if ((num = read(child_fd, buf, READBUFSIZ65536)) < 1)
1625 /* FIXME: SPEED/SIZE TRADE OFF - add a smaller READBUFSIZE
1626 * (currently 64k) to inbuf, use that instead of buf, and
1627 * save ourselves a memcpy(). */
1628 {
1629 lost_exe = ((errno(*__errno_location ()) == EIO5) ||
1630 (errno(*__errno_location ()) == EBADF9) ||
1631 (errno(*__errno_location ()) == EPIPE32) ||
1632 (errno(*__errno_location ()) == EINVAL22) || (errno(*__errno_location ()) == ENOSPC28));
1633 if ((errno(*__errno_location ()) != EAGAIN11) && (errno(*__errno_location ()) != EINTR4))
1634 perror("_ecore_exe_generic_handler() read problem ");
1635 }
1636 if (num > 0)
1637 { /* data got read. */
1638 inbuf = realloc(inbuf, inbuf_num + num);
1639 memcpy(inbuf + inbuf_num, buf, num);
1640 inbuf_num += num;
1641 }
1642 else
1643 { /* No more data to read. */
1644 if (inbuf)
1645 {
1646 Ecore_Exe_Event_Data *e;
1647
1648 /* Stash the data away for later. */
1649 if (flags & ECORE_EXE_PIPE_READ)
1650 {
1651 exe->read_data_buf = inbuf;
1652 exe->read_data_size = inbuf_num;
1653 }
1654 else
1655 {
1656 exe->error_data_buf = inbuf;
1657 exe->error_data_size = inbuf_num;
1658 }
1659
1660 if (!(exe->flags & ECORE_EXE_PIPE_AUTO))
1661 {
1662 e = ecore_exe_event_data_get(exe, flags);
1663 if (e) /* Send the event. */
1664 ecore_event_add(event_type, e,
1665 _ecore_exe_event_exe_data_free,
1666 NULL((void*)0));
1667 }
1668 }
1669 if (lost_exe)
1670 {
1671 if (flags & ECORE_EXE_PIPE_READ)
1672 {
1673 if (exe->read_data_size)
1674 INF("There are %d bytes left unsent from the dead exe %s.",eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1675, "There are %d bytes left unsent from the dead exe %s."
, exe->read_data_size, exe->cmd)
1675 exe->read_data_size, exe->cmd)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1675, "There are %d bytes left unsent from the dead exe %s."
, exe->read_data_size, exe->cmd)
;
1676 }
1677 else
1678 {
1679 if (exe->error_data_size)
1680 INF("There are %d bytes left unsent from the dead exe %s.",eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1681, "There are %d bytes left unsent from the dead exe %s."
, exe->error_data_size, exe->cmd)
1681 exe->error_data_size, exe->cmd)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1681, "There are %d bytes left unsent from the dead exe %s."
, exe->error_data_size, exe->cmd)
;
1682 }
1683 /* Thought about this a bit. If the exe has actually
1684 * died, this won't do any harm as it must have died
1685 * recently and the pid has not had a chance to recycle.
1686 * It is also a paranoid catchall, coz the usual ecore_signal
1687 * mechenism should kick in. But let's give it a good
1688 * kick in the head anyway.
1689 */
1690 ecore_exe_terminate(exe);
1691 }
1692 break;
1693 }
1694 }
1695 }
1696
1697 return ECORE_CALLBACK_RENEW((Eina_Bool)1);
1698}
1699
1700static Eina_Bool
1701_ecore_exe_data_error_handler(void *data, Ecore_Fd_Handler *fd_handler)
1702{
1703 return _ecore_exe_data_generic_handler(data, fd_handler,
1704 ECORE_EXE_PIPE_ERROR);
1705}
1706
1707static Eina_Bool
1708_ecore_exe_data_read_handler(void *data, Ecore_Fd_Handler *fd_handler)
1709{
1710 return _ecore_exe_data_generic_handler(data, fd_handler,
1711 ECORE_EXE_PIPE_READ);
1712}
1713
1714static Eina_Bool
1715_ecore_exe_data_write_handler(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
1716{
1717 Ecore_Exe *exe;
1718
1719 exe = data;
1720 if ((exe->write_fd_handler) &&
1721 (ecore_main_fd_handler_active_get
1722 (exe->write_fd_handler, ECORE_FD_WRITE)))
1723 _ecore_exe_flush(exe);
1724
1725 /* If we have sent all there is to send, and we need to close the pipe, then close it. */
1726 if ((exe->close_stdin == 1)
1727 && (exe->write_data_size == exe->write_data_offset))
1728 {
1729 int ok = 0;
1730 int result;
1731
1732 INF("Closing stdin for %s", exe->cmd)eina_log_print(_ecore_log_dom, EINA_LOG_LEVEL_INFO, "ecore/src/lib/ecore_exe.c"
, __FUNCTION__, 1732, "Closing stdin for %s", exe->cmd)
;
1733 /* if (exe->child_fd_write != -1) E_NO_ERRNO(result, fsync(exe->child_fd_write), ok); This a) doesn't work, and b) isn't needed. */
1734 IF_FN_DEL(ecore_main_fd_handler_del, exe->write_fd_handler)if (exe->write_fd_handler) { ecore_main_fd_handler_del(exe
->write_fd_handler); exe->write_fd_handler = ((void*)0)
; }
;
1735 if (exe->child_fd_write != -1)
1736 E_NO_ERRNO(result, close(exe->child_fd_write), ok)while (((ok) = _ecore_exe_check_errno( (result) = (close(exe->
child_fd_write)), "ecore/src/lib/ecore_exe.c", 1736)) == -1) sleep
(1)
;
1737 exe->child_fd_write = -1;
1738 IF_FREE(exe->write_data_buf)if (exe->write_data_buf) free(exe->write_data_buf); exe
->write_data_buf = ((void*)0);
;
1739 }
1740
1741 return ECORE_CALLBACK_RENEW((Eina_Bool)1);
1742}
1743
1744static void
1745_ecore_exe_flush(Ecore_Exe *exe)
1746{
1747 int count;
1748
1749 /* check whether we need to write anything at all. */
1750 if ((exe->child_fd_write == -1) || (!exe->write_data_buf))
1751 return;
1752 if (exe->write_data_size == exe->write_data_offset)
1753 return;
1754
1755 count = write(exe->child_fd_write,
1756 (char *)exe->write_data_buf + exe->write_data_offset,
1757 exe->write_data_size - exe->write_data_offset);
1758 if (count < 1)
1759 {
1760 if (errno(*__errno_location ()) == EIO5 || errno(*__errno_location ()) == EBADF9 || errno(*__errno_location ()) == EPIPE32 || errno(*__errno_location ()) == EINVAL22 || errno(*__errno_location ()) == ENOSPC28) /* we lost our exe! */
1761 {
1762 ecore_exe_terminate(exe);
1763 if (exe->write_fd_handler)
1764 ecore_main_fd_handler_active_set(exe->write_fd_handler, 0);
1765 }
1766 }
1767 else
1768 {
1769 exe->write_data_offset += count;
1770 if (exe->write_data_offset >= exe->write_data_size)
1771 { /* Nothing left to write, clean up. */
1772 exe->write_data_size = 0;
1773 exe->write_data_offset = 0;
1774 IF_FREE(exe->write_data_buf)if (exe->write_data_buf) free(exe->write_data_buf); exe
->write_data_buf = ((void*)0);
;
1775 if (exe->write_fd_handler)
1776 ecore_main_fd_handler_active_set(exe->write_fd_handler, 0);
1777 }
1778 }
1779}
1780
1781static void
1782_ecore_exe_event_exe_data_free(void *data __UNUSED__, void *ev)
1783{
1784 Ecore_Exe_Event_Data *e;
1785
1786 e = ev;
1787 ecore_exe_event_data_free(e);
1788}
1789
1790static Ecore_Exe_Event_Add *
1791_ecore_exe_event_add_new(void)
1792{
1793 Ecore_Exe_Event_Add *e;
1794
1795 e = calloc(1, sizeof(Ecore_Exe_Event_Add));
1796 return e;
1797}
1798
1799static void
1800_ecore_exe_event_add_free(void *data __UNUSED__, void *ev)
1801{
1802 Ecore_Exe_Event_Add *e;
1803
1804 e = ev;
1805 free(e);
1806}
1807
1808void *
1809_ecore_exe_event_del_new(void)
1810{
1811 Ecore_Exe_Event_Del *e;
1812
1813 e = calloc(1, sizeof(Ecore_Exe_Event_Del));
1814 return e;
1815}
1816
1817void
1818_ecore_exe_event_del_free(void *data __UNUSED__, void *ev)
1819{
1820 Ecore_Exe_Event_Del *e;
1821
1822 e = ev;
1823 if (e->exe)
1824 ecore_exe_free(e->exe);
1825 free(e);
1826}
1827
1828static void
1829_ecore_exe_dead_attach(Ecore_Exe *exe)
1830{
1831 struct _ecore_exe_dead_exe *dead;
1832
1833 if (exe->doomsday_clock_dead) return;
1834 dead = calloc(1, sizeof(struct _ecore_exe_dead_exe));
1835 if (dead)
1836 {
1837 dead->pid = exe->pid;
1838 dead->cmd = strdup(exe->cmd);
1839 IF_FN_DEL(ecore_timer_del, exe->doomsday_clock)if (exe->doomsday_clock) { ecore_timer_del(exe->doomsday_clock
); exe->doomsday_clock = ((void*)0); }
;
1840 exe->doomsday_clock =
1841 ecore_timer_add(10.0, _ecore_exe_make_sure_its_dead, dead);
1842 exe->doomsday_clock_dead = dead;
1843 }
1844}