Skip to content

Commit 2fef49f

Browse files
authored
Merge pull request #3309 from Watson1978/dir-fchdir-and-for-fd
Dir: fchdir と for_fd を追加 (Ruby 3.3)
2 parents 5f7b7e0 + cb757a8 commit 2fef49f

1 file changed

Lines changed: 69 additions & 0 deletions

File tree

manual/api/_builtin/Dir.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,43 @@ p Dir.pwd #=> "/var/spool/mail"
135135
p Dir.chdir("~/.ssh") # => Errno::ENOENT
136136
```
137137

138+
#@since 3.3
139+
- **SEE** [m:Dir.fchdir]
140+
#@end
141+
142+
#@since 3.3
143+
### def fchdir(fd) -> 0
144+
### def fchdir(fd) { ... } -> object
145+
146+
カレントディレクトリを、整数のファイルディスクリプタ fd が指す
147+
ディレクトリに変更します。
148+
149+
ファイルディスクリプタを UNIX ソケット経由で渡したり子プロセスに渡したりする
150+
場合、[m:Dir.chdir] の代わりに fchdir を使うと TOCTOU (time-of-check to
151+
time-of-use) 脆弱性を避けられます。
152+
153+
ブロックを指定しない場合、カレントディレクトリを fd の指すディレクトリに変更し、
154+
0 を返します。
155+
156+
ブロックを指定した場合、カレントディレクトリの変更はブロックの実行中に限られます。
157+
ブロックの実行結果を返します。
158+
159+
- **param** `fd` -- ディレクトリを指すファイルディスクリプタを整数で指定します。
160+
161+
- **raise** `Errno::EXXX` -- 失敗した場合に発生します。
162+
163+
```ruby title="例"
164+
Dir.chdir("/var/spool/mail")
165+
p Dir.pwd # => "/var/spool/mail"
166+
167+
dir = Dir.new("/usr")
168+
Dir.fchdir(dir.fileno)
169+
p Dir.pwd # => "/usr"
170+
```
171+
172+
- **SEE** [m:Dir.chdir], [m:Dir#fileno], [m:Dir.for_fd]
173+
#@end
174+
138175
### def chroot(path) -> 0
139176

140177
ルートディレクトリを path に変更します。
@@ -362,6 +399,38 @@ Dir.mktmpdir do |tmpdir|
362399
end
363400
```
364401

402+
#@since 3.3
403+
### def for_fd(fd) -> Dir
404+
405+
整数のディレクトリファイルディスクリプタ fd が指すディレクトリを表す、
406+
新しい [c:Dir] オブジェクトを返します。
407+
408+
返される [c:Dir] オブジェクトには対応するパスがないため、
409+
[m:Dir#path] は nil を返します。
410+
411+
このメソッドは POSIX 2008 で定義された fdopendir() を使用します。
412+
POSIX 非対応のプラットフォームでは実装されておらず、
413+
[c:NotImplementedError] が発生します。
414+
415+
- **param** `fd` -- ディレクトリを指すファイルディスクリプタを整数で指定します。
416+
417+
```ruby title="例"
418+
require 'tmpdir'
419+
420+
Dir.mktmpdir do |tmpdir|
421+
d0 = Dir.new(tmpdir)
422+
d1 = Dir.for_fd(d0.fileno)
423+
424+
p d1.class # => Dir
425+
p d0.path # => tmpdir のパス
426+
p d1.path # => nil
427+
d0.close
428+
end
429+
```
430+
431+
- **SEE** [m:Dir#fileno], [m:Dir#path], [m:Dir.fchdir]
432+
#@end
433+
365434
### def exist?(file_name) -> bool
366435

367436
file_name で与えられたディレクトリが存在する場合に真を返します。

0 commit comments

Comments
 (0)