ruby-changes:54883
From: glass <ko1@a...>
Date: Tue, 19 Feb 2019 14:44:59 +0900 (JST)
Subject: [ruby-changes:54883] glass:r67088 (trunk): file.c: enable File.birthtime on Linux
glass 2019-02-19 14:44:53 +0900 (Tue, 19 Feb 2019) New Revision: 67088 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=67088 Log: file.c: enable File.birthtime on Linux enable File.birthtime on Linux if statx(2) is available. Modified files: trunk/configure.ac trunk/file.c Index: configure.ac =================================================================== --- configure.ac (revision 67087) +++ configure.ac (revision 67088) @@ -1897,6 +1897,7 @@ AC_CHECK_FUNCS(sigaltstack) https://github.com/ruby/ruby/blob/trunk/configure.ac#L1897 AC_CHECK_FUNCS(sigprocmask) AC_CHECK_FUNCS(sinh) AC_CHECK_FUNCS(spawnv) +AC_CHECK_FUNCS(statx) AC_CHECK_FUNCS(symlink) AC_CHECK_FUNCS(syscall) AC_CHECK_FUNCS(sysconf) Index: file.c =================================================================== --- file.c (revision 67087) +++ file.c (revision 67088) @@ -1112,6 +1112,72 @@ stat_without_gvl(const char *path, struc https://github.com/ruby/ruby/blob/trunk/file.c#L1112 RUBY_UBF_IO, NULL); } +#ifdef HAVE_STATX +typedef struct no_gvl_statx_data { + struct statx *stx; + int fd; + const char *path; + int flags; + unsigned int mask; +} no_gvl_statx_data; + +static VALUE +no_gvl_statx(void *data) +{ + no_gvl_statx_data *arg = data; + return (VALUE)statx(arg->fd, arg->path, arg->flags, arg->mask, arg->stx); +} + +static int +statx_without_gvl(int fd, const char *path, int flags, unsigned int mask, struct statx *stx) +{ + no_gvl_statx_data data; + + data.stx = stx; + data.fd = fd; + data.path = path; + data.flags = flags; + data.mask = mask; + + if (path) { + /* call statx(2) with pathname */ + return (int)(VALUE)rb_thread_call_without_gvl((void *)no_gvl_statx, &data, + RUBY_UBF_IO, NULL); + } + else { + return (int)(VALUE)rb_thread_io_blocking_region(no_gvl_statx, &data, fd); + } +} + +static int +rb_statx(VALUE file, struct statx *stx, unsigned int mask) +{ + VALUE tmp; + int result; + + tmp = rb_check_convert_type_with_id(file, T_FILE, "IO", idTo_io); + if (!NIL_P(tmp)) { + rb_io_t *fptr; + GetOpenFile(tmp, fptr); + result = statx_without_gvl(fptr->fd, NULL, AT_EMPTY_PATH, mask, stx); + file = tmp; + } + else { + FilePathValue(file); + file = rb_str_encode_ospath(file); + result = statx_without_gvl(AT_FDCWD, RSTRING_PTR(file), 0, mask, stx); + } + RB_GC_GUARD(file); + return result; +} + +static VALUE +statx_birthtime(struct statx *stx) +{ + return rb_time_nano_new(stx->stx_btime.tv_sec, stx->stx_btime.tv_nsec); +} +#endif + static int rb_stat(VALUE file, struct stat *st) { @@ -2280,7 +2346,6 @@ rb_file_ctime(VALUE obj) https://github.com/ruby/ruby/blob/trunk/file.c#L2346 return stat_ctime(&st); } -#if defined(HAVE_STAT_BIRTHTIME) /* * call-seq: * File.birthtime(file_name) -> time @@ -2295,6 +2360,7 @@ rb_file_ctime(VALUE obj) https://github.com/ruby/ruby/blob/trunk/file.c#L2360 * */ +#if defined(HAVE_STAT_BIRTHTIME) static VALUE rb_file_s_birthtime(VALUE klass, VALUE fname) { @@ -2307,6 +2373,23 @@ rb_file_s_birthtime(VALUE klass, VALUE f https://github.com/ruby/ruby/blob/trunk/file.c#L2373 } return stat_birthtime(&st); } +#elif defined(HAVE_STATX) +static VALUE +rb_file_s_birthtime(VALUE klass, VALUE fname) +{ + struct statx stx; + + if (rb_statx(fname, &stx, STATX_BTIME) < 0) { + int e = errno; + FilePathValue(fname); + rb_syserr_fail_path(e, fname); + } + if (!(stx.stx_mask & STATX_BTIME)) { + /* birthtime is not supported on the filesystem */ + rb_notimplement(); + } + return statx_birthtime(&stx); +} #else # define rb_file_s_birthtime rb_f_notimplement #endif -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/