Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rubinius/rubinius
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 3a4c3fda1dec
Choose a base ref
...
head repository: rubinius/rubinius
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4de8eb50cf8b
Choose a head ref
  • 4 commits
  • 4 files changed
  • 1 contributor

Commits on Oct 16, 2015

  1. Check if struct stat has nanosecond resolution.

    Check for st_atim, st_mtim, st_ctim, etc. in struct stat (sys/stat.h)
    andre-richter authored and Yorick Peterse committed Oct 16, 2015
    Copy the full SHA
    1756765 View commit details
  2. Add nanosecond support for Stat::[amc]time

    andre-richter authored and Yorick Peterse committed Oct 16, 2015
    Copy the full SHA
    97b8fb3 View commit details
  3. Spec: Check microsecond resolution for File#utime

    andre-richter authored and Yorick Peterse committed Oct 16, 2015
    Copy the full SHA
    8762203 View commit details
  4. Implement microsecond resolution for File#utime

    andre-richter authored and Yorick Peterse committed Oct 16, 2015
    Copy the full SHA
    4de8eb5 View commit details
Showing with 102 additions and 7 deletions.
  1. +36 −0 configure
  2. +13 −2 kernel/common/file.rb
  3. +26 −2 spec/ruby/core/file/utime_spec.rb
  4. +27 −3 vm/builtin/stat.cpp
36 changes: 36 additions & 0 deletions configure
Original file line number Diff line number Diff line change
@@ -1230,6 +1230,42 @@ int main() { return tgetnum(""); }
@defines << "HAVE_GETTID"
end

if has_struct_member("stat", "st_atim", ["sys/stat.h"])
@defines << "HAVE_STRUCT_STAT_ST_ATIM"
end

if has_struct_member("stat", "st_atimespec", ["sys/stat.h"])
@defines << "HAVE_STRUCT_STAT_ST_ATIMESPEC"
end

if has_struct_member("stat", "st_atimensec", ["sys/stat.h"])
@defines << "HAVE_STRUCT_STAT_ST_ATIMENSEC"
end

if has_struct_member("stat", "st_mtim", ["sys/stat.h"])
@defines << "HAVE_STRUCT_STAT_ST_MTIM"
end

if has_struct_member("stat", "st_mtimespec", ["sys/stat.h"])
@defines << "HAVE_STRUCT_STAT_ST_MTIMESPEC"
end

if has_struct_member("stat", "st_mtimensec", ["sys/stat.h"])
@defines << "HAVE_STRUCT_STAT_ST_MTIMENSEC"
end

if has_struct_member("stat", "st_ctim", ["sys/stat.h"])
@defines << "HAVE_STRUCT_STAT_ST_CTIM"
end

if has_struct_member("stat", "st_ctimespec", ["sys/stat.h"])
@defines << "HAVE_STRUCT_STAT_ST_CTIMESPEC"
end

if has_struct_member("stat", "st_ctimensec", ["sys/stat.h"])
@defines << "HAVE_STRUCT_STAT_ST_CTIMENSEC"
end

if has_struct_member("stat", "st_birthtimespec", ["sys/stat.h"])
@defines << "HAVE_ST_BIRTHTIME"
end
15 changes: 13 additions & 2 deletions kernel/common/file.rb
Original file line number Diff line number Diff line change
@@ -137,15 +137,26 @@ def self.mtime(path)
# #=> Integer
def self.utime(a_in, m_in, *paths)
a_in ||= Time.now
a_in_usec = if a_in.is_a?(Time) || a_in.is_a?(Float) || a_in.is_a?(Rational)
Time.at(a_in).usec
else
0
end
m_in ||= Time.now
m_in_usec = if m_in.is_a?(Time) || m_in.is_a?(Float) || m_in.is_a?(Rational)
Time.at(m_in).usec
else
0
end

FFI::MemoryPointer.new(POSIX::TimeVal, 2) do |ptr|
atime = POSIX::TimeVal.new ptr
mtime = POSIX::TimeVal.new ptr[1]
atime[:tv_sec] = a_in.to_i
atime[:tv_usec] = 0
atime[:tv_usec] = a_in_usec

