summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-06-22 11:30:29 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-06-22 11:30:29 +0000
commitbcadfd9c083c8893dcc428cbd969809c1db8dac1 (patch)
tree9de7b46ea4077441e292d85f01f4b4da7de4c249
parent7b036a8ea78e713adbd29778612693d405b91813 (diff)
* internal.h (rb_execarg): add pgroup_given and pgroup_pgid fields.
* process.c (EXEC_OPTION_PGROUP): removed. (rb_execarg_addopt): update the new fields, instead of options array. (run_exec_pgroup): take a struct rb_execarg argument. refer the new fields. (rb_execarg_run_options): follow run_exec_pgroup change. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36181 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog10
-rw-r--r--internal.h2
-rw-r--r--process.c34
3 files changed, 31 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog
index e2228ee4b7..1bf97728e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Fri Jun 22 20:27:39 2012 Tanaka Akira <akr@fsij.org>
+
+ * internal.h (rb_execarg): add pgroup_given and pgroup_pgid fields.
+
+ * process.c (EXEC_OPTION_PGROUP): removed.
+ (rb_execarg_addopt): update the new fields, instead of options array.
+ (run_exec_pgroup): take a struct rb_execarg argument. refer the new
+ fields.
+ (rb_execarg_run_options): follow run_exec_pgroup change.
+
Fri Jun 22 18:48:51 2012 Kouhei Sutou <kou@cozmixng.org>
* README.EXT, README.EXT.ja: use "sval" for the third argument
diff --git a/internal.h b/internal.h
index 1c73eadb84..3d7a68c95b 100644
--- a/internal.h
+++ b/internal.h
@@ -176,7 +176,9 @@ struct rb_execarg {
VALUE envp_str;
VALUE envp_buf;
VALUE dup2_tmpbuf;
+ unsigned pgroup_given : 1;
unsigned umask_given : 1;
+ pid_t pgroup_pgid; /* asis(-1), new pgroup(0), specified pgroup (0<V). */
mode_t umask_mask;
};
diff --git a/process.c b/process.c
index fd0e6c9d93..2f73a9e496 100644
--- a/process.c
+++ b/process.c
@@ -1254,7 +1254,6 @@ rb_proc_exec(const char *str)
}
enum {
- EXEC_OPTION_PGROUP,
EXEC_OPTION_RLIMIT,
EXEC_OPTION_UNSETENV_OTHERS,
EXEC_OPTION_ENV,
@@ -1559,21 +1558,22 @@ rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
id = SYM2ID(key);
#ifdef HAVE_SETPGID
if (id == rb_intern("pgroup")) {
- if (!NIL_P(rb_ary_entry(options, EXEC_OPTION_PGROUP))) {
+ pid_t pgroup;
+ if (e->pgroup_given) {
rb_raise(rb_eArgError, "pgroup option specified twice");
}
if (!RTEST(val))
- val = Qfalse;
+ pgroup = -1; /* asis(-1) means "don't call setpgid()". */
else if (val == Qtrue)
- val = INT2FIX(0);
+ pgroup = 0; /* new process group. */
else {
- pid_t pgroup = NUM2PIDT(val);
+ pgroup = NUM2PIDT(val);
if (pgroup < 0) {
rb_raise(rb_eArgError, "negative process group ID : %ld", (long)pgroup);
}
- val = PIDT2NUM(pgroup);
}
- rb_ary_store(options, EXEC_OPTION_PGROUP, val);
+ e->pgroup_given = 1;
+ e->pgroup_pgid = pgroup;
}
else
#endif
@@ -2626,22 +2626,27 @@ run_exec_dup2_child(VALUE ary, struct rb_execarg *s, char *errmsg, size_t errmsg
#ifdef HAVE_SETPGID
/* This function should be async-signal-safe when _save_ is Qnil. Actually it is. */
static int
-run_exec_pgroup(VALUE obj, struct rb_execarg *s, char *errmsg, size_t errmsg_buflen)
+run_exec_pgroup(const struct rb_execarg *e, struct rb_execarg *s, char *errmsg, size_t errmsg_buflen)
{
/*
* If FD_CLOEXEC is available, rb_fork waits the child's execve.
* So setpgid is done in the child when rb_fork is returned in the parent.
* No race condition, even without setpgid from the parent.
- * (Is there an environment which has setpgid but FD_CLOEXEC?)
+ * (Is there an environment which has setpgid but no FD_CLOEXEC?)
*/
int ret;
pid_t pgroup;
+
+ pgroup = e->pgroup_pgid;
+ if (pgroup == -1)
+ return 0;
+
if (s) {
- VALUE save = s->options;
/* maybe meaningless with no fork environment... */
- rb_ary_store(save, EXEC_OPTION_PGROUP, PIDT2NUM(getpgrp()));
+ s->pgroup_given = 1;
+ s->pgroup_pgid = getpgrp();
}
- pgroup = NUM2PIDT(obj);
+
if (pgroup == 0) {
pgroup = getpid(); /* async-signal-safe */
}
@@ -2735,9 +2740,8 @@ rb_execarg_run_options(const struct rb_execarg *e, struct rb_execarg *s, char *e
}
#ifdef HAVE_SETPGID
- obj = rb_ary_entry(options, EXEC_OPTION_PGROUP);
- if (RTEST(obj)) {
- if (run_exec_pgroup(obj, s, errmsg, errmsg_buflen) == -1) /* async-signal-safe */
+ if (e->pgroup_given) {
+ if (run_exec_pgroup(e, s, errmsg, errmsg_buflen) == -1) /* async-signal-safe */
return -1;
}
#endif