IO#statfs and File::Statfs

Issue #9772 has been updated by Akira T…

Yui NARUSE wrote:

statfs では f_type の類がとれないからですね。[ruby-core:62150]

なるほど。

では、IO#statfs では f_type の類は必須で、
f_type の類が提供されない環境では statvfs があっても
IO#statfs は提供しないということでしょうか?

なお、NetBSDとOpenBSDでは動くようにした…はずです。

OpenBSD 5.5 が出たので記念にインストールして試してみたところ、コンパイルできない感じです。

% uname -mrsv
OpenBSD 5.5 GENERIC#271 amd64
% make up all
Updating '.':
At revision 45793.
./revision.h unchanged
        CC = gcc
        LD = ld
        LDSHARED = gcc -shared
        CFLAGS = -O0 -fno-fast-math -ggdb3 -Wall -Wextra 
-Wno-unused-parameter -Wno-parentheses -Wno-long-long 
-Wno-missing-field-initializers -Wunused-variable -Werror=pointer-arith 
-Werror=write-strings -Werror=declaration-after-statement 
-Werror=implicit-function-declaration -Werror=deprecated-declarations 
-std=iso9899:1999
        XCFLAGS = -D_FORTIFY_SOURCE=2 -fstack-protector 
-fno-strict-overflow -fvisibility=hidden -DRUBY_EXPORT -fPIE
        CPPFLAGS = -DRUBY_DEBUG_ENV   -I. 
-I.ext/include/x86_64-openbsd5.5 -I./include -I.
        DLDFLAGS = -fstack-protector -pie
        SOLIBS =
Reading specs from /usr/lib/gcc-lib/amd64-unknown-openbsd5.5/4.2.1/specs
Target: amd64-unknown-openbsd5.5
Configured with: OpenBSD/amd64 system compiler
Thread model: posix
gcc version 4.2.1 20070719
compiling file.c
file.c: In function 'rb_io_statfs':
file.c:1153: error: storage size of 'st' isn't known
file.c:1161: warning: implicit declaration of function 'fstatvfs'
file.c:1153: warning: unused variable 'st'
file.c: In function 'statfs_memsize':
file.c:5358: error: invalid application of 'sizeof' to incomplete type 
'statfs_t'
file.c: In function 'statfs_new_0':
file.c:5373: error: invalid application of 'sizeof' to incomplete type 
'statfs_t'
file.c:5374: error: dereferencing pointer to incomplete type
file.c:5374: error: dereferencing pointer to incomplete type
file.c: In function 'rb_statfs_init':
file.c:5423: error: storage size of 'st' isn't known
file.c:5428: warning: implicit declaration of function 'statvfs'
file.c:5435: error: invalid application of 'sizeof' to incomplete type 
'statfs_t'
file.c:5436: error: dereferencing pointer to incomplete type
file.c:5423: warning: unused variable 'st'
file.c: In function 'rb_statfs_init_copy':
file.c:5454: error: invalid application of 'sizeof' to incomplete type 
'statfs_t'
file.c:5455: error: dereferencing pointer to incomplete type
file.c:5455: error: dereferencing pointer to incomplete type
file.c: In function 'statfs_bsize':
file.c:5495: error: dereferencing pointer to incomplete type
file.c: In function 'statfs_blocks':
file.c:5509: error: dereferencing pointer to incomplete type
file.c: In function 'statfs_bfree':
file.c:5523: error: dereferencing pointer to incomplete type
file.c: In function 'statfs_bavail':
file.c:5537: error: dereferencing pointer to incomplete type
file.c: In function 'statfs_files':
file.c:5551: error: dereferencing pointer to incomplete type
file.c: In function 'statfs_ffree':
file.c:5565: error: dereferencing pointer to incomplete type
file.c: In function 'statfs_inspect':
file.c:5627: error: dereferencing pointer to incomplete type
file.c:5628: error: dereferencing pointer to incomplete type
file.c:5628: error: dereferencing pointer to incomplete type
file.c:5628: error: dereferencing pointer to incomplete type
file.c:5629: error: dereferencing pointer to incomplete type
file.c:5629: error: dereferencing pointer to incomplete type
*** Error 1 in /home/akr/tst1/ruby (Makefile:330 'file.o': @ gcc -O0 
-fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter 
-Wno-parenthe...)
zsh: exit 1     make up all
% egrep -i 'statv?fs' .ext/include/x86_64-openbsd5.5/ruby/config.h
#define HAVE_STRUCT_STATVFS 1
#define HAVE_FSTATFS 1
#define HAVE_FSTATVFS 1

ヘッダファイルが足りないという感じかなぁ


Feature #9772: IO#statfs and File::Statfs

  • Author: Yui NARUSE
  • Status: Assigned
  • Priority: Normal
  • Assignee: Yukihiro M.
  • Category:
  • Target version:

IO#statfs and File::Statfs を追加しませんか。
(テストで statfs.f_type が必要だったのでとりあえず追加してしまっていますが)

statfs(2) は Unix 系 OS
でそこそこ普及している、あるパスが属するファイルシステムについての情報を得るためのシステムコールです。
OS によって多少差がありますが、だいたい以下の様な情報が得られます。

 struct statfs {
 uint32_t f_type;                /* type of filesystem */
 uint64_t f_bsize;               /* filesystem fragment size */
 uint64_t f_blocks;              /* total data blocks in filesystem 

/
uint64_t f_bfree; /
free blocks in filesystem /
int64_t f_bavail; /
free blocks avail to
non-superuser /
uint64_t f_files; /
total file nodes in filesystem
/
int64_t f_ffree; /
free nodes avail to
non-superuser /
char f_fstypename[MFSNAMELEN]; /
filesystem type name */
};

f_type の値が OS 依存だったり、Linux 以外だとそもそもどれがどの値かきちんと定義されていないとか
ツッコミどころの多い API ではあるのですが、他では得られない情報が得られます。

たとえば、以前から CRuby で使われている用途としては、あるファイルの乗っているファイルシステムが、
HFS+ かどうかがわかります。言い換えると、ファイル名が正規化されているかどうかがわかります。
ありがちな反論として、書き込めば正規化されるかわかるだろうというのがありえますが、
目当てのファイルと同じディレクトリに書き込めるとは限りません。
違うディレクトリだと別のファイルシステムがマウントされている可能性があります。

なお今回の用途は、SEEK_DATA/SEEK_HOLEができるか否かを、実際にやってみる以外の方法で知りたかった、というものです。
(Rubyのテストなのにやってみて調べるではテストにあまりならない)