From 34bee8175513f5b06c652c2fa9007bcaf93ee680 Mon Sep 17 00:00:00 2001 From: Emil Velikov Date: Sat, 25 Apr 2020 15:42:45 +0100 Subject: [PATCH] Call OpenProcess() from within __archive_create_child() Move the Windows specific to the Windows version of the helper, making the existing code shorter and simpler. This means that the child "handle" type will vary across the two platforms - something that we've already been doing with waitpid. Signed-off-by: Emil Velikov --- .../archive_read_support_filter_program.c | 18 +----------------- libarchive/archive_write_add_filter_program.c | 17 +---------------- libarchive/filter_fork.h | 4 ++++ libarchive/filter_fork_windows.c | 11 +++++++++-- 4 files changed, 15 insertions(+), 35 deletions(-) diff --git a/libarchive/archive_read_support_filter_program.c b/libarchive/archive_read_support_filter_program.c index 29c8a489a..bf5b6f2b3 100644 --- a/libarchive/archive_read_support_filter_program.c +++ b/libarchive/archive_read_support_filter_program.c @@ -400,7 +400,6 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd) static const size_t out_buf_len = 65536; char *out_buf; const char *prefix = "Program: "; - pid_t child; int ret; size_t l; @@ -428,7 +427,7 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd) state->out_buf_len = out_buf_len; ret = __archive_create_child(cmd, &state->child_stdin, - &state->child_stdout, &child); + &state->child_stdout, &state->child); if (ret != ARCHIVE_OK) { free(state->out_buf); archive_string_free(&state->description); @@ -438,21 +437,6 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd) cmd); return (ARCHIVE_FATAL); } -#if defined(_WIN32) && !defined(__CYGWIN__) - state->child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, child); - if (state->child == NULL) { - child_stop(self, state); - free(state->out_buf); - archive_string_free(&state->description); - free(state); - archive_set_error(&self->archive->archive, EINVAL, - "Can't initialize filter; unable to run program \"%s\"", - cmd); - return (ARCHIVE_FATAL); - } -#else - state->child = child; -#endif self->data = state; self->read = program_filter_read; diff --git a/libarchive/archive_write_add_filter_program.c b/libarchive/archive_write_add_filter_program.c index f64ae4a20..3dac86dc3 100644 --- a/libarchive/archive_write_add_filter_program.c +++ b/libarchive/archive_write_add_filter_program.c @@ -211,7 +211,6 @@ int __archive_write_program_open(struct archive_write_filter *f, struct archive_write_program_data *data, const char *cmd) { - pid_t child; int ret; if (data->child_buf == NULL) { @@ -227,26 +226,12 @@ __archive_write_program_open(struct archive_write_filter *f, } ret = __archive_create_child(cmd, &data->child_stdin, - &data->child_stdout, &child); + &data->child_stdout, &data->child); if (ret != ARCHIVE_OK) { archive_set_error(f->archive, EINVAL, "Can't launch external program: %s", cmd); return (ARCHIVE_FATAL); } -#if defined(_WIN32) && !defined(__CYGWIN__) - data->child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, child); - if (data->child == NULL) { - close(data->child_stdin); - data->child_stdin = -1; - close(data->child_stdout); - data->child_stdout = -1; - archive_set_error(f->archive, EINVAL, - "Can't launch external program: %s", cmd); - return (ARCHIVE_FATAL); - } -#else - data->child = child; -#endif return (ARCHIVE_OK); } diff --git a/libarchive/filter_fork.h b/libarchive/filter_fork.h index be1bc7e8e..2bf290c4d 100644 --- a/libarchive/filter_fork.h +++ b/libarchive/filter_fork.h @@ -34,7 +34,11 @@ int __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, +#if defined(_WIN32) && !defined(__CYGWIN__) + HANDLE *out_child); +#else pid_t *out_child); +#endif void __archive_check_child(int in, int out); diff --git a/libarchive/filter_fork_windows.c b/libarchive/filter_fork_windows.c index 7db1a0018..8d11179f3 100644 --- a/libarchive/filter_fork_windows.c +++ b/libarchive/filter_fork_windows.c @@ -33,7 +33,7 @@ int __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, - pid_t *out_child) + HANDLE *out_child) { HANDLE childStdout[2], childStdin[2],childStderr; SECURITY_ATTRIBUTES secAtts; @@ -45,6 +45,7 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, char *arg0, *ext; int i, l; DWORD fl, fl_old; + HANDLE child; childStdout[0] = childStdout[1] = INVALID_HANDLE_VALUE; childStdin[0] = childStdin[1] = INVALID_HANDLE_VALUE; @@ -155,13 +156,19 @@ __archive_create_child(const char *cmd, int *child_stdin, int *child_stdout, *child_stdout = _open_osfhandle((intptr_t)childStdout[0], _O_RDONLY); *child_stdin = _open_osfhandle((intptr_t)childStdin[1], _O_WRONLY); + child = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, + childInfo.dwProcessId); + if (child == NULL) // INVALID_HANDLE_VALUE ? + goto fail; + + *out_child = child; + CloseHandle(childStdout[1]); CloseHandle(childStdin[0]); archive_string_free(&cmdline); archive_string_free(&fullpath); __archive_cmdline_free(acmd); - *out_child = childInfo.dwProcessId; return ARCHIVE_OK; fail: -- 2.47.2