aboutsummaryrefslogtreecommitdiffstats
path: root/file.c
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-05-22 11:49:22 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-05-22 11:49:22 +0000
commit6b4f9210b0a105c68d98ebf2b80eea160c3af6a5 (patch)
tree3377fcaa4c7cdfa2d82dd97cd2fccbdb210954b4 /file.c
parenta999657e7e72d21c5904b2dd5bc056619aff2b81 (diff)
downloadruby-6b4f9210b0a105c68d98ebf2b80eea160c3af6a5.tar.gz
* 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
Diffstat (limited to 'file.c')
-rw-r--r--file.c112
1 files changed, 111 insertions, 1 deletions
diff --git a/file.c b/file.c
index af42d98dfb..2305066970 100644
--- a/file.c
+++ b/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
@@ -836,6 +849,37 @@ rb_stat_ctime(VALUE 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;
@@ -2084,6 +2132,65 @@ rb_file_ctime(VALUE obj)
/*
* 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)
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);