[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]