1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <errno.h>
8 #include <math.h>
9
10 #ifdef HAVE_IEEEFP_H
11 # include <ieeefp.h> /* for Solaris */
12 #endif
13
14 #ifdef HAVE_ISFINITE
15 # define ECORE_FINITE(t) isfinite(t)
16 #else
17 # define ECORE_FINITE(t) finite(t)
18 #endif
19
20 #define FIX_HZ 1
21
22 #ifdef FIX_HZ
23 # include <sys/param.h>
24 # ifndef HZ
25 # define HZ 100
26 # endif
27 #endif
28
29 /*
30 * On Windows, pipe() is implemented with sockets.
31 * Contrary to Linux, Windows uses different functions
32 * for sockets and fd's: write() is for fd's and send
33 * is for sockets. So I need to put some win32 code
34 * here. I can't think of a solution where the win32
35 * code is in Evil and not here.
36 */
37
38 #define PIPE_FD_INVALID -1
39
40 #ifdef _WIN32
41 # include <winsock2.h>
42 # include <evil_private.h> /* pipe fcntl */
43 # define pipe_write(fd, buffer, size) send((fd), (char *)(buffer), size, 0)
44 # define pipe_read(fd, buffer, size) recv((fd), (char *)(buffer), size, 0)
45 # define pipe_close(fd) closesocket(fd)
46 # define PIPE_FD_ERROR SOCKET_ERROR
47 #else
48 # ifdef HAVE_SYS_EPOLL_H
49 # include <sys/epoll.h>
50 # endif /* HAVE_SYS_EPOLL_H */
51 # ifdef HAVE_SYS_TIMERFD_H
52 # include <sys/timerfd.h>
53 # endif
54 # include <unistd.h>
55 # include <fcntl.h>
56 # define pipe_write(fd, buffer, size) write((fd), buffer, size)
57 # define pipe_read(fd, buffer, size) read((fd), buffer, size)
58 # define pipe_close(fd) close(fd)
59 # define PIPE_FD_ERROR -1
60 #endif /* ! _WIN32 */
61
62 #include "Ecore.h"
63 #include "ecore_private.h"
64
65 // How of then we should retry to write to the pipe
66 #define ECORE_PIPE_WRITE_RETRY 6
67
68 struct _Ecore_Pipe
69 {
70 ECORE_MAGIC;
71 int fd_read;
72 int fd_write;
73 Ecore_Fd_Handler *fd_handler;
74 const void *data;
75 Ecore_Pipe_Cb handler;
76 unsigned int len;
77 int handling;
78 unsigned int already_read;
79 void *passed_data;
80 int message;
81 #ifndef _WIN32
82 int pollfd;
83 int timerfd;
84 #endif
85 Eina_Bool delete_me : 1;
86 };
87 GENERIC_ALLOC_SIZE_DECLARE(Ecore_Pipe);
88
89 static Eina_Bool _ecore_pipe_read(void *data,
90 Ecore_Fd_Handler *fd_handler);
91
92 EAPI Ecore_Pipe *
ecore_pipe_add(Ecore_Pipe_Cb handler,const void * data)93 ecore_pipe_add(Ecore_Pipe_Cb handler,
94 const void *data)
95 {
96 return _ecore_pipe_add(handler, data);
97 }
98
99 EAPI void *
ecore_pipe_del(Ecore_Pipe * p)100 ecore_pipe_del(Ecore_Pipe *p)
101 {
102 if (!p) return NULL;
103 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
104 return _ecore_pipe_del(p);
105 }
106
107 EAPI void
ecore_pipe_read_close(Ecore_Pipe * p)108 ecore_pipe_read_close(Ecore_Pipe *p)
109 {
110 EINA_MAIN_LOOP_CHECK_RETURN;
111 if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
112 {
113 ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_close");
114 return;
115 }
116 if (p->fd_handler)
117 {
118 _ecore_main_fd_handler_del(ML_OBJ, ML_DAT, p->fd_handler);
119 p->fd_handler = NULL;
120 }
121 if (p->fd_read != PIPE_FD_INVALID)
122 {
123 pipe_close(p->fd_read);
124 p->fd_read = PIPE_FD_INVALID;
125 }
126 }
127
128 EAPI int
ecore_pipe_read_fd(Ecore_Pipe * p)129 ecore_pipe_read_fd(Ecore_Pipe *p)
130 {
131 EINA_MAIN_LOOP_CHECK_RETURN_VAL(PIPE_FD_INVALID);
132 if (!p) return PIPE_FD_INVALID;
133 return p->fd_read;
134 }
135
136 EAPI void
ecore_pipe_freeze(Ecore_Pipe * p)137 ecore_pipe_freeze(Ecore_Pipe *p)
138 {
139 EINA_MAIN_LOOP_CHECK_RETURN;
140 if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
141 {
142 ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_freeze");
143 return;
144 }
145 if (p->fd_handler)
146 {
147 _ecore_main_fd_handler_del(ML_OBJ, ML_DAT, p->fd_handler);
148 p->fd_handler = NULL;
149 }
150 }
151
152 EAPI void
ecore_pipe_thaw(Ecore_Pipe * p)153 ecore_pipe_thaw(Ecore_Pipe *p)
154 {
155 EINA_MAIN_LOOP_CHECK_RETURN;
156 if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
157 {
158 ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_thaw");
159 return;
160 }
161 if ((!p->fd_handler) && (p->fd_read != PIPE_FD_INVALID))
162 p->fd_handler = ecore_main_fd_handler_add(p->fd_read, ECORE_FD_READ,
163 _ecore_pipe_read, p,
164 NULL, NULL);
165 }
166
167 EAPI int
ecore_pipe_wait(Ecore_Pipe * p,int message_count,double wait)168 ecore_pipe_wait(Ecore_Pipe *p,
169 int message_count,
170 double wait)
171 {
172 return _ecore_pipe_wait(p, message_count, wait);
173 }
174
175 EAPI void
ecore_pipe_write_close(Ecore_Pipe * p)176 ecore_pipe_write_close(Ecore_Pipe *p)
177 {
178 if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
179 {
180 ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write_close");
181 return;
182 }
183 if (p->fd_write != PIPE_FD_INVALID)
184 {
185 pipe_close(p->fd_write);
186 p->fd_write = PIPE_FD_INVALID;
187 }
188 }
189
190 EAPI int
ecore_pipe_write_fd(Ecore_Pipe * p)191 ecore_pipe_write_fd(Ecore_Pipe *p)
192 {
193 EINA_MAIN_LOOP_CHECK_RETURN_VAL(PIPE_FD_INVALID);
194 if (!p) return PIPE_FD_INVALID;
195 return p->fd_write;
196 }
197
198 EAPI Eina_Bool
ecore_pipe_write(Ecore_Pipe * p,const void * buffer,unsigned int nbytes)199 ecore_pipe_write(Ecore_Pipe *p,
200 const void *buffer,
201 unsigned int nbytes)
202 {
203 ssize_t ret;
204 size_t already_written = 0;
205 int retry = ECORE_PIPE_WRITE_RETRY;
206 Eina_Bool ok = EINA_FALSE;
207 unsigned int bytes = nbytes;
208
209 if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
210 {
211 ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write");
212 goto out;
213 }
214
215 if (p->delete_me) goto out;
216
217 if (p->fd_write == PIPE_FD_INVALID) goto out;
218
219 do // First write the len into the pipe
220 {
221 ret = pipe_write(p->fd_write, &bytes, sizeof(bytes));
222 if (ret == sizeof(nbytes))
223 {
224 retry = ECORE_PIPE_WRITE_RETRY;
225 break;
226 }
227 else if (ret > 0)
228 {
229 // XXX What should we do here?
230 ERR("The length of the data was not written complete"
231 " to the pipe");
232 goto out;
233 }
234 else if ((ret == PIPE_FD_ERROR) && (errno == EPIPE))
235 {
236 pipe_close(p->fd_write);
237 p->fd_write = PIPE_FD_INVALID;
238 goto out;
239 }
240 else if ((ret == PIPE_FD_ERROR) && (errno == EINTR))
241 // try it again
242 ;
243 else
244 {
245 ERR("An unhandled error (ret: %zd errno: %d)"
246 "occurred while writing to the pipe the length",
247 ret, errno);
248 }
249 }
250 while (retry--);
251
252 if (retry != ECORE_PIPE_WRITE_RETRY) goto out;
253
254 do // and now pass the data to the pipe
255 {
256 ret = pipe_write(p->fd_write,
257 ((unsigned char *)buffer) + already_written,
258 nbytes - already_written);
259
260 if (ret == (ssize_t)(nbytes - already_written))
261 {
262 ok = EINA_TRUE;
263 goto out;
264 }
265 else if (ret >= 0)
266 {
267 already_written -= ret;
268 continue;
269 }
270 else if ((ret == PIPE_FD_ERROR) && (errno == EPIPE))
271 {
272 pipe_close(p->fd_write);
273 p->fd_write = PIPE_FD_INVALID;
274 goto out;
275 }
276 else if ((ret == PIPE_FD_ERROR) && (errno == EINTR))
277 // try it again
278 ;
279 else
280 {
281 ERR("An unhandled error (ret: %zd errno: %d)"
282 "occurred while writing to the pipe the length",
283 ret, errno);
284 }
285 }
286 while (retry--);
287
288 out:
289 return ok;
290 }
291
292 EAPI Ecore_Pipe *
ecore_pipe_full_add(Ecore_Pipe_Cb handler,const void * data,int fd_read,int fd_write,Eina_Bool read_survive_fork,Eina_Bool write_survive_fork)293 ecore_pipe_full_add(Ecore_Pipe_Cb handler,
294 const void *data,
295 int fd_read,
296 int fd_write,
297 Eina_Bool read_survive_fork,
298 Eina_Bool write_survive_fork)
299 {
300 Ecore_Pipe *p = NULL;
301 int fds[2];
302
303 EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
304 if (!handler) return NULL;
305
306 p = ecore_pipe_calloc(1);
307 if (!p) return NULL;
308
309 if ((fd_read == -1) && (fd_write == -1))
310 {
311 if (pipe(fds))
312 {
313 ecore_pipe_mp_free(p);
314 return NULL;
315 }
316 fd_read = fds[0];
317 fd_write = fds[1];
318 }
319 else
320 {
321 fd_read = (fd_read == -1) ? PIPE_FD_INVALID : fd_read;
322 fd_write = (fd_write == -1) ? PIPE_FD_INVALID : fd_write;
323 }
324
325 ECORE_MAGIC_SET(p, ECORE_MAGIC_PIPE);
326 p->fd_read = fd_read;
327 p->fd_write = fd_write;
328 p->handler = handler;
329 p->data = data;
330
331 if (!read_survive_fork) eina_file_close_on_exec(fd_read, EINA_TRUE);
332 if (!write_survive_fork) eina_file_close_on_exec(fd_write, EINA_TRUE);
333
334 #if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_SYS_TIMERFD_H)
335 struct epoll_event pollev = { 0 };
336 p->pollfd = epoll_create(1);
337 p->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
338 eina_file_close_on_exec(p->pollfd, EINA_TRUE);
339
340 pollev.data.ptr = &(p->fd_read);
341 pollev.events = EPOLLIN;
342 epoll_ctl(p->pollfd, EPOLL_CTL_ADD, p->fd_read, &pollev);
343
344 pollev.data.ptr = &(p->timerfd);
345 pollev.events = EPOLLIN;
346 epoll_ctl(p->pollfd, EPOLL_CTL_ADD, p->timerfd, &pollev);
347 #endif
348
349 if (fcntl(p->fd_read, F_SETFL, O_NONBLOCK) < 0)
350 ERR("can't set pipe to NONBLOCK");
351 p->fd_handler = ecore_main_fd_handler_add(p->fd_read, ECORE_FD_READ,
352 _ecore_pipe_read, p, NULL, NULL);
353 return p;
354 }
355
356 // Private functions
357 Ecore_Pipe *
_ecore_pipe_add(Ecore_Pipe_Cb handler,const void * data)358 _ecore_pipe_add(Ecore_Pipe_Cb handler,
359 const void *data)
360 {
361 return ecore_pipe_full_add(handler, data, -1, -1, EINA_FALSE, EINA_FALSE);
362 }
363
364 void *
_ecore_pipe_del(Ecore_Pipe * p)365 _ecore_pipe_del(Ecore_Pipe *p)
366 {
367 void *data = NULL;
368
369 if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
370 {
371 ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_del");
372 return NULL;
373 }
374 #if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_SYS_TIMERFD_H)
375 epoll_ctl(p->pollfd, EPOLL_CTL_DEL, p->fd_read, NULL);
376 epoll_ctl(p->pollfd, EPOLL_CTL_DEL, p->timerfd, NULL);
377 if (p->timerfd >= 0) close(p->timerfd);
378 if (p->pollfd >= 0) close(p->pollfd);
379 p->timerfd = PIPE_FD_INVALID;
380 p->pollfd = PIPE_FD_INVALID;
381 #endif
382 p->delete_me = EINA_TRUE;
383 if (p->handling > 0) return (void *)p->data;
384 if (p->fd_handler) _ecore_main_fd_handler_del(ML_OBJ, ML_DAT,
385 p->fd_handler);
386 if (p->fd_read != PIPE_FD_INVALID) pipe_close(p->fd_read);
387 if (p->fd_write != PIPE_FD_INVALID) pipe_close(p->fd_write);
388 p->fd_handler = NULL;
389 p->fd_read = PIPE_FD_INVALID;
390 p->fd_write = PIPE_FD_INVALID;
391 data = (void *)p->data;
392 ecore_pipe_mp_free(p);
393 return data;
394 }
395
396 static void
_ecore_pipe_unhandle(Ecore_Pipe * p)397 _ecore_pipe_unhandle(Ecore_Pipe *p)
398 {
399 p->handling--;
400 if (p->delete_me) _ecore_pipe_del(p);
401 }
402
403 #if ! defined(HAVE_SYS_EPOLL_H) || ! defined(HAVE_SYS_TIMERFD_H)
404 int
_ecore_pipe_wait(Ecore_Pipe * p,int message_count,double wait)405 _ecore_pipe_wait(Ecore_Pipe *p,
406 int message_count,
407 double wait)
408 {
409 struct timeval tv, *t;
410 fd_set rset, wset, exset;
411 double end = 0.0;
412 double timeout;
413 int ret;
414 int total = 0;
415
416 EINA_MAIN_LOOP_CHECK_RETURN_VAL(-1);
417 if (p->fd_read == PIPE_FD_INVALID) return -1;
418
419 FD_ZERO(&rset);
420 FD_ZERO(&wset);
421 FD_ZERO(&exset);
422 FD_SET(p->fd_read, &rset);
423
424 if (wait >= 0.0) end = ecore_time_get() + wait;
425 timeout = wait;
426
427 while ((message_count > 0) && ((timeout > 0.0) || (wait <= 0.0)))
428 {
429 if (wait >= 0.0)
430 {
431 // finite() tests for NaN, too big, too small, and infinity.
432 if ((!ECORE_FINITE(timeout)) || (EINA_DBL_EQ(timeout, 0.0)))
433 {
434 tv.tv_sec = 0;
435 tv.tv_usec = 0;
436 }
437 else if (timeout > 0.0)
438 {
439 int sec, usec;
440 #ifdef FIX_HZ
441 timeout += (0.5 / HZ);
442 #endif
443 sec = (int)timeout;
444 usec = (int)((timeout - (double)sec) * 1000000);
445 tv.tv_sec = sec;
446 tv.tv_usec = usec;
447 }
448 t = &tv;
449 }
450 else t = NULL;
451
452 ret = main_loop_select(p->fd_read + 1, &rset, &wset, &exset, t);
453
454 if (ret > 0)
455 {
456 p->handling++;
457 _ecore_pipe_read(p, NULL);
458 message_count -= p->message;
459 total += p->message;
460 p->message = 0;
461 _ecore_pipe_unhandle(p);
462 }
463 else if (ret == 0) break;
464 else if (errno != EINTR)
465 {
466 if (p->fd_read != PIPE_FD_INVALID)
467 {
468 close(p->fd_read);
469 p->fd_read = PIPE_FD_INVALID;
470 }
471 break;
472 }
473
474 if (wait >= 0.0) timeout = end - ecore_time_get();
475 }
476
477 return total;
478 }
479
480 #else
481 int
_ecore_pipe_wait(Ecore_Pipe * p,int message_count,double wait)482 _ecore_pipe_wait(Ecore_Pipe *p,
483 int message_count,
484 double wait)
485 {
486 int64_t timerfdbuf;
487 struct epoll_event pollincoming[2];
488 double timeout;
489 int ret = 0;
490 int total = 0;
491 int time_exit = -1;
492 Eina_Bool fd_read_found;
493 Eina_Bool fd_timer_found;
494 struct itimerspec tspec_new;
495
496 EINA_MAIN_LOOP_CHECK_RETURN_VAL(-1);
497 if (p->fd_read == PIPE_FD_INVALID) return -1;
498
499 timeout = wait;
500 int sec, usec;
501 if (wait >= 0.0)
502 {
503 if ((!ECORE_FINITE(timeout)) || (EINA_DBL_EQ(timeout, 0.0)))
504 {
505 tspec_new.it_value.tv_sec = 0;
506 tspec_new.it_value.tv_nsec = 0;
507 tspec_new.it_interval.tv_sec = 0;
508 tspec_new.it_interval.tv_nsec = 0;
509 time_exit = 0;
510 }
511 else
512 {
513 #ifdef FIX_HZ
514 timeout += (0.5 / HZ);
515 #endif
516 sec = (int)timeout;
517 usec = (int)((timeout - (double)sec) * 1000000000);
518 tspec_new.it_value.tv_sec = sec;
519 tspec_new.it_value.tv_nsec = (int)(usec) % 1000000000;
520 tspec_new.it_interval.tv_sec = 0;
521 tspec_new.it_interval.tv_nsec = 0;
522 timerfd_settime(p->timerfd, 0, &tspec_new, NULL);
523 }
524 }
525
526 while ((p->pollfd != PIPE_FD_INVALID) && (ret = epoll_wait(p->pollfd, pollincoming, 2, time_exit)) > 0)
527 {
528 fd_read_found = EINA_FALSE;
529 fd_timer_found = EINA_FALSE;
530
531 for (int i = 0; i < ret;i++)
532 {
533 if ((&p->fd_read == pollincoming[i].data.ptr))
534 fd_read_found = EINA_TRUE;
535 if ((&p->timerfd == pollincoming[i].data.ptr))
536 fd_timer_found = EINA_TRUE;
537 }
538
539 p->handling++;
540 if (fd_read_found)
541 {
542 _ecore_pipe_read(p, NULL);
543 message_count -= p->message;
544 total += p->message;
545 p->message = 0;
546 if (message_count <= 0)
547 {
548 _ecore_pipe_unhandle(p);
549 break;
550 }
551 }
552
553 if ((fd_timer_found) && (p->timerfd != PIPE_FD_INVALID))
554 {
555 if (pipe_read(p->timerfd, &timerfdbuf, sizeof(timerfdbuf)) <
556 (int)sizeof(int64_t))
557 WRN("Could not read timerfd data");
558 _ecore_pipe_unhandle(p);
559 break;
560 }
561 _ecore_pipe_unhandle(p);
562 }
563 if (ret < 0)
564 {
565 if (errno != EBADF)
566 WRN("epoll file descriptor is not a valid");
567 else if (errno != EINVAL)
568 WRN("epoll file descriptor is not an epoll file descriptor, or maxevents is less than or equal to zero.");
569 else if (errno != EFAULT)
570 WRN("The memory area pointed to by epoll_event is not accessible with write permissions.");
571 else if (errno != EINTR)
572 WRN("The call was interrupted by a signal handler before any of the requested epoll_event "
573 "occurred or the timeout expired; see signal(7).");
574 }
575 return total;
576 }
577
578 #endif
579 static void
_ecore_pipe_handler_call(Ecore_Pipe * p,unsigned char * buf,size_t len)580 _ecore_pipe_handler_call(Ecore_Pipe *p,
581 unsigned char *buf,
582 size_t len)
583 {
584 void *data = (void*) p->data;
585
586 // clear all values of pipe first.
587 p->passed_data = NULL;
588 p->already_read = 0;
589 p->len = 0;
590 p->message++;
591
592 if (!p->delete_me) p->handler(data, buf, len);
593
594 // free p->passed_data
595 free(buf);
596 }
597
598 static Eina_Bool
_ecore_pipe_read(void * data,Ecore_Fd_Handler * fd_handler EINA_UNUSED)599 _ecore_pipe_read(void *data,
600 Ecore_Fd_Handler *fd_handler EINA_UNUSED)
601 {
602 Ecore_Pipe *p = (Ecore_Pipe *)data;
603 int i;
604
605 p->handling++;
606 for (i = 0; i < 16; i++)
607 {
608 ssize_t ret;
609
610 // if we already have read some data we don't need to read the len
611 // but to finish the already started job
612 if (p->len == 0)
613 {
614 // read the len of the passed data
615 ret = pipe_read(p->fd_read, &p->len, sizeof(p->len));
616
617 // catch the non error case first
618 // read amount ok - nothing more to do
619 if (ret == sizeof(p->len))
620 ;
621 else if (ret > 0)
622 {
623 // we got more data than we asked for - definite error
624 ERR("Only read %i bytes from the pipe, although"
625 " we need to read %i bytes.",
626 (int)ret, (int)sizeof(p->len));
627 _ecore_pipe_unhandle(p);
628 return ECORE_CALLBACK_CANCEL;
629 }
630 else if (ret == 0)
631 {
632 // we got no data
633 if (i == 0)
634 {
635 // no data on first try through means an error
636 _ecore_pipe_handler_call(p, NULL, 0);
637 pipe_close(p->fd_read);
638 p->fd_read = PIPE_FD_INVALID;
639 p->fd_handler = NULL;
640 _ecore_pipe_unhandle(p);
641 return ECORE_CALLBACK_CANCEL;
642 }
643 else
644 {
645 // no data after first loop try is ok
646 _ecore_pipe_unhandle(p);
647 return ECORE_CALLBACK_RENEW;
648 }
649 }
650 #ifndef _WIN32
651 else if ((ret == PIPE_FD_ERROR) &&
652 ((errno == EINTR) || (errno == EAGAIN)))
653 {
654 _ecore_pipe_unhandle(p);
655 return ECORE_CALLBACK_RENEW;
656 }
657 else
658 {
659 ERR("An unhandled error (ret: %i errno: %i [%s])"
660 "occurred while reading from the pipe the length",
661 (int)ret, errno, strerror(errno));
662 _ecore_pipe_unhandle(p);
663 return ECORE_CALLBACK_RENEW;
664 }
665 #else
666 else // ret == PIPE_FD_ERROR is the only other case on Windows
667 {
668 if (WSAGetLastError() != WSAEWOULDBLOCK)
669 {
670 _ecore_pipe_handler_call(p, NULL, 0);
671 pipe_close(p->fd_read);
672 p->fd_read = PIPE_FD_INVALID;
673 p->fd_handler = NULL;
674 _ecore_pipe_unhandle(p);
675 return ECORE_CALLBACK_CANCEL;
676 }
677 }
678 #endif
679 }
680 // if somehow we got less than or equal to 0 we got an errnoneous
681 // messages so call callback with null and len we got. this case should
682 // never happen
683 if (p->len == 0)
684 {
685 _ecore_pipe_handler_call(p, NULL, 0);
686 _ecore_pipe_unhandle(p);
687 return ECORE_CALLBACK_RENEW;
688 }
689
690 // we dont have a buffer to hold the data, so alloc it
691 if (!p->passed_data)
692 {
693 p->passed_data = malloc(p->len);
694 // alloc failed - error case
695 if (!p->passed_data)
696 {
697 _ecore_pipe_handler_call(p, NULL, 0);
698 // close the pipe
699 pipe_close(p->fd_read);
700 p->fd_read = PIPE_FD_INVALID;
701 p->fd_handler = NULL;
702 _ecore_pipe_unhandle(p);
703 return ECORE_CALLBACK_CANCEL;
704 }
705 }
706
707 // and read the passed data
708 ret = pipe_read(p->fd_read,
709 ((unsigned char *)p->passed_data) + p->already_read,
710 p->len - p->already_read);
711
712 // catch the non error case first
713 // if we read enough data to finish the message/buffer
714 if (ret == (ssize_t)(p->len - p->already_read))
715 _ecore_pipe_handler_call(p, p->passed_data, p->len);
716 else if (ret > 0)
717 {
718 // more data left to read
719 p->already_read += (unsigned int)ret;
720 _ecore_pipe_unhandle(p);
721 return ECORE_CALLBACK_RENEW;
722 }
723 else if (ret == 0)
724 {
725 // 0 bytes to read - could be more to read next select wake up
726 _ecore_pipe_unhandle(p);
727 return ECORE_CALLBACK_RENEW;
728 }
729 #ifndef _WIN32
730 else if ((ret == PIPE_FD_ERROR) &&
731 ((errno == EINTR) || (errno == EAGAIN)))
732 {
733 _ecore_pipe_unhandle(p);
734 return ECORE_CALLBACK_RENEW;
735 }
736 else
737 {
738 ERR("An unhandled error (ret: %zd errno: %d)"
739 "occurred while reading from the pipe the data",
740 ret, errno);
741 _ecore_pipe_unhandle(p);
742 return ECORE_CALLBACK_RENEW;
743 }
744 #else
745 else // ret == PIPE_FD_ERROR is the only other case on Windows
746 {
747 if (WSAGetLastError() != WSAEWOULDBLOCK)
748 {
749 _ecore_pipe_handler_call(p, NULL, 0);
750 pipe_close(p->fd_read);
751 p->fd_read = PIPE_FD_INVALID;
752 p->fd_handler = NULL;
753 _ecore_pipe_unhandle(p);
754 return ECORE_CALLBACK_CANCEL;
755 }
756 else break;
757 }
758 #endif
759 }
760
761 _ecore_pipe_unhandle(p);
762 return ECORE_CALLBACK_RENEW;
763 }
764
765