Permalink
Browse files

pspawn supports all :pgroup => pgid options

  • Loading branch information...
1 parent f649812 commit cd2b655be51fc6a8c17df6d243bb276109257eb6 @rtomayko committed Mar 9, 2011
Showing with 77 additions and 6 deletions.
  1. +6 −6 README.md
  2. +40 −0 ext/posix-spawn.c
  3. +31 −0 test/test_spawn.rb
View
@@ -179,6 +179,12 @@ These `Process::spawn` arguments are currently supported to any of
clearing environment variables:
:unsetenv_others => true : clear environment variables except specified by env
:unsetenv_others => false : don't clear (default)
+ current directory:
+ :chdir => str
+ process group:
+ :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)
redirection:
key:
FD : single file descriptor in child process
@@ -196,16 +202,10 @@ These `Process::spawn` arguments are currently supported to any of
:err : the file descriptor 2 which is the standard error
integer : the file descriptor of specified the integer
io : the file descriptor specified as io.fileno
- current directory:
- :chdir => str
These options are currently NOT supported:
options: hash
- process group:
- :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)
resource limit: resourcename is core, cpu, data, etc. See Process.setrlimit.
:rlimit_resourcename => limit
:rlimit_resourcename => [cur_limit, max_limit]
View
@@ -208,6 +208,42 @@ posixspawn_file_actions_init(posix_spawn_file_actions_t *fops, VALUE options)
rb_hash_foreach(options, posixspawn_file_actions_operations_iter, (VALUE)fops);
}
+/*
+ * Initialize pgroup related flags in the posix_spawnattr struct based on the
+ * options Hash.
+ *
+ * :pgroup => 0 | true - spawned process is in a new process group with the
+ * same id as the new process's pid.
+ * :pgroup => pgid - spawned process is in a new process group with id
+ * pgid.
+ * :pgroup => nil - spawned process has the same pgid as the parent
+ * process (this is the default).
+ *
+ * The options Hash is modified in place with the :pgroup key being removed.
+ */
+static void
+posixspawn_set_pgroup(VALUE options, posix_spawnattr_t *pattr, short *pflags)
+{
+ VALUE pgroup_val;
+ pgroup_val = rb_hash_delete(options, ID2SYM(rb_intern("pgroup")));
+
+ switch (TYPE(pgroup_val)) {
+ case T_TRUE:
+ (*pflags) |= POSIX_SPAWN_SETPGROUP;
+ posix_spawnattr_setpgroup(pattr, 0);
+ break;
+ case T_FIXNUM:
+ (*pflags) |= POSIX_SPAWN_SETPGROUP;
+ posix_spawnattr_setpgroup(pattr, FIX2INT(pgroup_val));
+ break;
+ case T_NIL:
+ break;
+ default:
+ rb_raise(rb_eTypeError, ":pgroup option is invalid");
+ break;
+ }
+}
+
static int
each_env_check_i(VALUE key, VALUE val, VALUE arg)
{
@@ -366,6 +402,10 @@ rb_posixspawn_pspawn(VALUE self, VALUE env, VALUE argv, VALUE options)
*/
flags |= POSIX_SPAWN_USEVFORK;
#endif
+
+ /* setup pgroup options */
+ posixspawn_set_pgroup(options, &attr, &flags);
+
posix_spawnattr_setflags(&attr, flags);
if (RTEST(dirname = rb_hash_delete(options, ID2SYM(rb_intern("chdir"))))) {
View
@@ -270,6 +270,37 @@ def test_spawn_redirect_fd_to_file_with_symbolic_name_and_flags
end
##
+ # :pgroup => <pgid>
+
+ def test_spawn_inherit_pgroup_from_parent_by_default
+ pgrp = Process.getpgrp
+ pid = _spawn("ruby", "-e", "exit(Process.getpgrp == #{pgrp} ? 0 : 1)")
+ assert_process_exit_ok pid
+ end
+
+ def test_spawn_inherit_pgroup_from_parent_when_nil
+ pgrp = Process.getpgrp
+ pid = _spawn("ruby", "-e", "exit(Process.getpgrp == #{pgrp} ? 0 : 1)", :pgroup => nil)
+ assert_process_exit_ok pid
+ end
+
+ def test_spawn_new_pgroup_with_true
+ pid = _spawn("ruby", "-e", "exit(Process.getpgrp == $$ ? 0 : 1)", :pgroup => true)
+ assert_process_exit_ok pid
+ end
+
+ def test_spawn_new_pgroup_with_zero
+ pid = _spawn("ruby", "-e", "exit(Process.getpgrp == $$ ? 0 : 1)", :pgroup => 0)
+ assert_process_exit_ok pid
+ end
+
+ def test_spawn_explicit_pgroup
+ pgrp = Process.getpgrp
+ pid = _spawn("ruby", "-e", "exit(Process.getpgrp == #{pgrp} ? 0 : 1)", :pgroup => pgrp)
+ assert_process_exit_ok pid
+ end
+
+ ##
# Exceptions
def test_spawn_raises_exception_on_unsupported_options

0 comments on commit cd2b655

Please sign in to comment.