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

ruby-changes:38126

From: akr <ko1@a...>
Date: Fri, 10 Apr 2015 18:45:46 +0900 (JST)
Subject: [ruby-changes:38126] akr:r50207 (trunk): * process.c (rb_execarg_parent_start1): Handle EINTR.

akr	2015-04-10 18:45:29 +0900 (Fri, 10 Apr 2015)

  New Revision: 50207

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=50207

  Log:
    * process.c (rb_execarg_parent_start1): Handle EINTR.

  Modified files:
    trunk/ChangeLog
    trunk/process.c
    trunk/test/ruby/test_process.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 50206)
+++ ChangeLog	(revision 50207)
@@ -1,3 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Apr 10 18:29:49 2015  Tanaka Akira  <akr@f...>
+
+	* process.c (rb_execarg_parent_start1): Handle EINTR.
+
 Fri Apr 10 17:27:58 2015  Koichi Sasada  <ko1@a...>
 
 	* vm.c (vm_exec): check other events when RETURN is thrown.
Index: process.c
===================================================================
--- process.c	(revision 50206)
+++ process.c	(revision 50207)
@@ -2286,7 +2286,6 @@ fill_envp_buf_i(st_data_t st_key, st_dat https://github.com/ruby/ruby/blob/trunk/process.c#L2286
 static long run_exec_dup2_tmpbuf_size(long n);
 
 struct open_struct {
-    int entered;
     VALUE fname;
     int oflags;
     mode_t perm;
@@ -2299,8 +2298,8 @@ open_func(void *ptr) https://github.com/ruby/ruby/blob/trunk/process.c#L2298
 {
     struct open_struct *data = ptr;
     const char *fname = RSTRING_PTR(data->fname);
-    data->entered = 1;
     data->ret = parent_redirect_open(fname, data->oflags, data->perm);
+    data->err = errno;
     return NULL;
 }
 
@@ -2327,18 +2326,21 @@ rb_execarg_parent_start1(VALUE execarg_o https://github.com/ruby/ruby/blob/trunk/process.c#L2326
             if (NIL_P(fd2v)) {
                 struct open_struct open_data;
                 FilePathValue(vpath);
-                do {
-                    rb_thread_check_ints();
-                    open_data.entered = 0;
-                    open_data.fname = vpath;
-                    open_data.oflags = flags;
-                    open_data.perm = perm;
-                    open_data.ret = -1;
-                    rb_thread_call_without_gvl2(open_func, (void *)&open_data, RUBY_UBF_IO, 0);
-                } while (!open_data.entered);
-                fd2 = open_data.ret;
-                if (fd2 == -1)
+              again:
+                open_data.fname = vpath;
+                open_data.oflags = flags;
+                open_data.perm = perm;
+                open_data.ret = -1;
+                open_data.err = EINTR;
+                rb_thread_call_without_gvl2(open_func, (void *)&open_data, RUBY_UBF_IO, 0);
+                if (open_data.ret == -1) {
+                    if (open_data.err == EINTR) {
+                        rb_thread_check_ints();
+                        goto again;
+                    }
                     rb_sys_fail("open");
+                }
+                fd2 = open_data.ret;
                 rb_update_max_fd(fd2);
                 RARRAY_ASET(param, 3, INT2FIX(fd2));
                 rb_thread_check_ints();
Index: test/ruby/test_process.rb
===================================================================
--- test/ruby/test_process.rb	(revision 50206)
+++ test/ruby/test_process.rb	(revision 50207)
@@ -574,6 +574,43 @@ class TestProcess < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_process.rb#L574
     }
   end unless windows? # does not support fifo
 
+  def test_execopts_redirect_open_fifo_interrupt_raise
+    with_tmpchdir {|d|
+      system("mkfifo fifo")
+      return if !$?.success?
+      IO.popen([RUBY, '-e', <<-'EOS']) {|io|
+        class E < StandardError; end
+        trap(:USR1) { raise E }
+        begin
+          system("cat", :in => "fifo")
+        rescue E
+          puts "ok"
+        end
+      EOS
+        sleep 0.1
+        Process.kill(:USR1, io.pid)
+        assert_equal("ok\n", io.read)
+      }
+    }
+  end unless windows? # does not support fifo
+
+  def test_execopts_redirect_open_fifo_interrupt_print
+    with_tmpchdir {|d|
+      system("mkfifo fifo")
+      return if !$?.success?
+      IO.popen([RUBY, '-e', <<-'EOS']) {|io|
+        trap(:USR1) { print "trap\n" }
+        system("cat", :in => "fifo")
+      EOS
+        sleep 0.1
+        Process.kill(:USR1, io.pid)
+        sleep 0.1
+        File.write("fifo", "ok\n")
+        assert_equal("trap\nok\n", io.read)
+      }
+    }
+  end unless windows? # does not support fifo
+
   def test_execopts_redirect_pipe
     with_pipe {|r1, w1|
       with_pipe {|r2, w2|

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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