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

Try statx syscall

* file.c (rb_file_s_birthtime): export for pathname to check if
  birthtime is supported.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67097 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2019-02-20 06:54:23 +00:00
parent d034fcb13f
commit 15a98ab428
5 changed files with 51 additions and 12 deletions

View file

@ -1897,7 +1897,18 @@ AC_CHECK_FUNCS(sigaltstack)
AC_CHECK_FUNCS(sigprocmask)
AC_CHECK_FUNCS(sinh)
AC_CHECK_FUNCS(spawnv)
AC_CHECK_FUNCS(statx)
AC_CHECK_FUNCS(statx, [],
[AS_CASE(["$target_os"], [linux*],
[AC_CHECK_DECLS([__NR_statx], [ac_cv_func_statx=syscall], [],
[
@%:@ ifdef HAVE_SYSCALL_H
@%:@ include <syscall.h>
@%:@ elif defined HAVE_SYS_SYSCALL_H
@%:@ include <sys/syscall.h>
@%:@ endif
])
])
])
AC_CHECK_FUNCS(symlink)
AC_CHECK_FUNCS(syscall)
AC_CHECK_FUNCS(sysconf)
@ -1913,6 +1924,8 @@ AC_CHECK_FUNCS(utimes)
AC_CHECK_FUNCS(wait4)
AC_CHECK_FUNCS(waitpid)
AS_IF([test "$ac_cv_func_statx" = syscall], [AC_DEFINE(HAVE_STATX, 0)])
AS_CASE(["$ac_cv_func_memset_s:$ac_cv_func_qsort_s"], [*yes*],
[RUBY_DEFINE_IF([!defined __STDC_WANT_LIB_EXT1__], [__STDC_WANT_LIB_EXT1__], 1)])

View file

@ -1,4 +1,4 @@
# frozen_string_literal: false
require 'mkmf'
have_struct_member("struct stat", "st_birthtimespec", "sys/stat.h")
have_func("rb_file_s_birthtime")
create_makefile('pathname')

View file

@ -512,7 +512,7 @@ path_atime(VALUE self)
return rb_funcall(rb_cFile, id_atime, 1, get_strpath(self));
}
#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC) || defined(_WIN32)
#if defined(HAVE_RB_FILE_S_BIRTHTIME)
/*
* call-seq:
* pathname.birthtime -> time
@ -528,6 +528,7 @@ path_birthtime(VALUE self)
return rb_funcall(rb_cFile, id_birthtime, 1, get_strpath(self));
}
#else
/* check at compilation time for `respond_to?` */
# define path_birthtime rb_f_notimplement
#endif

28
file.c
View file

@ -1113,6 +1113,24 @@ stat_without_gvl(const char *path, struct stat *st)
}
#ifdef HAVE_STATX
# if HAVE_STATX == 0
# ifdef HAVE_SYSCALL_H
# include <syscall.h>
# elif defined HAVE_SYS_SYSCALL_H
# include <sys/syscall.h>
# endif
# if defined __linux__
# include <linux/stat.h>
static inline int
statx(int dirfd, const char *pathname, int flags,
unsigned int mask, struct statx *statxbuf)
{
return syscall(__NR_statx, dirfd, pathname, flags, mask, statxbuf);
}
# endif
# endif
typedef struct no_gvl_statx_data {
struct statx *stx;
int fd;
@ -2360,9 +2378,10 @@ rb_file_ctime(VALUE obj)
*
*/
#if defined(HAVE_STAT_BIRTHTIME)
static VALUE
#if defined(HAVE_STAT_BIRTHTIME) || defined(HAVE_STATX)
RUBY_FUNC_EXPORTED VALUE
rb_file_s_birthtime(VALUE klass, VALUE fname)
# if defined(HAVE_STAT_BIRTHTIME)
{
struct stat st;
@ -2374,8 +2393,6 @@ rb_file_s_birthtime(VALUE klass, VALUE fname)
return stat_birthtime(&st);
}
# elif defined(HAVE_STATX)
static VALUE
rb_file_s_birthtime(VALUE klass, VALUE fname)
{
struct statx stx;
@ -2391,6 +2408,9 @@ rb_file_s_birthtime(VALUE klass, VALUE fname)
return statx_birthtime(&stx);
}
# else
# error Not implemented
# endif
#else
# define rb_file_s_birthtime rb_f_notimplement
#endif

View file

@ -789,10 +789,15 @@ class TestPathname < Test::Unit::TestCase
end
def test_birthtime
assert_kind_of(Time, Pathname(__FILE__).birthtime)
# Check under a (probably) local filesystem.
# Remote filesystems often may not support birthtime.
with_tmpchdir('rubytest-pathname') do |dir|
open("a", "w") {}
assert_kind_of(Time, Pathname("a").birthtime)
rescue NotImplementedError
assert_raise(NotImplementedError) do
File.birthtime(__FILE__)
File.birthtime("a")
end
end
end