From: Joerg Sonnenberger Date: Mon, 26 May 2008 15:45:44 +0000 (-0400) Subject: Be more persistent when trying to get blocking behavior back for X-Git-Tag: v2.6.0~197 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d0ddd8bc6029bd0e1fb15760d86950dd51a3f6e8;p=thirdparty%2Flibarchive.git Be more persistent when trying to get blocking behavior back for the pipes. If the child switched the descriptor back to non-blocking, set it back to blocking and call poll/select. Make the poll/select code filter out -1 as descriptor for this purpose. SVN-Revision: 95 --- diff --git a/libarchive/archive_read_support_compression_program.c b/libarchive/archive_read_support_compression_program.c index 206215c89..d3da22259 100644 --- a/libarchive/archive_read_support_compression_program.c +++ b/libarchive/archive_read_support_compression_program.c @@ -177,6 +177,12 @@ restart_read: state->child_in_buf_avail = ret; } + if (state->child_stdin == -1) { + fcntl(state->child_stdout, F_SETFL, 0); + __archive_check_child(state->child_stdin, state->child_stdout); + goto restart_read; + } + do { ret = write(state->child_stdin, state->child_in_buf, state->child_in_buf_avail); diff --git a/libarchive/archive_write_set_compression_program.c b/libarchive/archive_write_set_compression_program.c index b8b20c86c..c1b099358 100644 --- a/libarchive/archive_write_set_compression_program.c +++ b/libarchive/archive_write_set_compression_program.c @@ -180,6 +180,12 @@ restart_write: if (ret == -1 && errno != EAGAIN) return (-1); + if (state->child_stdout == -1) { + fcntl(state->child_stdin, F_SETFL, 0); + __archive_check_child(state->child_stdin, state->child_stdout); + goto restart_write; + } + do { ret = read(state->child_stdout, state->child_buf + state->child_buf_avail, diff --git a/libarchive/filter_fork.c b/libarchive/filter_fork.c index 3c2d829d0..a097e6986 100644 --- a/libarchive/filter_fork.c +++ b/libarchive/filter_fork.c @@ -118,23 +118,35 @@ __archive_check_child(int in, int out) { #if defined(HAVE_POLL) struct pollfd fds[2]; + int idx; - fds[0].fd = in; - fds[0].events = POLLOUT; - fds[1].fd = out; - fds[1].events = POLLIN; + idx = 0; + if (in != -1) { + fds[idx].fd = in; + fds[idx].events = POLLOUT; + ++idx; + } + if (out != -1) { + fds[idx].fd = out; + fds[idx].events = POLLIN; + ++idx; + } - poll(fds, 2, -1); /* -1 == INFTIM, wait forever */ + poll(fds, idx, -1); /* -1 == INFTIM, wait forever */ #elif defined(HAVE_SELECT) fd_set fds_in, fds_out, fds_error; FD_ZERO(&fds_in); - FD_SET(out, &fds_in); FD_ZERO(&fds_out); - FD_SET(in, &fds_out); FD_ZERO(&fds_error); - FD_SET(in, &fds_error); - FD_SET(out, &fds_error); + if (out != -1) { + FD_SET(out, &fds_in); + FD_SET(out, &fds_error); + } + if (in != -1) { + FD_SET(in, &fds_out); + FD_SET(in, &fds_error); + } select(in < out ? out + 1 : in + 1, &fds_in, &fds_out, &fds_error, NULL); #else sleep(1);