Mercurial > hg > octave-shane > gnulib-hg
changeset 14870:d52404af0321
pipe-filter-ii: Fix test failure on AIX and IRIX.
* lib/pipe-filter-ii.c (pipe_filter_ii_execute): When write() fails
with EAGAIN, retry with a smaller buffer size.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 05 Jun 2011 19:15:25 +0200 |
parents | b8de6a14a6d5 |
children | 82d665ed443a |
files | ChangeLog lib/pipe-filter-ii.c |
diffstat | 2 files changed, 38 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-06-05 Bruno Haible <bruno@clisp.org> + + pipe-filter-ii: Fix test failure on AIX and IRIX. + * lib/pipe-filter-ii.c (pipe_filter_ii_execute): When write() fails + with EAGAIN, retry with a smaller buffer size. + 2011-06-05 Bruno Haible <bruno@clisp.org> localename: Fix link dependencies.
--- a/lib/pipe-filter-ii.c +++ b/lib/pipe-filter-ii.c @@ -347,21 +347,42 @@ const void *buf = prepare_write (&bufsize, private_data); if (buf != NULL) { - ssize_t nwritten = - write (fd[1], buf, - bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize); - if (nwritten < 0) + /* Writing to a pipe in non-blocking mode is tricky: The + write() call may fail with EAGAIN, simply because suffcient + space is not available in the pipe. See POSIX:2008 + <http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html>. + This happens actually on AIX and IRIX, when bufsize >= 8192 + (even though PIPE_BUF and pathconf ("/", _PC_PIPE_BUF) are + both 32768). */ + size_t attempt_to_write = + (bufsize > SSIZE_MAX ? SSIZE_MAX : bufsize); + for (;;) { - if (!IS_EAGAIN (errno)) + ssize_t nwritten = write (fd[1], buf, attempt_to_write); + if (nwritten < 0) { - if (exit_on_error) - error (EXIT_FAILURE, errno, - _("write to %s subprocess failed"), progname); - goto fail; + if (errno == EAGAIN) + { + attempt_to_write = attempt_to_write / 2; + if (attempt_to_write == 0) + break; + } + else if (!IS_EAGAIN (errno)) + { + if (exit_on_error) + error (EXIT_FAILURE, errno, + _("write to %s subprocess failed"), + progname); + goto fail; + } + } + else + { + if (nwritten > 0) + done_write ((void *) buf, nwritten, private_data); + break; } } - else if (nwritten > 0) - done_write ((void *) buf, nwritten, private_data); } else {