summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2008-06-15 10:45:57 +0000
committerkientzle <kientzle@FreeBSD.org>2008-06-15 10:45:57 +0000
commitfc70e49ebfd776d40b338afe8257f404b59449e0 (patch)
tree9a91ef4fcb23000923100d4ae69479ce72a92b2a /lib
parentbfa1b1945861a658152087251d6468ed8a8fd201 (diff)
downloadFreeBSD-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.c11
-rw-r--r--lib/libarchive/archive_write_set_compression_program.c10
-rw-r--r--lib/libarchive/filter_fork.c37
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);
OpenPOWER on IntegriCloud