mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* process.c (rb_exec_arg_fixup): allocate a temporary buffer for
run_exec_dup2 here because it should be async-signal-safe. (run_exec_dup2): use the temporary buffer. (run_exec_dup2_tmpbuf_size): new function. * include/ruby/intern.h (rb_exec_arg): add dup2_tmpbuf field. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35923 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
2073258a7d
commit
ad5bfed17c
3 changed files with 43 additions and 19 deletions
|
|
@ -1,3 +1,12 @@
|
|||
Tue Jun 5 21:57:22 2012 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* process.c (rb_exec_arg_fixup): allocate a temporary buffer for
|
||||
run_exec_dup2 here because it should be async-signal-safe.
|
||||
(run_exec_dup2): use the temporary buffer.
|
||||
(run_exec_dup2_tmpbuf_size): new function.
|
||||
|
||||
* include/ruby/intern.h (rb_exec_arg): add dup2_tmpbuf field.
|
||||
|
||||
Tue Jun 5 20:13:15 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* object.c (rb_obj_init_copy): should check if trusted too.
|
||||
|
|
|
|||
|
|
@ -598,6 +598,7 @@ struct rb_exec_arg {
|
|||
VALUE argv_buf;
|
||||
VALUE envp_str;
|
||||
VALUE envp_buf;
|
||||
VALUE dup2_tmpbuf;
|
||||
};
|
||||
int rb_proc_exec_n(int, VALUE*, const char*);
|
||||
int rb_proc_exec(const char*);
|
||||
|
|
|
|||
52
process.c
52
process.c
|
|
@ -1870,13 +1870,25 @@ fill_envp_buf_i(st_data_t st_key, st_data_t st_val, st_data_t arg)
|
|||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
static long run_exec_dup2_tmpbuf_size(long n);
|
||||
|
||||
void
|
||||
rb_exec_arg_fixup(struct rb_exec_arg *e)
|
||||
{
|
||||
VALUE unsetenv_others, envopts;
|
||||
VALUE ary;
|
||||
|
||||
e->redirect_fds = check_exec_fds(e->options);
|
||||
|
||||
ary = rb_ary_entry(e->options, EXEC_OPTION_DUP2);
|
||||
if (!NIL_P(ary)) {
|
||||
size_t len = run_exec_dup2_tmpbuf_size(RARRAY_LEN(ary));
|
||||
VALUE tmpbuf = hide_obj(rb_str_new(0, len));
|
||||
rb_str_set_len(tmpbuf, len);
|
||||
e->dup2_tmpbuf = tmpbuf;
|
||||
}
|
||||
|
||||
unsetenv_others = rb_ary_entry(e->options, EXEC_OPTION_UNSETENV_OTHERS);
|
||||
envopts = rb_ary_entry(e->options, EXEC_OPTION_ENV);
|
||||
if (RTEST(unsetenv_others) || !NIL_P(envopts)) {
|
||||
|
|
@ -2110,26 +2122,30 @@ intrcmp(const void *a, const void *b)
|
|||
return *(int*)b - *(int*)a;
|
||||
}
|
||||
|
||||
struct run_exec_dup2_fd_pair {
|
||||
int oldfd;
|
||||
int newfd;
|
||||
long older_index;
|
||||
long num_newer;
|
||||
};
|
||||
|
||||
static long
|
||||
run_exec_dup2_tmpbuf_size(long n)
|
||||
{
|
||||
return sizeof(struct run_exec_dup2_fd_pair) * n;
|
||||
}
|
||||
|
||||
/* This function should be async-signal-safe when _save_ is not Qnil. */
|
||||
static int
|
||||
run_exec_dup2(VALUE ary, VALUE save, char *errmsg, size_t errmsg_buflen)
|
||||
run_exec_dup2(VALUE ary, VALUE tmpbuf, VALUE save, char *errmsg, size_t errmsg_buflen)
|
||||
{
|
||||
long n, i;
|
||||
int ret;
|
||||
int extra_fd = -1;
|
||||
struct fd_pair {
|
||||
int oldfd;
|
||||
int newfd;
|
||||
long older_index;
|
||||
long num_newer;
|
||||
} *pairs = 0;
|
||||
struct run_exec_dup2_fd_pair *pairs = 0;
|
||||
|
||||
n = RARRAY_LEN(ary);
|
||||
pairs = (struct fd_pair *)malloc(sizeof(struct fd_pair) * n); /* xxx: not async-signal-safe */
|
||||
if (pairs == NULL) {
|
||||
ERRMSG("malloc");
|
||||
return -1;
|
||||
}
|
||||
pairs = (struct run_exec_dup2_fd_pair *)RSTRING_PTR(tmpbuf);
|
||||
|
||||
/* initialize oldfd and newfd: O(n) */
|
||||
for (i = 0; i < n; i++) {
|
||||
|
|
@ -2141,16 +2157,16 @@ run_exec_dup2(VALUE ary, VALUE save, char *errmsg, size_t errmsg_buflen)
|
|||
|
||||
/* sort the table by oldfd: O(n log n) */
|
||||
if (!RTEST(save))
|
||||
qsort(pairs, n, sizeof(struct fd_pair), intcmp); /* hopefully async-signal-safe */
|
||||
qsort(pairs, n, sizeof(struct run_exec_dup2_fd_pair), intcmp); /* hopefully async-signal-safe */
|
||||
else
|
||||
qsort(pairs, n, sizeof(struct fd_pair), intrcmp);
|
||||
qsort(pairs, n, sizeof(struct run_exec_dup2_fd_pair), intrcmp);
|
||||
|
||||
/* initialize older_index and num_newer: O(n log n) */
|
||||
for (i = 0; i < n; i++) {
|
||||
int newfd = pairs[i].newfd;
|
||||
struct fd_pair key, *found;
|
||||
struct run_exec_dup2_fd_pair key, *found;
|
||||
key.oldfd = newfd;
|
||||
found = bsearch(&key, pairs, n, sizeof(struct fd_pair), intcmp); /* hopefully async-signal-safe */
|
||||
found = bsearch(&key, pairs, n, sizeof(struct run_exec_dup2_fd_pair), intcmp); /* hopefully async-signal-safe */
|
||||
pairs[i].num_newer = 0;
|
||||
if (found) {
|
||||
while (pairs < found && (found-1)->oldfd == newfd)
|
||||
|
|
@ -2245,11 +2261,9 @@ run_exec_dup2(VALUE ary, VALUE save, char *errmsg, size_t errmsg_buflen)
|
|||
}
|
||||
}
|
||||
|
||||
free(pairs); /* xxx: not async-signal-safe */
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
free(pairs); /* xxx: not async-signal-safe */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -2502,7 +2516,7 @@ rb_run_exec_options_err(const struct rb_exec_arg *e, struct rb_exec_arg *s, char
|
|||
|
||||
obj = rb_ary_entry(options, EXEC_OPTION_DUP2);
|
||||
if (!NIL_P(obj)) {
|
||||
if (run_exec_dup2(obj, soptions, errmsg, errmsg_buflen) == -1) /* xxx: not async-signal-safe */
|
||||
if (run_exec_dup2(obj, e->dup2_tmpbuf, soptions, errmsg, errmsg_buflen) == -1) /* xxx: not async-signal-safe */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue