* process.c (rb_execarg_parent_start1): Handle EINTR.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50207 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2015-04-10 09:45:29 +00:00
Родитель 93df5a0a90
Коммит ff381ca19b
3 изменённых файлов: 56 добавлений и 13 удалений

Просмотреть файл

@ -1,3 +1,7 @@
Fri Apr 10 18:29:49 2015 Tanaka Akira <akr@fsij.org>
* process.c (rb_execarg_parent_start1): Handle EINTR.
Fri Apr 10 17:27:58 2015 Koichi Sasada <ko1@atdot.net>
* vm.c (vm_exec): check other events when RETURN is thrown.

Просмотреть файл

@ -2286,7 +2286,6 @@ fill_envp_buf_i(st_data_t st_key, st_data_t st_val, st_data_t arg)
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)
{
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_obj)
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();

Просмотреть файл

@ -574,6 +574,43 @@ class TestProcess < Test::Unit::TestCase
}
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|