diff --git a/BUILD b/BUILD index d4fcd4e8c897a69902056e236129b842e2af46fd..c40ee518bba3007c7becc9c3e6f2781f68f9c09a 100644 --- a/BUILD +++ b/BUILD @@ -84,6 +84,7 @@ cc_library( "src/core/support/string_posix.c", "src/core/support/string_win32.c", "src/core/support/subprocess_posix.c", + "src/core/support/subprocess_windows.c", "src/core/support/sync.c", "src/core/support/sync_posix.c", "src/core/support/sync_win32.c", @@ -1158,6 +1159,7 @@ objc_library( "src/core/support/string_posix.c", "src/core/support/string_win32.c", "src/core/support/subprocess_posix.c", + "src/core/support/subprocess_windows.c", "src/core/support/sync.c", "src/core/support/sync_posix.c", "src/core/support/sync_win32.c", diff --git a/Makefile b/Makefile index 40cbdfa896854e975b06ef95d73acf2c469d4851..794778dae480681fcfa9999661d5dcf27c2bc0b6 100644 --- a/Makefile +++ b/Makefile @@ -2235,6 +2235,7 @@ LIBGPR_SRC = \ src/core/support/string_posix.c \ src/core/support/string_win32.c \ src/core/support/subprocess_posix.c \ + src/core/support/subprocess_windows.c \ src/core/support/sync.c \ src/core/support/sync_posix.c \ src/core/support/sync_win32.c \ diff --git a/binding.gyp b/binding.gyp index 036d37b891f9e471209d40b59c4f32afe1c7b531..133f8f48624570eb5ca6bca9b2bd199cea293bf6 100644 --- a/binding.gyp +++ b/binding.gyp @@ -516,6 +516,7 @@ 'src/core/support/string_posix.c', 'src/core/support/string_win32.c', 'src/core/support/subprocess_posix.c', + 'src/core/support/subprocess_windows.c', 'src/core/support/sync.c', 'src/core/support/sync_posix.c', 'src/core/support/sync_win32.c', diff --git a/build.yaml b/build.yaml index 42776a73e93a3449b0fe1e4a4ed80cd4b4dcc051..f8d18fbb9a681cf7f725f0f821e920a9459a91f7 100644 --- a/build.yaml +++ b/build.yaml @@ -499,6 +499,7 @@ libs: - src/core/support/string_posix.c - src/core/support/string_win32.c - src/core/support/subprocess_posix.c + - src/core/support/subprocess_windows.c - src/core/support/sync.c - src/core/support/sync_posix.c - src/core/support/sync_win32.c diff --git a/gRPC.podspec b/gRPC.podspec index f33aa076e235135688ff38cba4a6bcd3087fab0c..30b278798a1d0b3c8876c8bda798a72d330eb09d 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -151,6 +151,7 @@ Pod::Spec.new do |s| 'src/core/support/string_posix.c', 'src/core/support/string_win32.c', 'src/core/support/subprocess_posix.c', + 'src/core/support/subprocess_windows.c', 'src/core/support/sync.c', 'src/core/support/sync_posix.c', 'src/core/support/sync_win32.c', diff --git a/grpc.gemspec b/grpc.gemspec index 97abccae48c88053e691d8238b8f8d729673540f..585d3ec9090d613950f96fb93a469b433a6e92a1 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -134,6 +134,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/support/string_posix.c ) s.files += %w( src/core/support/string_win32.c ) s.files += %w( src/core/support/subprocess_posix.c ) + s.files += %w( src/core/support/subprocess_windows.c ) s.files += %w( src/core/support/sync.c ) s.files += %w( src/core/support/sync_posix.c ) s.files += %w( src/core/support/sync_win32.c ) diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 7333405db3d63b6a2b66a30b20c5f377d1780d06..30edbc7251f53bf947dff17663da5c86183a66a1 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -80,6 +80,7 @@ #define GPR_ARCH_64 1 #define GPR_GETPID_IN_PROCESS_H 1 #define GPR_WINSOCK_SOCKET 1 +#define GPR_WINDOWS_SUBPROCESS 1 #ifdef __GNUC__ #define GPR_GCC_ATOMIC 1 #define GPR_GCC_TLS 1 @@ -94,6 +95,7 @@ #define GPR_WIN32 1 #define GPR_GETPID_IN_PROCESS_H 1 #define GPR_WINSOCK_SOCKET 1 +#define GPR_WINDOWS_SUBPROCESS 1 #ifdef __GNUC__ #define GPR_GCC_ATOMIC 1 #define GPR_GCC_TLS 1 diff --git a/package.json b/package.json index 5b80a4875b2945c8335afa50cce0020c761d8ac1..0a3440e6e4cf20668bdb07dc74458dffecd3734c 100644 --- a/package.json +++ b/package.json @@ -491,6 +491,7 @@ "src/core/support/string_posix.c", "src/core/support/string_win32.c", "src/core/support/subprocess_posix.c", + "src/core/support/subprocess_windows.c", "src/core/support/sync.c", "src/core/support/sync_posix.c", "src/core/support/sync_win32.c", diff --git a/src/core/support/subprocess_windows.c b/src/core/support/subprocess_windows.c new file mode 100644 index 0000000000000000000000000000000000000000..d48c5437f0fecf35994c69ac65e921270d4e3d7c --- /dev/null +++ b/src/core/support/subprocess_windows.c @@ -0,0 +1,141 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <grpc/support/port_platform.h> + +#ifdef GPR_WINDOWS_SUBPROCESS + +#include <windows.h> +#include <string.h> +#include <tchar.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/subprocess.h> +#include "src/core/support/string.h" +#include "src/core/support/string_win32.h" + +struct gpr_subprocess { + PROCESS_INFORMATION pi; + int joined; + int interrupted; +}; + +const char *gpr_subprocess_binary_extension() { return ".exe"; } + +gpr_subprocess *gpr_subprocess_create(int argc, const char **argv) { + gpr_subprocess *r; + + STARTUPINFO si; + PROCESS_INFORMATION pi; + + char *args = gpr_strjoin_sep(argv, argc, " ", NULL); + TCHAR *args_tchar; + + args_tchar = gpr_char_to_tchar(args); + gpr_free(args); + + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + memset(&pi, 0, sizeof(pi)); + + if (!CreateProcess(NULL, args_tchar, NULL, NULL, FALSE, + CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi)) { + gpr_free(args_tchar); + return NULL; + } + gpr_free(args_tchar); + + r = gpr_malloc(sizeof(gpr_subprocess)); + memset(r, 0, sizeof(*r)); + r->pi = pi; + return r; +} + +void gpr_subprocess_destroy(gpr_subprocess *p) { + if (p) { + if (!p->joined) { + gpr_subprocess_interrupt(p); + gpr_subprocess_join(p); + } + if (p->pi.hProcess) { + CloseHandle(p->pi.hProcess); + } + if (p->pi.hThread) { + CloseHandle(p->pi.hThread); + } + gpr_free(p); + } +} + +int gpr_subprocess_join(gpr_subprocess *p) { + DWORD dwExitCode; + if (GetExitCodeProcess(p->pi.hProcess, &dwExitCode)) { + if (dwExitCode == STILL_ACTIVE) { + if (WaitForSingleObject(p->pi.hProcess, INFINITE) == WAIT_OBJECT_0) { + p->joined = 1; + goto getExitCode; + } + return -1; // failed to join + } else { + goto getExitCode; + } + } else { + return -1; // failed to get exit code + } + +getExitCode: + if (p->interrupted) { + return 0; + } + if (GetExitCodeProcess(p->pi.hProcess, &dwExitCode)) { + return dwExitCode; + } else { + return -1; // failed to get exit code + } +} + +void gpr_subprocess_interrupt(gpr_subprocess *p) { + DWORD dwExitCode; + if (GetExitCodeProcess(p->pi.hProcess, &dwExitCode)) { + if (dwExitCode == STILL_ACTIVE) { + gpr_log(GPR_INFO, "sending ctrl-break"); + GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, p->pi.dwProcessId); + p->joined = 1; + p->interrupted = 1; + } + } + return; +} + +#endif /* GPR_WINDOWS_SUBPROCESS */ diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index d26a8647dc9748d224221f5dda9f60cb9965a405..708091df9f1eba11a7f2a5219a81aec6deb4875d 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -60,6 +60,7 @@ CORE_SOURCE_FILES = [ 'src/core/support/string_posix.c', 'src/core/support/string_win32.c', 'src/core/support/subprocess_posix.c', + 'src/core/support/subprocess_windows.c', 'src/core/support/sync.c', 'src/core/support/sync_posix.c', 'src/core/support/sync_win32.c', diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 1585bdeac44e425b63a8d57ae12304470cb2f44e..cd49a1980dc26e9e369affbf31551f0750f3861a 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1139,6 +1139,7 @@ src/core/support/string.c \ src/core/support/string_posix.c \ src/core/support/string_win32.c \ src/core/support/subprocess_posix.c \ +src/core/support/subprocess_windows.c \ src/core/support/sync.c \ src/core/support/sync_posix.c \ src/core/support/sync_win32.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 1654228e39611e70298a935e706d4385fa8eaecb..aef0023a3e5c403ae697dfa488b94c101bc058c8 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -2916,6 +2916,7 @@ "src/core/support/string_win32.c", "src/core/support/string_win32.h", "src/core/support/subprocess_posix.c", + "src/core/support/subprocess_windows.c", "src/core/support/sync.c", "src/core/support/sync_posix.c", "src/core/support/sync_win32.c", diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj b/vsprojects/vcxproj/gpr/gpr.vcxproj index cba35888905936f36bffe7b0a70022eed74a3564..b20d6ff77f53946b541b3f957193514464325a7d 100644 --- a/vsprojects/vcxproj/gpr/gpr.vcxproj +++ b/vsprojects/vcxproj/gpr/gpr.vcxproj @@ -269,6 +269,8 @@ </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\support\subprocess_posix.c"> </ClCompile> + <ClCompile Include="$(SolutionDir)\..\src\core\support\subprocess_windows.c"> + </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\support\sync.c"> </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\support\sync_posix.c"> diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters index 1f8b09a1e9a40b4460e1ce27e561b838655fd39d..85d8ec8672952d438d48f34845f871e5e2e27f58 100644 --- a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters +++ b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters @@ -91,6 +91,9 @@ <ClCompile Include="$(SolutionDir)\..\src\core\support\subprocess_posix.c"> <Filter>src\core\support</Filter> </ClCompile> + <ClCompile Include="$(SolutionDir)\..\src\core\support\subprocess_windows.c"> + <Filter>src\core\support</Filter> + </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\support\sync.c"> <Filter>src\core\support</Filter> </ClCompile>