ruby-changes:23872
From: akr <ko1@a...>
Date: Tue, 5 Jun 2012 21:59:50 +0900 (JST)
Subject: [ruby-changes:23872] akr:r35923 (trunk): * process.c (rb_exec_arg_fixup): allocate a temporary buffer for
akr 2012-06-05 21:59:40 +0900 (Tue, 05 Jun 2012) New Revision: 35923 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=35923 Log: * 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. Modified files: trunk/ChangeLog trunk/include/ruby/intern.h trunk/process.c Index: include/ruby/intern.h =================================================================== --- include/ruby/intern.h (revision 35922) +++ include/ruby/intern.h (revision 35923) @@ -598,6 +598,7 @@ 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*); Index: ChangeLog =================================================================== --- ChangeLog (revision 35922) +++ ChangeLog (revision 35923) @@ -1,3 +1,12 @@ +Tue Jun 5 21:57:22 2012 Tanaka Akira <akr@f...> + + * 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@r...> * object.c (rb_obj_init_copy): should check if trusted too. Index: process.c =================================================================== --- process.c (revision 35922) +++ process.c (revision 35923) @@ -1870,13 +1870,25 @@ 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 @@ 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 @@ /* 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 @@ } } - free(pairs); /* xxx: not async-signal-safe */ return 0; fail: - free(pairs); /* xxx: not async-signal-safe */ return -1; } @@ -2502,7 +2516,7 @@ 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; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/