File: | tests/suite/ecore/src/lib/ecore_exe.c |
Location: | line 528, column 14 |
Description: | Value stored to 'vfork_exec_errno' is never read |
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 | |
85 | struct _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 | |
134 | struct _ecore_exe_dead_exe |
135 | { |
136 | pid_t pid; |
137 | char *cmd; |
138 | }; |
139 | |
140 | static inline void _ecore_exe_exec_it(const char *exe_cmd, Ecore_Exe_Flags flags); |
141 | static Eina_Bool _ecore_exe_data_generic_handler(void *data, Ecore_Fd_Handler *fd_handler, Ecore_Exe_Flags flags); |
142 | static Eina_Bool _ecore_exe_data_error_handler(void *data, Ecore_Fd_Handler *fd_handler); |
143 | static Eina_Bool _ecore_exe_data_read_handler(void *data, Ecore_Fd_Handler *fd_handler); |
144 | static Eina_Bool _ecore_exe_data_write_handler(void *data, Ecore_Fd_Handler *fd_handler); |
145 | static void _ecore_exe_flush(Ecore_Exe * exe); |
146 | static void _ecore_exe_event_exe_data_free(void *data __UNUSED__, void *ev); |
147 | static Ecore_Exe *_ecore_exe_is_it_alive(pid_t pid); |
148 | static Eina_Bool _ecore_exe_make_sure_its_dead(void *data); |
149 | static Eina_Bool _ecore_exe_make_sure_its_really_dead(void *data); |
150 | static Ecore_Exe_Event_Add *_ecore_exe_event_add_new(void); |
151 | static void _ecore_exe_event_add_free(void *data, void *ev); |
152 | static void _ecore_exe_dead_attach(Ecore_Exe *exe); |
153 | |
154 | EAPI__attribute__ ((visibility("default"))) int ECORE_EXE_EVENT_ADD = 0; |
155 | EAPI__attribute__ ((visibility("default"))) int ECORE_EXE_EVENT_DEL = 0; |
156 | EAPI__attribute__ ((visibility("default"))) int ECORE_EXE_EVENT_DATA = 0; |
157 | EAPI__attribute__ ((visibility("default"))) int ECORE_EXE_EVENT_ERROR = 0; |
158 | |
159 | static Ecore_Exe *exes = NULL((void*)0); |
160 | static 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 | */ |
165 | static 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 | |
177 | static 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 | |
306 | static 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 | */ |
325 | EAPI__attribute__ ((visibility("default"))) void |
326 | ecore_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 | */ |
341 | EAPI__attribute__ ((visibility("default"))) int |
342 | ecore_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 | */ |
357 | EAPI__attribute__ ((visibility("default"))) Ecore_Exe * |
358 | ecore_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 | */ |
417 | EAPI__attribute__ ((visibility("default"))) Ecore_Exe * |
418 | ecore_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 | */ |
708 | EAPI__attribute__ ((visibility("default"))) void |
709 | ecore_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 | */ |
733 | EAPI__attribute__ ((visibility("default"))) Eina_Bool |
734 | ecore_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 | */ |
777 | EAPI__attribute__ ((visibility("default"))) void |
778 | ecore_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 | */ |
799 | EAPI__attribute__ ((visibility("default"))) void |
800 | ecore_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 | */ |
860 | EAPI__attribute__ ((visibility("default"))) Ecore_Exe_Event_Data * |
861 | ecore_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 | */ |
991 | EAPI__attribute__ ((visibility("default"))) void |
992 | ecore_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 | */ |
1018 | EAPI__attribute__ ((visibility("default"))) const char * |
1019 | ecore_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 | */ |
1040 | EAPI__attribute__ ((visibility("default"))) void * |
1041 | ecore_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 | */ |
1105 | EAPI__attribute__ ((visibility("default"))) void |
1106 | ecore_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 | */ |
1120 | EAPI__attribute__ ((visibility("default"))) pid_t |
1121 | ecore_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 | */ |
1139 | EAPI__attribute__ ((visibility("default"))) const char * |
1140 | ecore_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 | */ |
1157 | EAPI__attribute__ ((visibility("default"))) void * |
1158 | ecore_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 | */ |
1174 | EAPI__attribute__ ((visibility("default"))) Ecore_Exe_Flags |
1175 | ecore_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 | */ |
1196 | EAPI__attribute__ ((visibility("default"))) void |
1197 | ecore_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 | */ |
1212 | EAPI__attribute__ ((visibility("default"))) void |
1213 | ecore_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 | */ |
1228 | EAPI__attribute__ ((visibility("default"))) void |
1229 | ecore_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 | */ |
1245 | EAPI__attribute__ ((visibility("default"))) void |
1246 | ecore_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 | */ |
1262 | EAPI__attribute__ ((visibility("default"))) void |
1263 | ecore_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 | */ |
1280 | EAPI__attribute__ ((visibility("default"))) void |
1281 | ecore_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 | */ |
1312 | EAPI__attribute__ ((visibility("default"))) void |
1313 | ecore_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 | */ |
1331 | EAPI__attribute__ ((visibility("default"))) void |
1332 | ecore_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 | |
1342 | static 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 | |
1379 | static 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 | |
1411 | static 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 | |
1436 | void |
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 | |
1445 | void |
1446 | _ecore_exe_shutdown(void) |
1447 | { |
1448 | while (exes) |
1449 | ecore_exe_free(exes); |
1450 | } |
1451 | |
1452 | Ecore_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 | |
1465 | Ecore_Timer * |
1466 | _ecore_exe_doomsday_clock_get(Ecore_Exe *exe) |
1467 | { |
1468 | return exe->doomsday_clock; |
1469 | } |
1470 | |
1471 | void |
1472 | _ecore_exe_doomsday_clock_set(Ecore_Exe *exe, Ecore_Timer *dc) |
1473 | { |
1474 | exe->doomsday_clock = dc; |
1475 | } |
1476 | |
1477 | static 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 | |
1572 | static 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 | |
1700 | static 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 | |
1707 | static 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 | |
1714 | static 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 | |
1744 | static 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 | |
1781 | static 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 | |
1790 | static 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 | |
1799 | static 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 | |
1808 | void * |
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 | |
1817 | void |
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 | |
1828 | static 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 | } |