From bf7690a6dc4d459c3a1315ba23ea521d64ab9afa Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 5 Jun 2011 19:15:25 +0200 Subject: [PATCH] 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. --- ChangeLog | 6 ++++++ lib/pipe-filter-ii.c | 43 ++++++++++++++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index f6db6cb1e..0262b303e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2011-06-05 Bruno Haible + 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 + localename: Fix link dependencies. * modules/localename (Link): Mention $(LIBTHREAD) or $(LTLIBTHREAD). * modules/localename-tests (Makefile.am): Link test-localename with diff --git a/lib/pipe-filter-ii.c b/lib/pipe-filter-ii.c index f20b7b41c..d0eb86b77 100644 --- a/lib/pipe-filter-ii.c +++ b/lib/pipe-filter-ii.c @@ -347,21 +347,42 @@ pipe_filter_ii_execute (const char *progname, 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 + . + 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 { -- 2.11.0