Skip to content

File#mtime does not behave like it does in MRI in respect to renamed and deleted files on POSIX #5073

@Taywee

Description

@Taywee

Environment

  • jruby 9.1.16.0 (2.3.3) 2018-02-21 8f3f95a OpenJDK 64-Bit Server VM 25.151-b12 on 1.8.0_151-b12 +jit [linux-x86_64]
  • Linux nyarlathotep 4.14.11-gentoo-r2 Project suggestions #2 SMP Wed Feb 28 17:37:50 MST 2018 x86_64 Intel(R) Core(TM) i5-3570K CPU @ 3.40GHz GenuineIntel GNU/Linux

Expected Behavior

File#mtime doesn't return the same data for File#stat#mtime when the file has been renamed or deleted since the filehandle was opened (if the file has been removed, it throws an exception; if the file has been renamed, it silently gets the wrong data). MRI gets this data from the open filehandle and therefore gets the correct mtime. There are probably other methods on File that are shortcuts for stat that have this same issue. #size appears to have the correct behavior, but #ctime and #atime do not.

Here's an example program that works on MRI (printing "true" twice) but crashes in Jruby:

#!/usr/bin/env ruby

require 'tmpdir'
require 'pathname'
require 'fileutils'

Dir.mktmpdir do |dir|
  dir = Pathname.new dir
  filename = dir + 'foo'
  File.open(filename, 'w') {|f| f.puts('foo')}
  file = File.open filename
  p file.stat.mtime == file.mtime
  File.rename(filename, dir + 'bar')
  p file.stat.mtime == file.mtime
end

In MRI

true
true

Note that in MRI on Windows, this fails as well, due to Windows files being locked for deletion and renaming when they are open for reading, so it throws a permission denied error. This version works in MRI on Windows:

Dir.mktmpdir do |dir|
  dir = Pathname.new dir
  filename = dir + 'foo'
  File.open(filename, 'w') {|f| f.puts('foo')}
  File.open(filename, File::BINARY | File::SHARE_DELETE) do |file|
    p file.stat.mtime == file.mtime
    File.delete(filename)
    p file.stat.mtime == file.mtime
  end
end

Actual Behavior

true
Errno::ENOENT: No such file or directory - /tmp/d20180301-17838-1pibcq4/foo
               mtime at org/jruby/RubyFile.java:440
  block in ./test.rb at ./test.rb:14
                open at org/jruby/RubyIO.java:1171
  block in ./test.rb at ./test.rb:11
            mktmpdir at /home/taylor/.rbenv/versions/jruby-9.1.16.0/lib/ruby/stdlib/tmpdir.rb:89
              <main> at ./test.rb:7

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions