588 Commits
Author SHA1 Message Date
Yusuke EndohandClaude Opus 5.5 8d205a7e2f Pass errno of readdir to the GVL callback
nogvl_readdir reported a readdir failure by reading errno after
re-acquiring the GVL. Under M:N threads, the thread may be resumed on
another native thread there, and errno is per native thread, so the
exception had a wrong class.

    # strace -f -e trace=getdents64 -e inject=getdents64:error=EIO ruby test.rb
    p Ractor.new {
      4.times { Thread.new { loop { File.exist?("/nonexistent") } } }
      sleep 0.1
      Dir.children(".") rescue $!.class
    }.value
    #=> Errno::ENOENT (should be Errno::EIO)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:16:53 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 7cceceae94 Fix build where struct dirent has no d_type
`Dir.scan` broke the build on Haiku. Leave the type unknown there and let the `lstat` fallback below fill it in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 11:15:42 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 ee3d6c987b Use rb_len_t for the lengths and indices left in long
These still held String and Array lengths and indices in long, or cast them to long. rb_len_t is still long everywhere, so the generated code does not change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 16:45:25 +09:00
Hiroshi SHIBATAandClaude Opus 5 224dc5c110 Use rb_len_t for path lengths
The file, dir, load and ruby.c changes go together because rb_get_expanded_load_path() returns the maximum path length through a pointer. Lengths passed to the Windows string conversion helpers that take `long *` stay `long`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-09 14:00:15 +09:00
Burdette Lamar d84403c039 [DOC] Harmonize unlink doc 2026-09-28 09:28:21 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 5feb9db04d dir.c: Remove mkdir, rmdir and opendir overrides for Windows
include/ruby/win32.h and win32/dir.h have mapped them to the rb_w32_u* functions since 5b98b2ce39.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:48:30 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 d65eccb775 dir.c: Remove redundant case in has_magic
On Windows the default case already sets hasalpha for '~' because IS_WIN32 is 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:48:30 +09:00
Hiroshi SHIBATAandClaude Opus 5.5 1a367ebfea dir.c: Remove USE_NAME_ON_FS_BY_FNMATCH
DOSISH is defined only on _WIN32, which has used USE_NAME_ON_FS_REAL_BASENAME since 45df1c24d2, so this code is never compiled. It even passes an undeclared `basename` to do_opendir.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 19:48:30 +09:00
Matt Valentine-House 3ebb1b2cab dir.c: keep GC-registered globals shareable or unregistered
last_cwd is set on init in the main Ractor, but Dir.pwd attempts to
store into it. When this is done on a child Ractor we violate the
invariant that the owning and registering Ractor must be the same. On a
normal build the use-after-free is invisible, because we only zero out
the flags, so the cache check compares the slot bytes as usual and just
thinks it's a cache miss.

