1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* io.c (io_getpartial): use rb_str_locktmp_ensure().

[ruby-core:56121] [Bug #8669]

* io.c (rb_io_sysread): ditto.

* test/ruby/test_io.rb: add tests for above.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42214 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
glass 2013-07-28 11:31:58 +00:00
parent 5c2f4fbcbd
commit e4b0852ae4
3 changed files with 63 additions and 5 deletions

View file

@ -1,3 +1,12 @@
Sun Jul 28 20:28:41 2013 Masaki Matsushita <glass.saga@gmail.com>
* io.c (io_getpartial): use rb_str_locktmp_ensure().
[ruby-core:56121] [Bug #8669]
* io.c (rb_io_sysread): ditto.
* test/ruby/test_io.rb: add tests for above.
Sun Jul 28 20:10:49 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/extmk.rb (extmake): should make static libraries for extensions

31
io.c
View file

@ -2397,12 +2397,27 @@ rb_io_set_nonblock(rb_io_t *fptr)
void
rb_readwrite_sys_fail(int writable, const char *mesg);
struct read_internal_arg {
int fd;
char *str_ptr;
long len;
};
static VALUE
read_internal_call(VALUE arg)
{
struct read_internal_arg *p = (struct read_internal_arg *)arg;
p->len = rb_read_internal(p->fd, p->str_ptr, p->len);
return Qundef;
}
static VALUE
io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
{
rb_io_t *fptr;
VALUE length, str;
long n, len;
struct read_internal_arg arg;
rb_scan_args(argc, argv, "11", &length, &str);
@ -2428,9 +2443,11 @@ io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
rb_io_set_nonblock(fptr);
}
io_setstrbuf(&str, len);
rb_str_locktmp(str);
n = rb_read_internal(fptr->fd, RSTRING_PTR(str), len);
rb_str_unlocktmp(str);
arg.fd = fptr->fd;
arg.str_ptr = RSTRING_PTR(str);
arg.len = len;
rb_str_locktmp_ensure(str, read_internal_call, (VALUE)&arg);
n = arg.len;
if (n < 0) {
if (!nonblock && rb_io_wait_readable(fptr->fd))
goto again;
@ -4542,6 +4559,7 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
VALUE len, str;
rb_io_t *fptr;
long n, ilen;
struct read_internal_arg arg;
rb_scan_args(argc, argv, "11", &len, &str);
ilen = NUM2LONG(len);
@ -4571,8 +4589,11 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
io_setstrbuf(&str, ilen);
rb_str_locktmp(str);
n = rb_read_internal(fptr->fd, RSTRING_PTR(str), ilen);
rb_str_unlocktmp(str);
arg.fd = fptr->fd;
arg.str_ptr = RSTRING_PTR(str);
arg.len = ilen;
rb_ensure(read_internal_call, (VALUE)&arg, rb_str_unlocktmp, str);
n = arg.len;
if (n == -1) {
rb_sys_fail_path(fptr->pathv);

View file

@ -2815,4 +2815,32 @@ End
ensure
t.kill
end
def test_readpartial_unlocktmp_ensure
bug8669 = '[ruby-core:56121] [Bug #8669]'
str = ""
r, = IO.pipe
t = Thread.new { r.readpartial(4096, str) }
sleep 0.1 until t.stop?
t.raise
sleep 0.1 while t.alive?
assert_nothing_raised(RuntimeError, bug8669) { str.clear }
ensure
t.kill
end
def test_sysread_unlocktmp_ensure
bug8669 = '[ruby-core:56121] [Bug #8669]'
str = ""
r, = IO.pipe
t = Thread.new { r.sysread(4096, str) }
sleep 0.1 until t.stop?
t.raise
sleep 0.1 while t.alive?
assert_nothing_raised(RuntimeError, bug8669) { str.clear }
ensure
t.kill
end
end