From: lars@segv.dk (Lars Munch)
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. SVN revision: 40305
This commit is contained in:
parent
b0d7b37388
commit
7f1bde6cf4
|
@ -294,10 +294,12 @@ extern "C" {
|
||||||
EAPI Ecore_Pipe *ecore_pipe_add(void (*handler) (void *data, void *buffer, unsigned int nbyte), const void *data);
|
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 void *ecore_pipe_del(Ecore_Pipe *p);
|
||||||
EAPI int ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes);
|
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_time_get(void);
|
||||||
EAPI double ecore_loop_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_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 Ecore_Timer *ecore_timer_loop_add(double in, int (*func) (void *data), const void *data);
|
||||||
EAPI void *ecore_timer_del(Ecore_Timer *timer);
|
EAPI void *ecore_timer_del(Ecore_Timer *timer);
|
||||||
|
|
|
@ -332,20 +332,68 @@ ecore_pipe_del(Ecore_Pipe *p)
|
||||||
"ecore_pipe_del");
|
"ecore_pipe_del");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ecore_main_fd_handler_del(p->fd_handler);
|
if(p->fd_handler != NULL)
|
||||||
close(p->fd_read);
|
ecore_main_fd_handler_del(p->fd_handler);
|
||||||
close(p->fd_write);
|
if(p->fd_read != -1)
|
||||||
|
close(p->fd_read);
|
||||||
|
if(p->fd_write != -1)
|
||||||
|
close(p->fd_write);
|
||||||
data = (void *)p->data;
|
data = (void *)p->data;
|
||||||
free (p);
|
free (p);
|
||||||
return data;
|
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.
|
* Write on the file descriptor the data passed as parameter.
|
||||||
*
|
*
|
||||||
* @param p The Ecore_Pipe object.
|
* @param p The Ecore_Pipe object.
|
||||||
* @param buffer The data to write into the pipe.
|
* @param buffer The data to write into the pipe.
|
||||||
* @param nbytes The size of the @p buffer in bytes
|
* @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
|
* @ingroup Ecore_Pipe_Group
|
||||||
*/
|
*/
|
||||||
EAPI int
|
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_MAGIC_FAIL(p, ECORE_MAGIC_PIPE,
|
||||||
"ecore_pipe_write");
|
"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
|
do
|
||||||
{
|
{
|
||||||
ret = pipe_write(p->fd_write, &nbytes, sizeof(nbytes));
|
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? */
|
/* XXX What should we do here? */
|
||||||
fprintf(stderr, "The length of the data was not written complete"
|
fprintf(stderr, "The length of the data was not written complete"
|
||||||
" to the pipe\n");
|
" 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)
|
else if (ret == -1 && errno == EINTR)
|
||||||
/* try it again */
|
/* try it again */
|
||||||
|
@ -390,7 +448,7 @@ ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes)
|
||||||
while (retry--);
|
while (retry--);
|
||||||
|
|
||||||
if (retry != ECORE_PIPE_WRITE_RETRY)
|
if (retry != ECORE_PIPE_WRITE_RETRY)
|
||||||
return 0;
|
return FALSE;
|
||||||
|
|
||||||
/* and now pass the data to the pipe */
|
/* and now pass the data to the pipe */
|
||||||
do
|
do
|
||||||
|
@ -400,12 +458,18 @@ ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes)
|
||||||
nbytes - already_written);
|
nbytes - already_written);
|
||||||
|
|
||||||
if (ret == (ssize_t)(nbytes - already_written))
|
if (ret == (ssize_t)(nbytes - already_written))
|
||||||
return 1;
|
return TRUE;
|
||||||
else if (ret >= 0)
|
else if (ret >= 0)
|
||||||
{
|
{
|
||||||
already_written -= ret;
|
already_written -= ret;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (ret == -1 && errno == EPIPE)
|
||||||
|
{
|
||||||
|
close(p->fd_write);
|
||||||
|
p->fd_write = -1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
else if (ret == -1 && errno == EINTR)
|
else if (ret == -1 && errno == EINTR)
|
||||||
/* try it again */
|
/* try it again */
|
||||||
;
|
;
|
||||||
|
@ -418,7 +482,7 @@ ecore_pipe_write(Ecore_Pipe *p, const void *buffer, unsigned int nbytes)
|
||||||
}
|
}
|
||||||
while (retry--);
|
while (retry--);
|
||||||
|
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Private function */
|
/* 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"
|
fprintf(stderr, "Only read %d bytes from the pipe, although"
|
||||||
" we need to read %d bytes.\n", ret, sizeof(p->len));
|
" we need to read %d bytes.\n", ret, sizeof(p->len));
|
||||||
}
|
}
|
||||||
else if ((ret == 0) ||
|
else if (ret == 0)
|
||||||
((ret == -1) && ((errno == EINTR) || (errno == EAGAIN))))
|
{
|
||||||
|
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;
|
return ECORE_CALLBACK_RENEW;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -488,6 +559,14 @@ _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
|
||||||
p->already_read += ret;
|
p->already_read += ret;
|
||||||
return ECORE_CALLBACK_RENEW;
|
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))
|
else if (ret == -1 && (errno == EINTR || errno == EAGAIN))
|
||||||
return ECORE_CALLBACK_RENEW;
|
return ECORE_CALLBACK_RENEW;
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue