Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 24 additions & 16 deletions io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1327,14 +1327,15 @@ rb_io_write_memory(rb_io_t *fptr, const void *buf, size_t count)
static ssize_t
rb_writev_internal(rb_io_t *fptr, const struct iovec *iov, int iovcnt)
{
if (!iovcnt) return 0;

VALUE scheduler = rb_fiber_scheduler_current();
if (scheduler != Qnil) {
for (int i = 0; i < iovcnt; i += 1) {
VALUE result = rb_fiber_scheduler_io_write_memory(scheduler, fptr->self, iov[i].iov_base, iov[i].iov_len, 0);
// This path assumes at least one `iov`:
VALUE result = rb_fiber_scheduler_io_write_memory(scheduler, fptr->self, iov[0].iov_base, iov[0].iov_len, 0);

if (!UNDEF_P(result)) {
return rb_fiber_scheduler_io_result_apply(result);
}
if (!UNDEF_P(result)) {
return rb_fiber_scheduler_io_result_apply(result);
}
}

Expand Down Expand Up @@ -2041,7 +2042,7 @@ io_binwritev_internal(VALUE arg)
while (remaining) {
long result = rb_writev_internal(fptr, iov, iovcnt);

if (result > 0) {
if (result >= 0) {
offset += result;
if (fptr->wbuf.ptr && fptr->wbuf.len) {
if (offset < (size_t)fptr->wbuf.len) {
Expand Down Expand Up @@ -8914,30 +8915,37 @@ io_puts_ary(VALUE ary, VALUE out, int recur)
VALUE
rb_io_puts(int argc, const VALUE *argv, VALUE out)
{
int i, n;
VALUE line, args[2];

/* if no argument given, print newline. */
if (argc == 0) {
rb_io_write(out, rb_default_rs);
return Qnil;
}
for (i=0; i<argc; i++) {
for (int i = 0; i < argc; i++) {
// Convert the argument to a string:
if (RB_TYPE_P(argv[i], T_STRING)) {
line = argv[i];
goto string;
}
if (rb_exec_recursive(io_puts_ary, argv[i], out)) {
else if (rb_exec_recursive(io_puts_ary, argv[i], out)) {
continue;
}
line = rb_obj_as_string(argv[i]);
string:
n = 0;
args[n++] = line;
if (RSTRING_LEN(line) == 0 ||
!rb_str_end_with_asciichar(line, '\n')) {
else {
line = rb_obj_as_string(argv[i]);
}

// Write the line:
int n = 0;
if (RSTRING_LEN(line) == 0) {
args[n++] = rb_default_rs;
}
else {
args[n++] = line;
if (!rb_str_end_with_asciichar(line, '\n')) {
args[n++] = rb_default_rs;
}
}

rb_io_writev(out, n, args);
}

Expand Down
28 changes: 28 additions & 0 deletions test/fiber/test_io.rb
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,34 @@ def test_read_write_blocking
assert_predicate(o, :closed?)
end

def test_puts_empty
omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)

i, o = UNIXSocket.pair
i.nonblock = false
o.nonblock = false

thread = Thread.new do
# This scheduler provides non-blocking `io_read`/`io_write`:
scheduler = IOBufferScheduler.new
Fiber.set_scheduler scheduler

Fiber.schedule do
# This was causing a segfault on older Ruby.
o.puts ""
o.puts nil
o.close
end
end

thread.join

message = i.read
i.close

assert_equal $/*2, message
end

def test_io_select
omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)

Expand Down