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 <[email protected]>
---
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel