From: Paul Jackson , Paul Jackson xdelta3 automatically sets up child compression and decompression processes and pipes data to and from them, in various cases. Sometimes this can hang, due to improper closing, or lose data, due to improper flushing. This patch purports to fix this, but has not been tested very well at all. More work may be needed here. The patch also makes one error message less scary. --- xdelta3-main.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) --- xdelta3.0.0.orig/xdelta3-main.h 2012-03-26 23:11:26.346316918 -0500 +++ xdelta3.0.0/xdelta3-main.h 2012-03-26 23:11:40.218752082 -0500 @@ -2135,9 +2135,11 @@ main_waitpid_check(pid_t pid) } else if (! WIFEXITED (status)) { - ret = ECHILD; - XPR(NT "external compression [pid %d] signal %d\n", - pid, WIFSIGNALED (status) ? WTERMSIG (status) : WSTOPSIG (status)); + if ( ! (WIFSIGNALED (status) && WTERMSIG (status) == SIGPIPE) ) { + ret = ECHILD; + XPR(NT "external compression [pid %d] signal %d\n", + pid, WIFSIGNALED (status) ? WTERMSIG (status) : WSTOPSIG (status)); + } } else if (WEXITSTATUS (status) != 0) { @@ -2221,7 +2223,8 @@ main_pipe_copier (uint8_t *pipe_buf, int force_drain = 0; if (nread > 0 && (ret = main_pipe_write (outfd, pipe_buf, nread))) { - if (option_force && ret == EPIPE) + /* Next line: Until better fix, *always* drain if EPIPE. */ + if ( /* option_force && */ ret == EPIPE) { /* This causes the loop to continue reading until nread * == 0. */ @@ -2265,7 +2268,7 @@ main_pipe_copier (uint8_t *pipe_buf, if (garbage != 0) { - XPR(NT "trailing garbage ignored in %s (%"Q"u bytes)\n", + XPR(NT "skipped trailing bytes in %s (%"Q"u bytes)\n", ifile->filename, garbage); } return 0; @@ -2354,6 +2357,8 @@ main_input_decompress_setup (const main_ } if (close (inpipefd[PIPE_READ_FD]) || + close (outpipefd[PIPE_READ_FD]) || + close (outpipefd[PIPE_WRITE_FD]) || main_pipe_copier (pipe_buf, pipe_bufsize, pipe_avail, ifile, inpipefd[PIPE_WRITE_FD]) || close (inpipefd[PIPE_WRITE_FD]))