diff --git a/BUILD b/BUILD index 459aebd820d021833ce22c582b7894f8b00000b7..727b137321cc615a7dc41eeb9cc9e9208fede42b 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", @@ -1154,6 +1155,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 31559d5c65226e51c297602031183e79faeed31f..a0be756c47670b2f52f2c0cc7dfd35f2287a0475 100644 --- a/Makefile +++ b/Makefile @@ -2231,6 +2231,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 651c2e13af35e0eed53dfbbcc7e1b189d4d9012c..ad8015dc85be285e6379ea2de87c379333d78567 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 1b3cb7920281909c00ceb12f58d92a9928fad985..b20f915c54c51d5988ef9017acf879fd55347d04 100644 --- a/build.yaml +++ b/build.yaml @@ -497,6 +497,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 922b246c54cbb6aa222446c42e041f583dbd709a..0bce6bdd212d2c4c7bba190915ce27fb3fbd2f5c 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 7f11ec778a554f4c651f7aa91fc45665e937dacd..ccd647113aa75c438d9570f042dbfc58abd60891 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..ad1cd8594dd5eede0a8adc63436ce5a51f80d56d 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 diff --git a/package.json b/package.json index f02a100bc7a46b43431e00acdbb35270848bf582..a0a44e1bd6baf055e2753fbb01e143a3b3b379ed 100644 --- a/package.json +++ b/package.json @@ -489,6 +489,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..b4b86565949f7624bb1b672863ac04a70c476fe4 --- /dev/null +++ b/src/core/support/subprocess_windows.c @@ -0,0 +1,141 @@ +/* + * + * Copyright 2015, 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 98ab1ff7f0e8424bff14c4aafa895717f1a3e190..04ed27002b6229991df9651ba5d5301fc697c310 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 11dc33a4630dd84003f0466baf1f6be69d6f2149..76b6644273883271b81a4808cd9fafd415e59b01 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1137,6 +1137,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 9113f1ca057e39c7153feb431f0aefaa200f73e2..1e1d2bb788e95145d8cff96bbe31bea269e6f17d 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -2902,6 +2902,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>