1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46047 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
naruse 2014-05-22 11:49:22 +00:00
parent a999657e7e
commit 6b4f9210b0
5 changed files with 158 additions and 1 deletions

View file

@ -1,3 +1,15 @@
Thu May 22 20:38:10 2014 NARUSE, Yui <naruse@ruby-lang.org>
* 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@ruby-lang.org>
* file.c: remove IO::Statfs because of reject. [Feature #9772]

9
NEWS
View file

@ -27,6 +27,15 @@ with all sufficient information, see the ChangeLog file.
* 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

View file

@ -1696,6 +1696,7 @@ AC_CHECK_MEMBERS([struct stat.st_mtimensec])
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>

112
file.c
View file

@ -782,6 +782,19 @@ stat_ctime(struct stat *st)
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
@ -835,6 +848,37 @@ rb_stat_ctime(VALUE self)
return stat_ctime(get_stat(self));
}
/*
* 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)
* # 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)
{"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;
@ -2082,6 +2130,65 @@ rb_file_ctime(VALUE obj)
return stat_ctime(&st);
}
/*
* 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
@ -5646,6 +5753,7 @@ Init_File(void)
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)
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)
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);

View file

@ -311,6 +311,31 @@ class TestFile < Test::Unit::TestCase
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|