Project

General

Profile

Feature #13743 ยป patch.diff

Glass_saga (Masaki Matsushita), 07/13/2017 11:15 AM

View differences:

configure.in
2449 2449
AC_CHECK_FUNCS(lchmod)
2450 2450
AC_CHECK_FUNCS(lchown)
2451 2451
AC_CHECK_FUNCS(link)
2452
AC_CHECK_FUNCS(linkat)
2452 2453
AC_CHECK_FUNCS(llabs)
2453 2454
AC_CHECK_FUNCS(lockf)
2454 2455
AC_CHECK_FUNCS(log2)
file.c
2717 2717
static VALUE
2718 2718
rb_file_s_link(VALUE klass, VALUE from, VALUE to)
2719 2719
{
2720

  
2721
#if defined(HAVE_LINKAT) && defined(AT_SYMLINK_FOLLOW)
2722
    VALUE tmp = rb_io_check_io(from);
2723
    rb_io_t *from_fptr = RFILE(rb_io_taint_check(from))->fptr;
2724

  
2725
    if (!NIL_P(tmp) && from_fptr && from_fptr->fd >= 0) { /* when 'from' is an IO and opened */
2726
	char from_path[PATH_MAX];
2727

  
2728
	rb_io_flush(from);
2729
	FilePathValue(to);
2730
	to = rb_str_encode_ospath(to);
2731
	snprintf(from_path, PATH_MAX,  "/proc/self/fd/%d", from_fptr->fd);
2732
	if (linkat(AT_FDCWD, from_path, AT_FDCWD, StringValueCStr(to), AT_SYMLINK_FOLLOW) < 0) {
2733
	    FilePathValue(from);
2734
	    from = rb_str_encode_ospath(from);
2735
	    sys_fail2(from, to);
2736
	}
2737
	return INT2FIX(0);
2738
    }
2739
#endif
2720 2740
    FilePathValue(from);
2721 2741
    FilePathValue(to);
2722 2742
    from = rb_str_encode_ospath(from);
test/ruby/test_file_exhaustive.rb
647 647
    assert_raise(Errno::EEXIST) { File.link(utf8_file, utf8_file) }
648 648
  end
649 649

  
650
  def test_hardlink_file_instannce
651
    regular_file = make_tmp_filename("hardlinkfile_file_instannce_from")
652
    hardlinkfile = make_tmp_filename("hardlinkfile_file_instannce_to")
653
    content = "foo"
654
    File.open(regular_file, "w") do |file|
655
      file.write(content)
656
      File.link(file, hardlinkfile)
657
      assert_equal(content, File.read(hardlinkfile))
658
    end
659
  rescue NotImplementedError
660
  end
661

  
662
  def test_hardlink_tmpfile
663
    hardlinkfile = make_tmp_filename("hardlinkfile_tmpfile")
664
    content = "foo"
665
    File.open(@dir, IO::WRONLY|IO::TMPFILE) do |tmpfile|
666
      tmpfile.write(content)
667
      File.link(tmpfile, hardlinkfile)
668
      assert_equal(content, File.read(hardlinkfile))
669
    end
670
  rescue NotImplementedError
671
  end if IO::TMPFILE
672

  
650 673
  def test_readlink
651 674
    return unless symlinkfile
652 675
    assert_equal(regular_file, File.readlink(symlinkfile))