ruby-changes:33966
From: naruse <ko1@a...>
Date: Thu, 22 May 2014 20:49:31 +0900 (JST)
Subject: [ruby-changes:33966] naruse:r46047 (trunk): * file.c (stat_birthtime): add birthtime support [Feature #9647]
naruse 2014-05-22 20:49:22 +0900 (Thu, 22 May 2014) New Revision: 46047 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=46047 Log: * file.c (stat_birthtime): add birthtime support [Feature #9647] * file.c (rb_stat_birthtime): add File::Stat.birthtime * file.c (rb_file_s_birthtime): add File.birthtime * file.c (rb_file_birthtime): add File#birthtime * configure.in: check struct stat.st_birthtimespec. Modified files: trunk/ChangeLog trunk/NEWS trunk/configure.in trunk/file.c trunk/test/ruby/test_file.rb Index: configure.in =================================================================== --- configure.in (revision 46046) +++ configure.in (revision 46047) @@ -1696,6 +1696,7 @@ AC_CHECK_MEMBERS([struct stat.st_mtimens https://github.com/ruby/ruby/blob/trunk/configure.in#L1696 AC_CHECK_MEMBERS([struct stat.st_ctim]) AC_CHECK_MEMBERS([struct stat.st_ctimespec]) AC_CHECK_MEMBERS([struct stat.st_ctimensec]) +AC_CHECK_MEMBERS([struct stat.st_birthtimespec]) AC_CHECK_TYPES([struct timeval], [], [], [@%:@ifdef HAVE_TIME_H @%:@include <time.h> Index: ChangeLog =================================================================== --- ChangeLog (revision 46046) +++ ChangeLog (revision 46047) @@ -1,3 +1,15 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Thu May 22 20:38:10 2014 NARUSE, Yui <naruse@r...> + + * file.c (stat_birthtime): add birthtime support [Feature #9647] + + * file.c (rb_stat_birthtime): add File::Stat.birthtime + + * file.c (rb_file_s_birthtime): add File.birthtime + + * file.c (rb_file_birthtime): add File#birthtime + + * configure.in: check struct stat.st_birthtimespec. + Thu May 22 19:38:14 2014 NARUSE, Yui <naruse@r...> * file.c: remove IO::Statfs because of reject. [Feature #9772] Index: NEWS =================================================================== --- NEWS (revision 46046) +++ NEWS (revision 46047) @@ -27,6 +27,15 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L27 * Float#next_float * Float#prev_float +* File + * New methods: + * File.birthtime + * File#birthtime + +* File::Stat + * New methods: + * File::Stat#birthtime + * Process * Extended method: * Process execution methods such as Process.spawn opens the file in write Index: test/ruby/test_file.rb =================================================================== --- test/ruby/test_file.rb (revision 46046) +++ test/ruby/test_file.rb (revision 46047) @@ -311,6 +311,31 @@ class TestFile < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_file.rb#L311 assert_equal(mod_time_contents, stats.mtime, bug6385) end + def test_stat + file = Tempfile.new("stat") + file.close + path = file.path + + t0 = Process.clock_gettime(Process::CLOCK_REALTIME) + File.write(path, "foo") + sleep 2 + File.write(path, "bar") + sleep 2 + File.chmod(0644, path) + sleep 2 + File.read(path) + + delta = 1 + stat = File.stat(path) + if stat.birthtime != stat.ctime + assert_in_delta t0, stat.birthtime.to_f, delta + end + assert_in_delta t0+2, stat.mtime.to_f, delta + assert_in_delta t0+4, stat.ctime.to_f, delta + assert_in_delta t0+6, stat.atime.to_f, delta + rescue NotImplementedError + end + def test_chmod_m17n bug5671 = '[ruby-dev:44898]' Dir.mktmpdir('test-file-chmod-m17n-') do |tmpdir| Index: file.c =================================================================== --- file.c (revision 46046) +++ file.c (revision 46047) @@ -782,6 +782,19 @@ stat_ctime(struct stat *st) https://github.com/ruby/ruby/blob/trunk/file.c#L782 return rb_time_nano_new(ts.tv_sec, ts.tv_nsec); } +#define HAVE_STAT_BIRTHTIME +#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC) +static VALUE +stat_birthtime(struct stat *st) +{ + struct timespec *ts = &st->st_birthtimespec; + return rb_time_nano_new(ts->tv_sec, ts->tv_nsec); +} +#elif defined(_WIN32) +#else +# undef HAVE_STAT_BIRTHTIME +#endif + /* * call-seq: * stat.atime -> time @@ -836,6 +849,37 @@ rb_stat_ctime(VALUE self) https://github.com/ruby/ruby/blob/trunk/file.c#L849 } /* + * call-seq: + * stat.birthtime -> aTime + * + * Returns the birth time for <i>stat</i>. + * If the platform doesn't have birthtime, returns <i>ctime</i>. + * + * File.write("testfile", "foo") + * sleep 10 + * File.write("testfile", "bar") + * sleep 10 + * File.chmod(0644, "testfile") + * sleep 10 + * File.read("testfile") + * File.stat("testfile").birthtime #=> 2014-02-24 11:19:17 +0900 + * File.stat("testfile").mtime #=> 2014-02-24 11:19:27 +0900 + * File.stat("testfile").ctime #=> 2014-02-24 11:19:37 +0900 + * File.stat("testfile").atime #=> 2014-02-24 11:19:47 +0900 + * + */ + +#if defined(HAVE_STAT_BIRTHTIME) +static VALUE +rb_stat_birthtime(VALUE self) +{ + return stat_birthtime(get_stat(self)); +} +#else +# define rb_stat_birthtime rb_f_notimplement +#endif + +/* * call-seq: * stat.inspect -> string * @@ -846,7 +890,8 @@ rb_stat_ctime(VALUE self) https://github.com/ruby/ruby/blob/trunk/file.c#L890 * # nlink=1, uid=0, gid=0, rdev=0x0, size=1374, blksize=4096, * # blocks=8, atime=Wed Dec 10 10:16:12 CST 2003, * # mtime=Fri Sep 12 15:41:41 CDT 2003, - * # ctime=Mon Oct 27 11:20:27 CST 2003>" + * # ctime=Mon Oct 27 11:20:27 CST 2003, + * # birthtime=Mon Aug 04 08:13:49 CDT 2003>" */ static VALUE @@ -871,6 +916,9 @@ rb_stat_inspect(VALUE self) https://github.com/ruby/ruby/blob/trunk/file.c#L916 {"atime", rb_stat_atime}, {"mtime", rb_stat_mtime}, {"ctime", rb_stat_ctime}, +#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC) + {"birthtime", rb_stat_birthtime}, +#endif }; struct stat* st; @@ -2084,6 +2132,65 @@ rb_file_ctime(VALUE obj) https://github.com/ruby/ruby/blob/trunk/file.c#L2132 /* * call-seq: + * File.birthtime(file_name) -> time + * + * Returns the birth time for the named file. + * + * _file_name_ can be an IO object. + * + * Note that on Windows (NTFS), returns creation time (birth time). + * + * File.birthtime("testfile") #=> Wed Apr 09 08:53:13 CDT 2003 + * + */ + +#if defined(HAVE_STAT_BIRTHTIME) +static VALUE +rb_file_s_birthtime(VALUE klass, VALUE fname) +{ + struct stat st; + + if (rb_stat(fname, &st) < 0) { + FilePathValue(fname); + rb_sys_fail_path(fname); + } + return stat_birthtime(&st); +} +#else +# define rb_file_s_birthtime rb_f_notimplement +#endif + +/* + * call-seq: + * file.birthtime -> time + * + * Returns the birth time for <i>file</i>. + * + * Note that on Windows (NTFS), returns creation time (birth time). + * + * File.new("testfile").birthtime #=> Wed Apr 09 08:53:14 CDT 2003 + * + */ + +#if defined(HAVE_STAT_BIRTHTIME) +static VALUE +rb_file_birthtime(VALUE obj) +{ + rb_io_t *fptr; + struct stat st; + + GetOpenFile(obj, fptr); + if (fstat(fptr->fd, &st) == -1) { + rb_sys_fail_path(fptr->pathv); + } + return stat_birthtime(&st); +} +#else +# define rb_file_birthtime rb_f_notimplement +#endif + +/* + * call-seq: * file.size -> integer * * Returns the size of <i>file</i> in bytes. @@ -5646,6 +5753,7 @@ Init_File(void) https://github.com/ruby/ruby/blob/trunk/file.c#L5753 rb_define_singleton_method(rb_cFile, "atime", rb_file_s_atime, 1); rb_define_singleton_method(rb_cFile, "mtime", rb_file_s_mtime, 1); rb_define_singleton_method(rb_cFile, "ctime", rb_file_s_ctime, 1); + rb_define_singleton_method(rb_cFile, "birthtime", rb_file_s_birthtime, 1); rb_define_singleton_method(rb_cFile, "utime", rb_file_s_utime, -1); rb_define_singleton_method(rb_cFile, "chmod", rb_file_s_chmod, -1); @@ -5693,6 +5801,7 @@ Init_File(void) https://github.com/ruby/ruby/blob/trunk/file.c#L5801 rb_define_method(rb_cFile, "atime", rb_file_atime, 0); rb_define_method(rb_cFile, "mtime", rb_file_mtime, 0); rb_define_method(rb_cFile, "ctime", rb_file_ctime, 0); + rb_define_method(rb_cFile, "birthtime", rb_file_birthtime, 0); rb_define_method(rb_cFile, "size", rb_file_size, 0); rb_define_method(rb_cFile, "chmod", rb_file_chmod, 1); @@ -5814,6 +5923,7 @@ Init_File(void) https://github.com/ruby/ruby/blob/trunk/file.c#L5923 rb_define_method(rb_cStat, "atime", rb_stat_atime, 0); rb_define_method(rb_cStat, "mtime", rb_stat_mtime, 0); rb_define_method(rb_cStat, "ctime", rb_stat_ctime, 0); + rb_define_method(rb_cStat, "birthtime", rb_stat_birthtime, 0); rb_define_method(rb_cStat, "inspect", rb_stat_inspect, 0); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/