mtime[:tv_sec] = m_in.to_i
mtime[:tv_usec] = 0
mtime[:tv_usec] = m_in_usec

paths.each do |path|

28 changes: 26 additions & 2 deletions spec/ruby/core/file/utime_spec.rb
Original file line number Diff line number Diff line change
@@ -2,8 +2,8 @@

describe "File.utime" do
before :each do
@atime = Time.now
@mtime = Time.now
@atime = Time.new(2000, 1, 1, 1, 1, 1.00001)
@mtime = Time.new(2000, 1, 1, 1, 1, 1.00001)
@file1 = tmp("specs_file_utime1")
@file2 = tmp("specs_file_utime2")
touch @file1
@@ -22,6 +22,30 @@
File.mtime(@file2).to_i.should be_close(@mtime.to_i, 2)
end

it "sets and gets microseconds from Time arguments" do
File.utime(@atime, @mtime, @file1, @file2)
File.atime(@file1).usec.should equal(10)
File.mtime(@file1).usec.should equal(10)
File.atime(@file2).usec.should equal(10)
File.mtime(@file2).usec.should equal(10)
end

it "sets and gets microseconds from Float arguments" do
File.utime(0.0001, 0.0001, @file1, @file2)
File.atime(@file1).usec.should equal(100)
File.mtime(@file1).usec.should equal(100)
File.atime(@file2).usec.should equal(100)
File.mtime(@file2).usec.should equal(100)
end

it "sets and gets microseconds from Rational arguments" do
File.utime(Rational(1, 1000), Rational(1, 1000), @file1, @file2)
File.atime(@file1).usec.should equal(1000)
File.mtime(@file1).usec.should equal(1000)
File.atime(@file2).usec.should equal(1000)
File.mtime(@file2).usec.should equal(1000)
end

it "uses the current times if two nil values are passed" do
File.utime(nil, nil, @file1, @file2)
File.atime(@file1).to_i.should be_close(Time.now.to_i, 2)
30 changes: 27 additions & 3 deletions vm/builtin/stat.cpp
Original file line number Diff line number Diff line change
@@ -66,15 +66,39 @@ namespace rubinius {
}

Time* Stat::stat_atime(STATE) {
return Time::at(state, st_.st_atime);
#ifdef HAVE_STRUCT_STAT_ST_ATIM
return Time::at(state, st_.st_atim.tv_sec, st_.st_atim.tv_nsec);
#elif HAVE_STRUCT_STAT_ST_ATIMESPEC
return Time::at(state, st_.st_atimespec.tv_sec, st_.st_atimespec.tv_nsec);
#elif HAVE_STRUCT_STAT_ST_ATIMENSEC
return Time::at(state, st_.st_atime, static_cast<long>(st_.st_atimensec));
#else
return Time::at(state, st_.st_atime);
#endif
}

Time* Stat::stat_mtime(STATE) {
return Time::at(state, st_.st_mtime);
#ifdef HAVE_STRUCT_STAT_ST_MTIM
return Time::at(state, st_.st_mtim.tv_sec, st_.st_mtim.tv_nsec);
#elif HAVE_STRUCT_STAT_ST_MTIMESPEC
return Time::at(state, st_.st_mtimespec.tv_sec, st_.st_mtimespec.tv_nsec);
#elif HAVE_STRUCT_STAT_ST_MTIMENSEC
return Time::at(state, st_.st_mtime, static_cast<long>(st_.st_mtimensec));
#else
return Time::at(state, st_.st_mtime);
#endif
}

Time* Stat::stat_ctime(STATE) {
return Time::at(state, st_.st_ctime);
#ifdef HAVE_STRUCT_STAT_ST_CTIM
return Time::at(state, st_.st_ctim.tv_sec, st_.st_ctim.tv_nsec);
#elif HAVE_STRUCT_STAT_ST_CTIMESPEC
return Time::at(state, st_.st_ctimespec.tv_sec, st_.st_ctimespec.tv_nsec);
#elif HAVE_STRUCT_STAT_ST_CTIMENSEC
return Time::at(state, st_.st_ctime, static_cast<long>(st_.st_ctimensec));
#else
return Time::at(state, st_.st_ctime);
#endif
}

Object* Stat::stat_birthtime(STATE) {