merge revision(s) 35249,35250: [Backport #6296]

* include/ruby/win32.h (rb_w32_aspawn_flags): add the declaration of
	  new function.

	* process.c (enum): add EXEC_OPTION_PGROUP and move the position
	  above for the usage in proc_spawn_n().

	* process.c (proc_spawn_n): add an argument to pass new option
	  `new_pgroup`. The option specifies CREATE_NEW_PROCESS_GROUP flag to
	  CreateProcessW(). This flag is necessary for the usage of
	  Process.kill on the subprocess on Windows.

	* process.c (rb_exec_arg_addopt): ditto.

	* process.c (rb_spawn_process): ditto.

	* process.c (documentation for rb_f_spawn): add documentation for new
	  option `new_pgroup` of spawn.

	* test/ruby/test_process.rb (TestProcess#test_execopts_new_pgroup):
	  add tests for option `new_pgroup`.

	* test/ruby/test_thread.rb
	  (TestThreadGroup#test_thread_timer_and_interrupt):
	  add option `new_pgroup: true` to spawn on Windows. It's needed for
	  Process.kill on a subprocess.

	* win32/win32.c (CreateChild): add an argument to pass
	  dwCreationFlags of CreateProcessW().

	* win32/win32.c (rb_w32_spawn): ditto.

	* win32/win32.c (rb_w32_aspawn_flags): add new function to pass
	  dwCreationFlags.

	* win32/win32.c (rb_w32_aspawn): refactor to move the content to
	  rb_w32_aspawn_flags().
	  [ruby-core:43245][Bug #6131]

	* test/ruby/test_thread.rb
	  (TestThreadGroup#test_thread_timer_and_interrupt): skip on Windows.
	  Process.kill cannot kill a subprocess if CREATE_NEW_PROCESS_GROUP
	  flag is not specified in a call to CreateProcessW().

	* win32/win32.c (CreateChild): revert the usage of
	  CREATE_NEW_PROCESS_GROUP flag for compatibility.
	  [ruby-core:43245][Bug #6131]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@35332 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
naruse 2012-04-14 21:47:27 +00:00
parent 7201291187
commit 97d00bcdee
7 changed files with 130 additions and 26 deletions

View file

@ -63,7 +63,7 @@
#define TO_SOCKET(x) _get_osfhandle(x)
static struct ChildRecord *CreateChild(const WCHAR *, const WCHAR *, SECURITY_ATTRIBUTES *, HANDLE, HANDLE, HANDLE);
static struct ChildRecord *CreateChild(const WCHAR *, const WCHAR *, SECURITY_ATTRIBUTES *, HANDLE, HANDLE, HANDLE, DWORD);
static int has_redirection(const char *);
int rb_w32_wait_events(HANDLE *events, int num, DWORD timeout);
static int rb_w32_open_osfhandle(intptr_t osfhandle, int flags);
@ -1008,10 +1008,9 @@ child_result(struct ChildRecord *child, int mode)
static struct ChildRecord *
CreateChild(const WCHAR *cmd, const WCHAR *prog, SECURITY_ATTRIBUTES *psa,
HANDLE hInput, HANDLE hOutput, HANDLE hError)
HANDLE hInput, HANDLE hOutput, HANDLE hError, DWORD dwCreationFlags)
{
BOOL fRet;
DWORD dwCreationFlags;
STARTUPINFOW aStartupInfo;
PROCESS_INFORMATION aProcessInformation;
SECURITY_ATTRIBUTES sa;
@ -1058,7 +1057,7 @@ CreateChild(const WCHAR *cmd, const WCHAR *prog, SECURITY_ATTRIBUTES *psa,
aStartupInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
}
dwCreationFlags = (CREATE_NEW_PROCESS_GROUP | NORMAL_PRIORITY_CLASS);
dwCreationFlags |= NORMAL_PRIORITY_CLASS;
if (lstrlenW(cmd) > 32767) {
child->pid = 0; /* release the slot */
@ -1209,14 +1208,14 @@ rb_w32_spawn(int mode, const char *cmd, const char *prog)
wshell = shell ? acp_to_wstr(shell, NULL) : NULL;
if (v2) ALLOCV_END(v2);
ret = child_result(CreateChild(wcmd, wshell, NULL, NULL, NULL, NULL), mode);
ret = child_result(CreateChild(wcmd, wshell, NULL, NULL, NULL, NULL, 0), mode);
free(wshell);
free(wcmd);
return ret;
}
rb_pid_t
rb_w32_aspawn(int mode, const char *prog, char *const *argv)
rb_w32_aspawn_flags(int mode, const char *prog, char *const *argv, DWORD flags)
{
int c_switch = 0;
size_t len;
@ -1275,12 +1274,19 @@ rb_w32_aspawn(int mode, const char *prog, char *const *argv)
if (v) ALLOCV_END(v);
wprog = prog ? acp_to_wstr(prog, NULL) : NULL;
ret = child_result(CreateChild(wcmd, wprog, NULL, NULL, NULL, NULL), mode);
ret = child_result(CreateChild(wcmd, wprog, NULL, NULL, NULL, NULL, flags), mode);
free(wprog);
free(wcmd);
return ret;
}
rb_pid_t
rb_w32_aspawn(int mode, const char *prog, char *const *argv)
{
return rb_w32_aspawn_flags(mode, prog, argv, 0);
}
/* License: Artistic or GPL */
typedef struct _NtCmdLineElement {
struct _NtCmdLineElement *next;
char *str;