From: Carsten H. (T. R. <ra...@ra...> - 2009-04-23 02:05:19
|
On Wed, 25 Mar 2009 08:53:41 +0100 la...@se... (Lars Munch) said: patch in! (sorry - i miss these - if you inline paste a patch as opposed to attach it.. the little "there is an attachment" icon doesnt show up for that mail). > 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. > > /* > Test example > gcc -Wall `pkg-config --libs --cflags ecore` tstpipe.c -o tstpipe > */ > > void handler(void *data, void *buffer, unsigned int nbyte) > { > char *s; > fprintf(stderr, "length %d\n", nbyte); > if(nbyte > 0 || buffer != NULL) > { > s = strndup((char*) buffer, nbyte); > fprintf(stderr, "%s\n", s); > free(s); > } > else > ecore_main_loop_quit(); > } > > int main(int argc, char *argv[]) > { > Ecore_Pipe *p; > pid_t cpid; > > ecore_init(); > p = ecore_pipe_add(handler, NULL); > > cpid = fork(); > if (cpid == -1) > { > perror("fork"); > exit(EXIT_FAILURE); > } > > if (cpid == 0) > { > int i; > /* Child */ > ecore_pipe_close_read(p); > for(i=0; i<4; i++) { > if(!ecore_pipe_write(p, "0123456789", 10)) > exit(EXIT_SUCCESS); > sleep(1); > } > exit(EXIT_SUCCESS); > } > else > { > /* Parent */ > ecore_pipe_close_write(p); > ecore_main_loop_begin(); > exit(EXIT_SUCCESS); > } > > ecore_shutdown(); > } > > Signed-off-by: Lars Munch <la...@se...> > --- > 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..0277852 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_close_write(Ecore_Pipe *p); > + EAPI void ecore_pipe_close_read(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..5608eda 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_close_read(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_close_write(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 > enl...@li... > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel > -- ------------- Codito, ergo sum - "I code, therefore I am" -------------- The Rasterman (Carsten Haitzler) ra...@ra... |