diff options
author | kientzle <kientzle@FreeBSD.org> | 2008-06-15 10:45:57 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2008-06-15 10:45:57 +0000 |
commit | fc70e49ebfd776d40b338afe8257f404b59449e0 (patch) | |
tree | 9a91ef4fcb23000923100d4ae69479ce72a92b2a /lib | |
parent | bfa1b1945861a658152087251d6468ed8a8fd201 (diff) | |
download | FreeBSD-src-fc70e49ebfd776d40b338afe8257f404b59449e0.zip FreeBSD-src-fc70e49ebfd776d40b338afe8257f404b59449e0.tar.gz |
A number of minor corrections to the support for external compression
programs:
* Support platforms that have fork() but not vfork()
* Don't write(), select(), or poll() against closed file descriptors
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libarchive/archive_read_support_compression_program.c | 11 | ||||
-rw-r--r-- | lib/libarchive/archive_write_set_compression_program.c | 10 | ||||
-rw-r--r-- | lib/libarchive/filter_fork.c | 37 |
3 files changed, 45 insertions, 13 deletions
diff --git a/lib/libarchive/archive_read_support_compression_program.c b/lib/libarchive/archive_read_support_compression_program.c index 5f6cb46..5d92b90 100644 --- a/lib/libarchive/archive_read_support_compression_program.c +++ b/lib/libarchive/archive_read_support_compression_program.c @@ -28,7 +28,8 @@ __FBSDID("$FreeBSD$"); /* This capability is only available on POSIX systems. */ -#if !defined(HAVE_PIPE) || !defined(HAVE_VFORK) || !defined(HAVE_FCNTL) +#if !defined(HAVE_PIPE) || !defined(HAVE_FCNTL) || \ + !(defined(HAVE_FORK) || defined(HAVE_VFORK)) /* * On non-Posix systems, allow the program to build, but choke if @@ -177,6 +178,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); @@ -191,7 +198,7 @@ restart_read: goto restart_read; } else if (ret == 0 || (ret == -1 && errno == EPIPE)) { close(state->child_stdin); - state->child_stdout = -1; + state->child_stdin = -1; fcntl(state->child_stdout, F_SETFL, 0); goto restart_read; } else { diff --git a/lib/libarchive/archive_write_set_compression_program.c b/lib/libarchive/archive_write_set_compression_program.c index b910ef6..3cd5c93 100644 --- a/lib/libarchive/archive_write_set_compression_program.c +++ b/lib/libarchive/archive_write_set_compression_program.c @@ -28,7 +28,9 @@ __FBSDID("$FreeBSD$"); /* This capability is only available on POSIX systems. */ -#if !defined(HAVE_PIPE) || !defined(HAVE_VFORK) || !defined(HAVE_FCNTL) +#if !defined(HAVE_PIPE) || !defined(HAVE_FCNTL) || \ + !(defined(HAVE_FORK) || defined(HAVE_VFORK)) +#include "archive.h" /* * On non-Posix systems, allow the program to build, but choke if @@ -180,6 +182,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/lib/libarchive/filter_fork.c b/lib/libarchive/filter_fork.c index dde6114..caf8c31 100644 --- a/lib/libarchive/filter_fork.c +++ b/lib/libarchive/filter_fork.c @@ -26,7 +26,8 @@ #include "archive_platform.h" /* This capability is only available on POSIX systems. */ -#if defined(HAVE_PIPE) && defined(HAVE_VFORK) && defined(HAVE_FCNTL) +#if defined(HAVE_PIPE) && defined(HAVE_FCNTL) && \ + (defined(HAVE_FORK) || defined(HAVE_VFORK)) __FBSDID("$FreeBSD$"); @@ -75,7 +76,11 @@ __archive_create_child(const char *path, int *child_stdin, int *child_stdout) stdout_pipe[1] = tmp; } +#if HAVE_VFORK switch ((child = vfork())) { +#else + switch ((child = fork())) { +#endif case -1: goto stdout_opened; case 0: @@ -118,23 +123,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); |