It gets flagged on ASAN builds
2026-09-25 19:24:10 +01:00
Nobuyoshi Nakada ea2836f7ec [Feature #17548] Allow Dir.glob to follow symlinks with ***
Allow recursive matching through directory symlinks while stopping
at links to ancestor directories to avoid cycles.
2026-09-24 18:48:45 +09:00
Peter Zhu d41370aec5 Fix crash in Dir#each/each_child/scan when closed
If the Dir object is closed in the block of Dir#each/each_child/scan, then
it will crash because dirp->dir will be a NULL pointer. The following
script demonstrates the crash:

    d = Dir.open("/")
    d.each { d.close }
2026-09-22 16:03:27 +09:00
Burdette Lamar 6723796db3 [DOC] Harmonize path methods- #18936 2026-09-22 12:05:45 +09:00
Ajay Krishnan a9a3ace7e5 [DOC] Fix Dir scan documentation 2026-07-27 09:24:51 -04:00
Nobuyoshi Nakada 878d20ef1b Use bounded strings in process and cwd handling
Track explicit lengths while parsing command strings and comparing the
current directory. This avoids relying on Ruby string terminators and
makes separators in the generated argument buffer explicit.
2026-07-15 13:28:39 +09:00
John HawthornandLuke Gruber daffaaee73 Mark most TypedData types as THREAD_SAFE_FREE
Set RUBY_TYPED_THREAD_SAFE_FREE on TypedData types whose dfree function
is trivially safe, and only frees its own memory

Types not yet marked as THREAD_SAFE_FREE:
- id2ref_tbl_type: sets the process-global id2ref_tbl to NULL.
- mutex_data_type: unlinks itself from another thread's keeping_mutexes list.
- autoload_data_type: deletes nodes from a shared intrusive list.
- autoload_const_type: deletes itself from a shared list.
- rb_cont_data_type: mutates the shared fiber pool and the global first_jit_cont list.
- rb_fiber_data_type: delegates to cont_free.
- FiberPoolDataType: mutates shared fiber pool free-lists.
- ractor_data_type: reconfigures global VM event-hook flags and call caches.
- exported_object_registry: frees a global table under the VM lock.
- rb_box_data_type (Box::Entry): unlinks classext from other live class and module objects.
- box_ext_cleanup_type: dereferences another String object and calls unlink.
- monitor_data_type: uses the default free, so the flag has no effect.

Co-authored-by: Luke Gruber <luke.gruber@shopify.com>
2026-06-23 13:30:26 -07:00
Burdette Lamar 01641624fe [DOC] Harmonize mkdir methods 2026-06-14 14:01:56 +09:00
Mikhail Dmitrichenko 18ae8d6ded dir.c: fix dirent leak on glob_opendir realloc failure
In glob_opendir(), each directory entry is copied before the entries
array is grown.  If growing ent->sort.entries fails, the function jumps
to the nomem label before the copied entry is stored in the array.

glob_dir_finish() only frees entries already recorded in
ent->sort.entries, so the current rdp is leaked on that error path.

Free rdp before jumping to nomem.

Signed-off-by: Mikhail Dmitrichenko <m.dmitrichenko222@gmail.com>
2026-05-07 20:42:56 +09:00
Jean Boussier cfec60d4be dir.c: cache and revalidate working directory
`rb_dir_getwd_ospath()` is called quite frequently, but
the overwhelming majority of the time, the current directory
didn't change.

We can also assume that most of the time, `PATH_MAX` is enough
for `getcwd`, hence we can first attempt to use a small stack
buffer rather than always allocate on the heap.

This way we can keep the last `pwd` and revalidate it with no
allocation.

On macOS syscalls are fairly slow, so the gain isn't very large.

macOS:

```
compare-ruby: ruby 4.1.0dev (2026-04-09T05:19:02Z master c091c186e4) +PRISM [arm64-darwin25]
built-ruby: ruby 4.1.0dev (2026-04-09T06:37:20Z get-cwd-cache ea02126d79) +PRISM [arm64-darwin25]
```

|         |compare-ruby|built-ruby|
|:--------|-----------:|---------:|
|Dir.pwd  |    105.183k|  113.420k|
|         |           -|     1.08x|
```

Linux (inside virtualized Docker)

```
compare-ruby: ruby 4.1.0dev (2026-04-07T08:26:25Z master fcd210086c) +PRISM [aarch64-linux]
built-ruby: ruby 4.1.0dev (2026-04-09T06:38:09Z get-cwd-cache 6774af9ba7) +PRISM [aarch64-linux]
```

|         |compare-ruby|built-ruby|
|:--------|-----------:|---------:|
|Dir.pwd  |      4.157M|    5.541M|
|         |           -|     1.33x|
2026-04-10 11:49:58 +02:00
John Hawthorn 126b657bd1 Use rb_ensure instead of guard objects for Dir.pwd
This replaces GC-based buffer guards (rb_imemo_tmpbuf,
TypedData_Wrap_Struct) with rb_ensure to clean up malloc/xmalloc memory
when an exception occurs.
2026-02-19 17:39:44 -08:00
Jean Boussier c9a49411dc Dir.scan: fallback to lstat when encountering DT_UNKNOWN
This was part of the spec accepted in [Feature #17001] but that
I forgot to include in the initial implementation.

to ensure coverage, we always go though the fallback path in debug
mode.
2026-02-13 13:19:52 +01:00
Nobuyoshi Nakada 0e4bad888e Adjust indent [ci skip] 2026-02-13 16:15:43 +09:00
Jean Boussier 3b5ee7488c Dir.scan: return or yield children along with their type
[Feature #21800]

There are numerous ruby tools that need to recursively scan
the project directory, such as Zeitwerk, rubocop, etc.

All of them end up listing childs of a directory then for each child
emit a `stat` call to check if it's a directory or not.

This is common enough for a pattern that on most operating
systems, `struct dirent` include a `dtype` member that allows to
check the file type without issuing a any extra system calls.

By yielding that type, we can make these routines twice as fast.

```
$ hyperfine './miniruby --disable-all --yjit ../test.rb' 'OPT=1 ./miniruby --disable-all --yjit ../test.rb'
Benchmark 1: ./miniruby --disable-all --yjit ../test.rb
  Time (mean ± σ):      1.428 s ±  0.062 s    [User: 0.342 s, System: 1.070 s]
  Range (min … max):    1.396 s …  1.601 s    10 runs

Benchmark 2: OPT=1 ./miniruby --disable-all --yjit ../test.rb
  Time (mean ± σ):     673.8 ms ±   5.8 ms    [User: 146.0 ms, System: 527.3 ms]
  Range (min … max):   659.7 ms … 679.6 ms    10 runs

Summary
  OPT=1 ./miniruby --disable-all --yjit ../test.rb ran
    2.12 ± 0.09 times faster than ./miniruby --disable-all --yjit ../test.rb
```

```ruby
if ENV['OPT']
  def count_ruby_files
    count = 0
    queue = [File.expand_path(__dir__)]
    while dir = queue.pop
      Dir.scan(dir) do |name, type|
        next if name.start_with?(".")

        case type
        when :directory
          queue << File.join(dir, name)
        when :file
          count += 1 if name.end_with?(".rb")
        end
      end
    end
    count
  end
else
  def count_ruby_files
    count = 0
    queue = [File.expand_path(__dir__)]
    while dir = queue.pop
      Dir.each_child(dir) do |name|
        next if name.start_with?(".")

        abspath = File.join(dir, name)
        if File.directory?(abspath)
          queue << abspath
        else
          count += 1 if name.end_with?(".rb")
        end
      end
    end
    count
  end
end

10.times do
  count_ruby_files
end
```
2026-02-12 15:52:42 +01:00
Peter Zhu b0ce1fd549 Combine rb_imemo_tmpbuf_auto_free_pointer and rb_imemo_tmpbuf_new 2025-09-15 09:25:20 -04:00
Collin Funk c1c7934b63 [Bug #21128] Include fcntl.h before checking for O_CLOEXEC
On glibc O_CLOEXEC is defined in fcntl.h and not unistd.h so this change
prevents the macro from being redefined.
2025-02-17 13:05:18 +09:00
Soutaro Matsumoto c7a638747a Fix constant documents (#12357)
Delete duplicated `Document-const:` directives

Those directives are attached to `rb_define_const` and `rb_file_const` where we don’t need them because the functions are supported by RDoc.
2024-12-17 11:58:00 +09:00
Jeremy EvansandNobuyoshi Nakada f2919bd11c Add error checking to readdir, telldir, and closedir calls in dir.c
Raise SystemCallError exception when these functions return an error.

This changes behavior for the following case (found by the tests):

```ruby
dir1 = Dir.new('..')
dir2 = Dir.for_fd(dir1.fileno)
dir1.close
dir2.close
```

The above code is basically broken, as `dir1.close` closed the file
descriptor.  The subsequent `dir2.close` call is undefined behavior.
When run in isolation, it raises Errno::EBADF after the change, but
if another thread opens a file descriptor between the `dir1.close`
and `dir2.close` calls, the `dir2.close` call could close the file
descriptor opened by the other thread.  Raising an exception is much
better in this case as it makes it obvious there is a bug in the code.

For the readdir check, since the GVL has already been released,
reacquire it rb_thread_call_with_gvl if an exception needs to be
raised.

Due to the number of closedir calls, this adds static close_dir_data
and check_closedir functions.  The close_dir_data takes a
struct dir_data * and handles setting the dir entry to NULL regardless
of failure.

Fixes [Bug #20586]

Co-authored-by: Nobuyoshi Nakada <nobu.nakada@gmail.com>
2024-09-12 10:04:10 -07:00
Nobuyoshi Nakada 05502c1dda Add a macro to initialize struct getattrlist_args 2024-07-17 12:00:27 +09:00
Jeremy Evans dabb6c49aa Release GVL around {,f}getattrlist calls in dir.c
Fixes [Bug #20587]
2024-07-16 19:20:17 -07:00
Jeremy Evans 8ade9994bf Release GVL around system calls in dir.c
* Release GVL for fdopendir calls
* Release GVL for readdir calls
* Release GVL for chdir call in dir_chdir0
* Release GVL for fchdir call in dir_fchdir
* Release GVL for chroot calls
* Release GVL for lstat calls
* Release GVL for stat calls
* Release GVL for fstatat calls
* Release GVL for getpwnam call in rb_home_dir_of
  (technically in file.c, but called from dir.c)

This does not release GVL for readdir/stat/lstat on Windows,
as that causes issues because the emulation functions that
are called in win32.c require the GVL.

This also removes some explicit casts either to or from void *,
which are allowed implicitly.  The remaining casts to or from
void * are part of function pointer casts, which are not
allowed implicitly and will generate a warning.
2024-07-14 12:02:00 -07:00
Yudai Takada 278a7cb057 [DOC] Fix a typo in dir.c
s/Retruns/Returns/
2024-06-12 10:42:01 +00:00
Jean Boussier 7c12169230 Eliminate internal uses of Data_Wrap_Struct
Ref: https://github.com/ruby/ruby/pull/10872

These should be the last internal uses of the old `Data` API
inside Ruby itself. Some use remain in a couple default gems.
2024-06-02 13:59:11 +02:00
Nobuyoshi Nakada 5326337d4f [Feature #20244] Issue a single Warning.warn call
Make the entire series of message lines a multiline string so that the
`Warning.warn` hook can receive them in a single call.
2024-03-14 18:33:28 +09:00
Nobuyoshi NakadaandAlan Wu 67fe047821 [Feature #20244] Register global variable for another thread
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2024-03-14 18:33:28 +09:00
Nobuyoshi Nakada 4bb8f8582f [Feature #20244] Show the conflicting another chdir block 2024-03-14 18:33:28 +09:00
Nobuyoshi Nakada 8fe86feecd [Feature #20244] Extract chdir_lock and its stuffs 2024-03-14 18:33:28 +09:00
Nobuyoshi Nakada d86c4e553e Define IO_WITHOUT_GVL macro 2024-01-24 20:51:50 +09:00
Xavier Noria aad246feba s/SafeStringValue/StringValue/
The macro SafeStringValue() became just StringValue() in c5c05460ac,
and it is deprecated nowadays.

This patch replaces remaining macro usage. Some occurrences are left in
ext/stringio and ext/win32ole, they should be fixed upstream.

The macro itself is not deleted, because it may be used in extensions.
2024-01-12 12:24:48 -08:00
Nobuyoshi Nakada 494e6b54ab [DOC] Add links from File::Constants in dir.c to File constants
Due to the bug ruby/rdoc#1067, `rb_file_const` needs `Document-const`
directives.
2023-12-18 20:17:44 +09:00
Victor Shepelev 570d7b2c3e [DOC] Adjust some new features wording/examples. (#9183)
* Reword Range#overlap? docs last paragraph.

* Docs: add explanation about Queue#freeze

* Docs: Add :rescue event docs for TracePoint

* Docs: Enhance Module#set_temporary_name documentation

* Docs: Slightly expand Process::Status deprecations

* Fix MatchData#named_captures rendering glitch

* Improve Dir.fchdir examples

* Adjust Refinement#target docs
2023-12-14 23:01:48 +02:00
Jeremy Evans f49af3c969 Make Dir#chdir never yield args, and return block return value
If no block is given, return 0 instead of nil for consistency
with Dir.chdir and Dir.fchdir.
2023-12-11 22:31:16 -08:00
Victor Shepelev 07734b51c6 [DOC] Small fixes for documentation rendering
Mostly just fixing RDoc's incorrect treatment of `+`
2023-12-09 13:54:33 +09:00
Nobuyoshi Nakada 0cdad3b92a Add RUBY_REFERENCES
Instead of `RUBY_REFERENCES_START` and `RUBY_REFERENCES_END`, so that
auto-indent works well.
2023-11-30 21:39:28 +09:00
Nobuyoshi Nakada 30f7b7a053 Prefix REF_EDGE and REFS_LIST_PTR with RUBY_
Also move `struct` so that `typedef`-ed names can be used.
2023-11-30 21:39:28 +09:00
Peter Zhu b040c529a0 Implement dir on VWA 2023-11-22 09:36:54 -05:00
Nobuyoshi Nakada 63fdfa1312 [DOC] Link Dir.exist? to File.directory? 2023-11-14 17:29:15 +09:00
Nobuyoshi Nakada b01118f29c [DOC] Describe Dir.home 2023-11-14 17:20:57 +09:00
Koichi Sasada be1bbd5b7d M:N thread scheduler for Ractors
This patch introduce M:N thread scheduler for Ractor system.

In general, M:N thread scheduler employs N native threads (OS threads)
to manage M user-level threads (Ruby threads in this case).
On the Ruby interpreter, 1 native thread is provided for 1 Ractor
and all Ruby threads are managed by the native thread.

From Ruby 1.9, the interpreter uses 1:1 thread scheduler which means
1 Ruby thread has 1 native thread. M:N scheduler change this strategy.

Because of compatibility issue (and stableness issue of the implementation)
main Ractor doesn't use M:N scheduler on default. On the other words,
threads on the main Ractor will be managed with 1:1 thread scheduler.

There are additional settings by environment variables:

`RUBY_MN_THREADS=1` enables M:N thread scheduler on the main ractor.
Note that non-main ractors use the M:N scheduler without this
configuration. With this configuration, single ractor applications
run threads on M:1 thread scheduler (green threads, user-level threads).

`RUBY_MAX_CPU=n` specifies maximum number of native threads for
M:N scheduler (default: 8).

This patch will be reverted soon if non-easy issues are found.

[Bug #19842]
2023-10-12 14:47:01 +09:00
Nobuyoshi Nakada 50520cc193 [DOC] Missing comment markers 2023-09-27 16:18:05 +09:00
Burdette Lamar bcc160b449 [DOC] RDoc for File::Constants (#8103) 2023-07-23 10:24:19 -04:00
Stan Lo 0db58dd0db [ruby/irb] Declare rdoc as dependency
(https://github.com/ruby/irb/pull/648)

IRB already has several features that rely on rdoc, such as:

- Autocompletion's document dialog
- Autocompletion's `PerfectMatchedProc`
- The `show_doc` command
- Easter egg

And we could use its pager more in the future too. So it makes sense to
declare rdoc as a dependency instead of relying on the one bundled with
Ruby.

https://github.com/ruby/irb/commit/4dffbb1dd3
2023-07-18 13:53:31 +00:00