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

Reply via email to