Project

General

Profile

Bug #5714 ยป set_binmode_fix.patch

h.shirosaki (Hiroshi Shirosaki), 12/15/2011 02:58 PM

View differences:

io.c
374 374
#  endif
375 375
#endif
376 376

  
377
#define rb_sys_fail_path(path) rb_sys_fail(NIL_P(path) ? 0 : RSTRING_PTR(path))
378

  
377 379
static int io_fflush(rb_io_t *);
378 380

  
379 381
#define NEED_NEWLINE_DECORATOR_ON_READ(fptr) ((fptr)->mode & FMODE_TEXTMODE)
......
423 425
    ssize_t read_size;
424 426
    long i;
425 427
    long newlines = 0;
428
    long extra_max;
426 429
    char *p;
427 430

  
428 431
    if (!rb_w32_fd_is_text((fptr)->fd)) return O_BINARY;
......
443 446
	setmode((fptr)->fd, O_BINARY);
444 447
	return O_TEXT;
445 448
    }
446
    /* add extra offset for '\r' */
447
    p = (fptr)->rbuf.ptr+(fptr)->rbuf.off;
449
    /* add extra offset for removed '\r' in rbuf */
450
    extra_max = pos - (fptr)->rbuf.len;
451
    p = (fptr)->rbuf.ptr + (fptr)->rbuf.off;
448 452
    for (i = 0; i < (fptr)->rbuf.len; i++) {
449 453
	if (*p == '\n') newlines++;
454
	if (extra_max == newlines) break;
450 455
	p++;
451 456
    }
452 457
    while (newlines >= 0) {
453 458
	r = lseek((fptr)->fd, pos - (fptr)->rbuf.len - newlines, SEEK_SET);
454 459
	if (newlines == 0) break;
455
	if (read_size = _read((fptr)->fd, (fptr)->rbuf.ptr, (fptr)->rbuf.len + newlines)) {
456
	    if (read_size == (fptr)->rbuf.len) {
457
		lseek((fptr)->fd, r, SEEK_SET);
458
		break;
459
	    }
460
	    else {
461
		newlines--;
462
	    }
460
	if (r < 0) {
461
	    newlines--;
462
	    continue;
463
	}
464
	read_size = _read((fptr)->fd, (fptr)->rbuf.ptr, (fptr)->rbuf.len + newlines);
465
	if (read_size < 0) {
466
	    rb_sys_fail_path(fptr->pathv);
467
	}
468
	if (read_size == (fptr)->rbuf.len) {
469
	    lseek((fptr)->fd, r, SEEK_SET);
470
	    break;
471
	}
472
	else {
473
	    newlines--;
463 474
	}
464 475
    }
465 476
    (fptr)->rbuf.off = 0;
......
484 495
#define shutdown(a,b)	0
485 496
#endif
486 497

  
487
#define rb_sys_fail_path(path) rb_sys_fail(NIL_P(path) ? 0 : RSTRING_PTR(path))
488

  
489 498
#if defined(_WIN32)
490 499
#define is_socket(fd, path)	rb_w32_is_socket(fd)
491 500
#elif !defined(S_ISSOCK)
test/ruby/test_io_m17n.rb
2314 2314
      end
2315 2315
    }
2316 2316
  end if /mswin|mingw/ =~ RUBY_PLATFORM
2317

  
2318
  def test_seek_with_setting_binmode
2319
    with_tmpdir {
2320
      str = "a\r\nb\r\nc\r\n\r\n\n\n\n\n\n\n\n"
2321
      generate_file("tmp", str)
2322
      open("tmp", "r") do |f|
2323
        assert_equal("a\n", f.gets)      # text
2324
        assert_equal("b\r\n", f.read(3)) # binary
2325
      end
2326
    }
2327
  end if /mswin|mingw/ =~ RUBY_PLATFORM
2317 2328
end