summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-08-02 11:39:44 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-08-02 11:39:44 +0000
commitc44ba832d11de47e6affb7d49eb91c74ede0572a (patch)
tree1746ba1ad5e600a89d9390f22c68cf022b12d8e1 /io.c
parentb13edd512d33d6da7336a10b014daa2af5b9dce1 (diff)
merge revision(s) 42212,42214: [Backport #8669]
* string.c: add internal API rb_str_locktmp_ensure(). * io.c (io_fread): use rb_str_locktmp_ensure(). [ruby-core:56121] [Bug #8669] * test/ruby/test_io.rb: add a test for above. * 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/branches/ruby_1_9_3@42327 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r--io.c55
1 files changed, 46 insertions, 9 deletions
diff --git a/io.c b/io.c
index e88918f575..7f1b1112b7 100644
--- a/io.c
+++ b/io.c
@@ -1816,15 +1816,31 @@ io_bufread(char *ptr, long len, rb_io_t *fptr)
return len - n;
}
+struct bufread_arg {
+ char *str_ptr;
+ long len;
+ rb_io_t *fptr;
+};
+
+static VALUE
+bufread_call(VALUE arg)
+{
+ struct bufread_arg *p = (struct bufread_arg *)arg;
+ p->len = io_bufread(p->str_ptr, p->len, p->fptr);
+ return Qundef;
+}
+
static long
io_fread(VALUE str, long offset, rb_io_t *fptr)
{
long len;
+ struct bufread_arg arg;
- rb_str_locktmp(str);
- len = io_bufread(RSTRING_PTR(str) + offset, RSTRING_LEN(str) - offset,
- fptr);
- rb_str_unlocktmp(str);
+ arg.str_ptr = RSTRING_PTR(str) + offset;
+ arg.len = RSTRING_LEN(str) - offset;
+ arg.fptr = fptr;
+ rb_str_locktmp_ensure(str, bufread_call, (VALUE)&arg);
+ len = arg.len;
if (len < 0) rb_sys_fail_path(fptr->pathv);
return len;
}
@@ -2124,12 +2140,27 @@ rb_io_set_nonblock(rb_io_t *fptr)
}
}
+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);
@@ -2154,9 +2185,11 @@ io_getpartial(int argc, VALUE *argv, VALUE io, int nonblock)
if (nonblock) {
rb_io_set_nonblock(fptr);
}
- 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;
@@ -4203,6 +4236,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);
@@ -4222,8 +4256,11 @@ rb_io_sysread(int argc, VALUE *argv, VALUE io)
rb_io_check_closed(fptr);
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);