This changeset basically replaces `ruby_xmalloc(x * y)` into
`ruby_xmalloc2(x, y)`. Some convenient functions are also
provided for instance `rb_xmalloc_mul_add(x, y, z)` which allocates
x * y + z byes.
Cfuncs that use rb_scan_args with the : entry suffer similar keyword
argument separation issues that Ruby methods suffer if the cfuncs
accept optional or variable arguments.
This makes the following changes to : handling.
* Treats as **kw, prompting keyword argument separation warnings
if called with a positional hash.
* Do not look for an option hash if empty keywords are provided.
For backwards compatibility, treat an empty keyword splat as a empty
mandatory positional hash argument, but emit a a warning, as this
behavior will be removed in Ruby 3. The argument number check
needs to be moved lower so it can correctly handle an empty
positional argument being added.
* If the last argument is nil and it is necessary to treat it as an option
hash in order to make sure all arguments are processed, continue to
treat the last argument as the option hash. Emit a warning in this case,
as this behavior will be removed in Ruby 3.
* If splitting the keyword hash into two hashes, issue a warning, as we
will not be splitting hashes in Ruby 3.
* If the keyword argument is required to fill a mandatory positional
argument, continue to do so, but emit a warning as this behavior will
be going away in Ruby 3.
* If keyword arguments are provided and the last argument is not a hash,
that indicates something wrong. This can happen if a cfunc is calling
rb_scan_args multiple times, and providing arguments that were not
passed to it from Ruby. Callers need to switch to the new
rb_scan_args_kw function, which allows passing of whether keywords
were provided.
This commit fixes all warnings caused by the changes above.
It switches some function calls to *_kw versions with appropriate
kw_splat flags. If delegating arguments, RB_PASS_CALLED_KEYWORDS
is used. If creating new arguments, RB_PASS_KEYWORDS is used if
the last argument is a hash to be treated as keywords.
In open_key_args in io.c, use rb_scan_args_kw.
In this case, the arguments provided come from another C
function, not Ruby. The last argument may or may not be a hash,
so we can't set keyword argument mode. However, if it is a
hash, we don't want to warn when treating it as keywords.
In Ruby files, make sure to appropriately use keyword splats
or literal keywords when calling Cfuncs that now issue keyword
argument separation warnings through rb_scan_args. Also, make
sure not to pass nil in place of an option hash.
Work around Kernel#warn warnings due to problems in the Rubygems
override of the method. There is an open pull request to fix
these issues in Rubygems, but part of the Rubygems tests for
their override fail on ruby-head due to rb_scan_args not
recognizing empty keyword splats, which this commit fixes.
Implementation wise, adding rb_scan_args_kw is kind of a pain,
because rb_scan_args takes a variable number of arguments.
In order to not duplicate all the code, the function internals need
to be split into two functions taking a va_list, and to avoid passing
in a ton of arguments, a single struct argument is used to handle
the variables previously local to the function.
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct. This commit deletes ANYARGS from
rb_ensure, which also revealed many arity / type mismatches.
* dir.c (join_path_from_pattern): add the last slash for directory
matching.
* test/ruby/test_dir.rb (test_glob_recursive_directory): add a test
for above.
[ruby-core:91110] [Bug #15540]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66838 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Braces were expended before ruby_glob0(). This caused to call
replace_real_basename() for same plain patterns repeatedly.
Move blace expansion into glob_helper() in ruby_glob0() to reduce
replace_real_basename() call.
This fix changes the order of glob results.
[Feature #13167] [Fix GH-1864]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64810 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (do_stat, do_lstat, do_opendir): need the length of the base
path for fstatat() when fd is valid.
* dir.c (glob_helper): fix for platforms where DT_UNKNOWN is not
available, e.g. Solaris.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64067 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This reverts commit r63982.
It breaks build on Solaris 11.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64038 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (do_stat, do_lstat): need the length of the base path for
fstatat() when fd is valid.
* dir.c (glob_helper): fix for platforms where DT_UNKNOWN is not
available, e.g. Solaris.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63982 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (glob_helper): fix directory glob which resulted in lacking
the first byte. adjust the length of basename to be appended as
well as removing the heading path, not the length of the joined
path. [ruby-dev:50588] [Bug #14899]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63909 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
SuSE 10 has openat(), but not O_CLOEXEC
Reported-by: wangpeiwen
[ruby-core:87591] [Bug #14864]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63720 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (dir_s_glob): [DOC] added an example of Dir.glob using
pattern list. [ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63041 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (rb_push_glob): do not assume string is NUL terminated
always, shared substring may not in the future.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63034 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (GlobPathValue): should be used in rb_push_glob only.
other methods should use FilePathValue.
https://hackerone.com/reports/302338
* dir.c (rb_push_glob): expand GlobPathValue
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62989 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Flags are 3rd argument of openat(2) while the 4th argument
(mode_t) is unnecessary for our uses. This bug exists since
Ruby 2.5 from r58860 and was discoverd by strace.
* dir.c (nogvl_opendir_at): use openat correctly
[Feature #13056] [Feature #14346]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61754 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
On further examination, Dir.chdir with a block from multiple
threads is thread-unsafe given our use of the chdir_blocking and
chdir_thread global variables.
This bug was only introduced in r60583 so not part of any stable
release.
Dir.chdir without a block can still make senses in a MT context
as only one thread could be cwd-sensitive and other threads do
not care which directory they're in.
* dir.c (dir_chdir): keep GVL here
(dir_s_chdir): release GVL if no block given
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61091 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Support nanosec file timestamp on Windows 8 or later.
Original patches are written by kubo (Kubo Takehiro).
Windows 7 and earlier also supports nanosec file timestamp, but it's too
accurate than system time. so, this feature is disabled on such versions.
[Feature #13726]
this change also includes [Misc #13702]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61013 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Use cast from `char*` to `void*` instead of union in opendir_without_gvl,
because convert from `void*` to `char*` without union in nogvl_opendir.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60875 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (opendir_without_gvl, with_gvl_gc_for_fd, opendir_at): check the VM is
already initialized before calling rb_thread_call_with{out,}_gvl().
[Bug #14115]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60837 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
openat(2) also performs a path lookup, so it is also subject
to pathological slowdowns like opendir(3) and open(2) syscalls.
* dir.c (struct opendir_at_arg): new struct for callback
(with_gvl_gc_for_fd): new callback for rb_thread_call_with_gvl
(gc_for_fd_with_gvl): moved up
(nogvl_opendir_at): extracted from do_opendir
(opendir_at): new wrapper to release GVL for opendir_at
(do_opendir): use new wrappers to release GVL
(nogvl_dir_empty_p): adjust for gc_for_fd_with_gvl
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60831 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
opendir(3) is subject to the same pathological slowdowns on
slow or unreliable filesystems as open(2), so release the GVL
to avoid stalling the entire VM like we do with IO#open
* dir.c (nogvl_opendir): new function
(opendir_without_gvl): new function
(dir_initialize): s/opendir/&_without_gvl/
(do_opendir): ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60830 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Using readdir(3) without any locking causes thread-safety
problems if directory streams get shared between threads. On
ancient platforms, readdir(3) may have thread-safety problems
even on different directory streams.
Using readdir_r(3) is not viable, either, as it's deprecated
due to name overflow problems.
So for now, rely on GVL as in previous Rubies and perhaps
consider per-"struct dir_data" mutexes for modern platforms
which allow concurrent calls to readdir(3) on different
directory streams.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60774 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (readdir_without_gvl): check the VM is already initialized before
calling rb_thread_call_without_gvl().
[Bug #14108]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60772 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Release GVL around all remaining readdir calls from the Dir
class to prevent pathological stalls on slow filesystems in
multi-threaded applications.
opendir, rewinddir, closedir calls are not affected yet, but
will be changed in future commits.
In the future, further work may be done consolidate multiple GVL
releasing calls to reduce overhead, similar to how changes to
Dir.empty? were made in r60111
* dir.c (nogvl_readdir): new function
(readdir_without_gvl): ditto
(dir_read): s/READDIR/readdir_without_gvl/
(dir_each_entry): ditto
(glob_helper): ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60769 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This avoids blocking the entire VM when operating on slow or
unreliable filesystems. Instead, only the thread performing
the mkdir or rmdir operation is blocked and other threads
are free to proceed.
* dir.c (nogvl_mkdir): new function
(nogvl_rmdir): ditto
(dir_s_mkdir): release GVL
(dir_s_rmdir): ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60595 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
mode_t is the correct type for these syscalls and it can be
easier-to-understand. It may also help portability to future
platforms and improve type checking.
* dir.c (dir_s_mkdir): use mode_t for mkdir(2)
* file.c (chmod_internal): use mode_t for chmod(2)
(rb_file_s_chmod): s/int/mode_t/
(lchmod_internal): ditto, deref pointer as in chmod_internal
(rb_file_s_lchmod): pass pointer as in rb_file_s_chmod
(rb_file_s_rename): use mode_t for umask(2)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60592 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
chdir(2) is subject to all the pathological slowdowns and
caveats as open(2) on slow or unreliable filesystems, so ensure
other threads can proceed while this is happening.
* dir.c (nogvl_chdir): new function
* dir.c (dir_chdir): release GVL
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60583 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This reverts commit r60341,r60342,r60344,r60345.
Breaking compabitility of the order of result breaks many tests.
To avoid such effort to fix tests, the order should be kept.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60478 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Because NaCl and PNaCl are already sunset status.
see https://bugs.chromium.org/p/chromium/issues/detail?id=239656#c160
configure.ac: Patch for this file was provided by @nobu.
[Feature #14041][ruby-core:83497][fix GH-1726]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60374 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This reverts commit r60253 because it causes on error on Linux.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60255 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This converts all slow syscalls in the Dir.empty? implementation
to release GVL. We avoid unnecessarily GVL release and
reacquire for each slow call (opendir, readdir, closedir) and
instead only release and acquire the GVL once in the common
case.
Benchmark results show a small degradation in single-threaded
performance:
Execution time (sec)
name trunk built
dir_empty_p 0.689 0.758
Speedup ratio: compare with the result of `trunk' (greater is better)
name built
dir_empty_p 0.909
* dir.c (rb_gc_for_fd_with_gvl): new function
(nogvl_dir_empty_p): ditto
(dir_s_empty_p): use new functions to release GVL
* benchmark/bm_dir_empty_p.rb: new benchmark
[ruby-core:83071] [Feature #13958]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60111 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (glob_helper): fix up r59527, dot files other than current
directory should not be included unless FNM_DOTMATCH is given.
[ruby-core:82266] [Bug #13785]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59529 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (glob_helper): fix up r59481 for old kernels, which
provide d_type member but just always set DT_UNKNOWN for any
entries. [ruby-core:82266] [Bug #13785]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59527 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (glob_helper): utilize d_type even if no recursive
pattern, to reduce stat/lstat syscalls in subsequent
glob_helper.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59481 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (glob_helper): fix globbing based on a relative path Dir.
[Feature #13056]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59479 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (dir_glob_options): relax base option. ignore when nil
or an empty string as :base option. [Feature #13056]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59476 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
The lifetime of a String VALUE must match or exceed the lifetime
of its R*_PTR result; otherwise the GC can while reclaim the
VALUE while the R*_PTR result is in use.
* dir.c (ruby_brace_expand): add var parameter for GC guard
(ruby_brace_glob_with_enc): adjust call
(file_s_fnmatch): ditto
(push_glob): remove misplaced GC guard
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59416 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* win32/win32.c (rb_dir_getwd_ospath): Windows implementation
moved from dir.c. get rid of freeing malloced memory by xfree.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59061 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (rb_dir_getwd_ospath): return cwd path in the OS path
encoding.
* file.c (rb_realpath_internal): work in the OS path encoding
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59040 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (glob_helper): yield globbed part only without the base
directory path part if the base is given. [Feature#13056]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58901 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c: [DOC] document the new `base` keyword argument of Dir.glob
[Feature #13056]; also improve docs for Dir.glob and Dir[].
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58885 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (dir_s_each_child, dir_s_children): Dir.each_child and
Dir.children which are similar to Dir.foreach and Dir.entries
respectively, except to exclude "." and "..". [Feature #11302]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58879 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (glob_helper): support Dir instance as `base` option.
[Feature#13056]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58860 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
enc is the name of the variable used in the example, not the name of the
keyword argument (encoding).
The documentation used to wrongly suggest that the keyword argument name was
"enc" which could cause people try try to call `Dir.open("thing", enc: "utf-8")`
Author: Olivier Lacan <hi@olivierlacan.com>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58566 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (glob_helper): raise a SystemCallError exception when
opendir() failed, except for ENOENT, ENOTDIR, and EACCES. this
behavior predates 1.0; the comments in glob.c claimed that
glob() returned -1 on error but actualy the pointer to a global
variable, then dir_glob() did check only -1 as the comments, and
ignored actual errors. [ruby-core:80226] [Bug #13276]
dir.c: ruby_glob_funcs_t
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58156 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (is_case_sensitive): use getattrlist() if fgetattrlist()
is unavailable, on OSX 10.5. [ruby-core:68829] [Bug #11054]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57248 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (rb_glob): merge rb_glob2 which is used only here.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56608 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (do_opendir): retry after GC when the limit for open file
descriptors reached.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56467 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (rb_dir_s_empty_p): use rb_gc_for_fd for the condition to
invoke GC by errno.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (to_be_ignored): make an inline function to get rid of
multiple errno function calls.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56465 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* *.c: rename rb_funcall2 to rb_funcallv, except for extensions
which are/will be/may be gems. [Fix GH-1406]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55773 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (USE_NAME_ON_FS): name constants.
* USE_NAME_ON_FS_REAL_BASENAME: platform dependent APIs to get
real basenames.
* USE_NAME_ON_FS_BY_FNMATCH: select the matching basename by
fnmatch.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55470 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (push_pattern, push_glob): deal with read paths as UTF-8
to stat later, on Windows as well as OS X.
[ruby-core:73868] [Bug #12081]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53877 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (rb_dir_s_empty_p): add Dir.empty? method, which tells the
argument is the name of an empty directory. [Feature #10121]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53841 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
NULL checking is finished Before call of memsize functions.
See r52979.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52986 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* dir.c (dir_initialize): use rb_gc_for_fd for ENOMEM
* ext/socket/init.c (rsock_socket): ditto
* ext/socket/socket.c (rsock_socketpair): ditto
* internal.h (rb_gc_for_fd): prototype
* io.c (rb_gc_for_fd): remove static
[ruby-core:71623] [Feature #11727]
Manpages for opendir(2), socket(2), and socketpair(3posix)
describe ENOMEM as a possible error for each of these;
handle it consistently with our existing wrappers for
open(2)/pipe(2) etc...
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52726 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Solaris 10 does not have dirfd, but the file descriptor of a
directory is stored in the d_fd or dd_fd member in the DIR struct.
Note that Solaris 11 has dirfd(3C).
* configure.in: checks for DIR.d_fd and DIR.dd_fd on Solaris 10.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52472 b2dd03c8-39d4-4d8f-98ff-823fe69b080e