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