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:
parent
a999657e7e
commit
6b4f9210b0
5 changed files with 158 additions and 1 deletions
12
ChangeLog
12
ChangeLog
|
@ -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
9
NEWS
|
@ -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
|
||||
|
|
|
@ -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
112
file.c
|
@ -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);
|
||||
|
||||
|
|
|
@ -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|
|
||||
|
|
Loading…
Reference in a new issue