On Wed, Mar 25, 2009 at 09:08:53AM +0100, Peter Wehrfritz wrote: > Lars Munch schrieb: > >Hi > > > >This patch adds two new functions, ecore_pipe_close_read and > >ecore_pipe_close_write, to ecore_pipe. The purpose it to enable > >ecore_pipe to be used together with fork (see example below). > > > >The patch also handles if the read or write end of the pipe closes. > > > > I think the names don't fit in to the efl-naming schema, very well. That > means that the verb is at the end of the function name, here this would > be "close". So ecore_pipe_write_close, or ecore_pipe_write_end_close > would be better.
Yes, you are right. Updated patch below. This patch adds two new functions, ecore_pipe_read_close and ecore_pipe_write_close, to ecore_pipe. The purpose it to enable ecore_pipe to be used together with fork. The patch also handles if the read or write end of the pipe closes. Signed-off-by: Lars Munch <l...@segv.dk> --- src/lib/ecore/Ecore.h | 4 +- src/lib/ecore/ecore_pipe.c | 101 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 93 insertions(+), 12 deletions(-) diff --git a/src/lib/ecore/Ecore.h b/src/lib/ecore/Ecore.h index 0a1969d..b001ded 100644 --- a/src/lib/ecore/Ecore.h +++ b/src/lib/ecore/Ecore.h @@ -290,10 +290,12 @@ extern "C" { EAPI Ecore_Pipe *ecore_pipe_add(void (*handler) (void *data, void *buffer, unsigned int nbyte), const void *data); EAPI void *ecore_pipe_del(Ecore_Pipe *p); EAPI int ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes); + EAPI void ecore_pipe_write_close(Ecore_Pipe *p); + EAPI void ecore_pipe_read_close(Ecore_Pipe *p); EAPI double ecore_time_get(void); EAPI double ecore_loop_time_get(void); - + EAPI Ecore_Timer *ecore_timer_add(double in, int (*func) (void *data), const void *data); EAPI Ecore_Timer *ecore_timer_loop_add(double in, int (*func) (void *data), const void *data); EAPI void *ecore_timer_del(Ecore_Timer *timer); diff --git a/src/lib/ecore/ecore_pipe.c b/src/lib/ecore/ecore_pipe.c index f6e4778..84fded0 100644 --- a/src/lib/ecore/ecore_pipe.c +++ b/src/lib/ecore/ecore_pipe.c @@ -332,20 +332,68 @@ ecore_pipe_del(Ecore_Pipe *p) "ecore_pipe_del"); return NULL; } - ecore_main_fd_handler_del(p->fd_handler); - close(p->fd_read); - close(p->fd_write); + if(p->fd_handler != NULL) + ecore_main_fd_handler_del(p->fd_handler); + if(p->fd_read != -1) + close(p->fd_read); + if(p->fd_write != -1) + close(p->fd_write); data = (void *)p->data; free (p); return data; } /** + * Close the read end of an Ecore_Pipe object created with ecore_pipe_add(). + * + * @param p The Ecore_Pipe object. + * @ingroup Ecore_Pipe_Group + */ +EAPI void +ecore_pipe_read_close(Ecore_Pipe *p) +{ + void *data; + + if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) + { + ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, + "ecore_pipe_close_read"); + return; + } + ecore_main_fd_handler_del(p->fd_handler); + p->fd_handler = NULL; + close(p->fd_read); + p->fd_read = -1; +} + +/** + * Close the write end of an Ecore_Pipe object created with ecore_pipe_add(). + * + * @param p The Ecore_Pipe object. + * @ingroup Ecore_Pipe_Group + */ +EAPI void +ecore_pipe_write_close(Ecore_Pipe *p) +{ + void *data; + + if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) + { + ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, + "ecore_pipe_close_write"); + return; + } + close(p->fd_write); + p->fd_write = -1; +} + +/** * Write on the file descriptor the data passed as parameter. * * @param p The Ecore_Pipe object. * @param buffer The data to write into the pipe. * @param nbytes The size of the @p buffer in bytes + * @return Returns TRUE on a successful write, FALSE on an error * @ingroup Ecore_Pipe_Group */ EAPI int @@ -359,9 +407,13 @@ ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes) { ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write"); - return 0; + return FALSE; } - /* first write the len into the pipe */ + + if(p->fd_write == -1) + return FALSE; + + /* First write the len into the pipe */ do { ret = pipe_write(p->fd_write, &nbytes, sizeof(nbytes)); @@ -375,7 +427,13 @@ ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes) /* XXX What should we do here? */ fprintf(stderr, "The length of the data was not written complete" " to the pipe\n"); - return 0; + return FALSE; + } + else if (ret == -1 && errno == EPIPE) + { + close(p->fd_write); + p->fd_write = -1; + return FALSE; } else if (ret == -1 && errno == EINTR) /* try it again */ @@ -390,7 +448,7 @@ ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes) while (retry--); if (retry != ECORE_PIPE_WRITE_RETRY) - return 0; + return FALSE; /* and now pass the data to the pipe */ do @@ -400,12 +458,18 @@ ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes) nbytes - already_written); if (ret == (ssize_t)(nbytes - already_written)) - return 1; + return TRUE; else if (ret >= 0) { already_written -= ret; continue; } + else if (ret == -1 && errno == EPIPE) + { + close(p->fd_write); + p->fd_write = -1; + return FALSE; + } else if (ret == -1 && errno == EINTR) /* try it again */ ; @@ -418,7 +482,7 @@ ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes) } while (retry--); - return 0; + return FALSE; } /* Private function */ @@ -453,8 +517,15 @@ _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) fprintf(stderr, "Only read %d bytes from the pipe, although" " we need to read %d bytes.\n", ret, sizeof(p->len)); } - else if ((ret == 0) || - ((ret == -1) && ((errno == EINTR) || (errno == EAGAIN)))) + else if (ret == 0) + { + p->handler((void *)p->data, NULL, 0); + close(p->fd_read); + p->fd_read = -1; + p->fd_handler = NULL; + return ECORE_CALLBACK_CANCEL; + } + else if ((ret == -1) && ((errno == EINTR) || (errno == EAGAIN))) return ECORE_CALLBACK_RENEW; else { @@ -488,6 +559,14 @@ _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__) p->already_read += ret; return ECORE_CALLBACK_RENEW; } + else if (ret == 0) + { + p->handler((void *)p->data, NULL, 0); + close(p->fd_read); + p->fd_read = -1; + p->fd_handler = NULL; + return ECORE_CALLBACK_CANCEL; + } else if (ret == -1 && (errno == EINTR || errno == EAGAIN)) return ECORE_CALLBACK_RENEW; else -- 1.6.2.1 ------------------------------------------------------------------------------ Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are powering Web 2.0 with engaging, cross-platform capabilities. Quickly and easily build your RIAs with Flex Builder, the Eclipse(TM)based development software that enables intelligent coding and step-through debugging. Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com _______________________________________________ enlightenment-devel mailing list enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel