diff options
author | shirosaki <shirosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-04-07 14:10:30 +0000 |
---|---|---|
committer | shirosaki <shirosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-04-07 14:10:30 +0000 |
commit | 42109a02f02b5e55a45df4f6bf3103c88be340cd (patch) | |
tree | 81bae35ff653d3597505c1df3324b21a6b0b1802 /process.c | |
parent | fc83ebb037bfecfd5abfd6dc92517870d65541b3 (diff) | |
download | ruby-42109a02f02b5e55a45df4f6bf3103c88be340cd.tar.gz |
* 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]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35250 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'process.c')
-rw-r--r-- | process.c | 69 |
1 files changed, 52 insertions, 17 deletions
@@ -1207,6 +1207,21 @@ rb_proc_exec(const char *str) #endif /* _WIN32 */ } +enum { + EXEC_OPTION_PGROUP, + EXEC_OPTION_RLIMIT, + EXEC_OPTION_UNSETENV_OTHERS, + EXEC_OPTION_ENV, + EXEC_OPTION_CHDIR, + EXEC_OPTION_UMASK, + EXEC_OPTION_DUP2, + EXEC_OPTION_CLOSE, + EXEC_OPTION_OPEN, + EXEC_OPTION_DUP2_CHILD, + EXEC_OPTION_CLOSE_OTHERS, + EXEC_OPTION_NEW_PGROUP +}; + #if defined(_WIN32) #define HAVE_SPAWNV 1 #endif @@ -1252,7 +1267,7 @@ proc_spawn_v(char **argv, char *prog) #endif static rb_pid_t -proc_spawn_n(int argc, VALUE *argv, VALUE prog) +proc_spawn_n(int argc, VALUE *argv, VALUE prog, VALUE options) { char **args; int i; @@ -1264,8 +1279,17 @@ proc_spawn_n(int argc, VALUE *argv, VALUE prog) args[i] = RSTRING_PTR(argv[i]); } args[i] = (char*) 0; - if (args[0]) + if (args[0]) { +#if defined(_WIN32) + DWORD flags = 0; + if (RTEST(rb_ary_entry(options, EXEC_OPTION_NEW_PGROUP))) { + flags = CREATE_NEW_PROCESS_GROUP; + } + pid = rb_w32_aspawn_flags(P_NOWAIT, prog ? RSTRING_PTR(prog) : 0, args, flags); +#else pid = proc_spawn_v(args, prog ? RSTRING_PTR(prog) : 0); +#endif + } ALLOCV_END(v); return pid; } @@ -1313,20 +1337,6 @@ hide_obj(VALUE obj) return obj; } -enum { - EXEC_OPTION_PGROUP, - EXEC_OPTION_RLIMIT, - EXEC_OPTION_UNSETENV_OTHERS, - EXEC_OPTION_ENV, - EXEC_OPTION_CHDIR, - EXEC_OPTION_UMASK, - EXEC_OPTION_DUP2, - EXEC_OPTION_CLOSE, - EXEC_OPTION_OPEN, - EXEC_OPTION_DUP2_CHILD, - EXEC_OPTION_CLOSE_OTHERS -}; - static VALUE check_exec_redirect_fd(VALUE v, int iskey) { @@ -1510,6 +1520,16 @@ rb_exec_arg_addopt(struct rb_exec_arg *e, VALUE key, VALUE val) } else #endif +#ifdef _WIN32 + if (id == rb_intern("new_pgroup")) { + if (!NIL_P(rb_ary_entry(options, EXEC_OPTION_NEW_PGROUP))) { + rb_raise(rb_eArgError, "new_pgroup option specified twice"); + } + val = RTEST(val) ? Qtrue : Qfalse; + rb_ary_store(options, EXEC_OPTION_NEW_PGROUP, val); + } + else +#endif #if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM) if (strncmp("rlimit_", rb_id2name(id), 7) == 0 && (rtype = rlimit_type_by_lname(rb_id2name(id)+7)) != -1) { @@ -3006,7 +3026,7 @@ rb_spawn_process(struct rb_exec_arg *earg, VALUE prog, char *errmsg, size_t errm pid = proc_spawn(RSTRING_PTR(prog)); } else { - pid = proc_spawn_n(argc, argv, prog); + pid = proc_spawn_n(argc, argv, prog, earg->options); } # if defined(_WIN32) if (pid == -1) @@ -3141,6 +3161,9 @@ rb_f_system(int argc, VALUE *argv) * :pgroup => true or 0 : make a new process group * :pgroup => pgid : join to specified process group * :pgroup => nil : don't change the process group (default) + * create new process group: Windows only + * :new_pgroup => true : the new process is the root process of a new process group + * :new_pgroup => false : don't create a new process group (default) * resource limit: resourcename is core, cpu, data, etc. See Process.setrlimit. * :rlimit_resourcename => limit * :rlimit_resourcename => [cur_limit, max_limit] @@ -3179,6 +3202,7 @@ rb_f_system(int argc, VALUE *argv) * If a hash is given as +options+, * it specifies * process group, + * create new process group, * resource limit, * current directory, * umask and @@ -3200,6 +3224,17 @@ rb_f_system(int argc, VALUE *argv) * pid = spawn(command, :pgroup=>true) # process leader * pid = spawn(command, :pgroup=>10) # belongs to the process group 10 * + * The <code>:new_pgroup</code> key in +options+ specifies to pass + * +CREATE_NEW_PROCESS_GROUP+ flag to <code>CreateProcessW()</code> that is + * Windows API. This option is only for Windows. + * true means the new process is the root process of the new process group. + * The new process has CTRL+C disabled. This flag is necessary for + * <code>Process.kill(:SIGINT, pid)</code> on the subprocess. + * :new_pgroup is false by default. + * + * pid = spawn(command, :new_pgroup=>true) # new process group + * pid = spawn(command, :new_pgroup=>false) # same process group + * * The <code>:rlimit_</code><em>foo</em> key specifies a resource limit. * <em>foo</em> should be one of resource types such as <code>core</code>. * The corresponding value should be an integer or an array which have one or |