Project

General

Profile

Actions

Misc #15615

closed

File.birthtimeがLinux環境で有効なファイル作成時刻を得られなかった場合の挙動について

Added by Glass_saga (Masaki Matsushita) about 5 years ago. Updated about 5 years ago.

Status:
Closed
Assignee:
-
[ruby-core:91607]

Description

File.birthtimeはファイルの作成時刻を返すメソッドです。
これまでLinux環境ではこのメソッドは実装されておらず、呼び出すとNotImplementedErrorが発生していましたが、r67088から一部のLinux環境でもFile.birthtimeが動作するようになりました。
Linux環境でのFile.birthtimeは、statx()というLinux 4.11から導入されたシステムコールを使うことで実装されています。

statx()には以下の特徴があります。

  1. stat()では取得できなかった情報が取れる
  • ファイル作成時刻
  • 圧縮や暗号化の有無などの属性
  1. どの情報に興味があるかをマスクで指定して使う
  • 指定した情報が返されるとは限らず、指定していない情報まで返される場合もある
  • 指定された情報の一部または全部を返せなかった場合でも戻り値は0であり、errnoもセットされない
  1. struct statxというstruct statとは異なる構造体を返す
  2. 返されたstatx構造体のうち、どの情報が有効であるかはstx_maskというメンバに格納される

statx()でファイルの作成時刻が得られるかどうかはファイルシステム依存であり、有効な値が得られない場合があります。
2.に挙げたように、statx()はこの場合でも0を返しerrnoもセットされません。
r67088では、stx_maskを参照して作成時刻が有効であるかどうかを確かめ、無効であった場合はNotImplementedErrorraiseします。
File.birthtimeTimeを返すことが期待されているので、値が無効だからといってnilを返す訳にもいかないと考えたからです。

しかし、NotImplementedErrorはプラットフォーム依存で機能の実装・未実装が異なる場合に用いられていることが多いようです。
少なくともfile.cの他の部分ではNotImplementedErrorはそのように使われています。
また、spec/ruby/core/file/birthtime_spec.rbには以下のような部分があります。

  platform_is :linux, :openbsd do
    it "raises an NotImplementedError" do
      lambda { File.birthtime(@file) }.should raise_error(NotImplementedError)
    end
  end

このテスト自体の是非はともかく、このようにNotImplementedErrorがプラットフォーム依存で発生するものと期待されている面はあるのではないかと思います。
そう考えると、ファイルシステム依存でNotImplementedErrorを発生させることは好ましくないかもしれません。
※ r67115ではErrno::ENOSYSを発生させるよう変更されました。

このような状況で、statx()で有効なファイル作成時刻が得られなかった場合File.birthtimeはどのように動作すべきかをこのチケットで議論いただければと思います。

Actions #1

Updated by Glass_saga (Masaki Matsushita) about 5 years ago

  • Related to Misc #15614: DevelopersMeeting20190311Japan added
Actions #2

Updated by Glass_saga (Masaki Matsushita) about 5 years ago

  • Related to deleted (Misc #15614: DevelopersMeeting20190311Japan)

Updated by nobu (Nobuyoshi Nakada) about 5 years ago

  • Description updated (diff)

とりあえずNotImplementedErrorとも一番近そうなENOSYSを投げるようにしましたが、本来セットされていないerrnoを装うよりはRuntimeErrorあたりのほうがいいのではないかと思います。
もしくは次点でnil

Actions #4

Updated by Glass_saga (Masaki Matsushita) about 5 years ago

  • Status changed from Open to Closed

Applied in changeset trunk|r67338.


file.c: raise NotImplementedError instread of Errno::ENOSYS

[Misc #15615]

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0