|
Solaris での実装
概要
この実装の主要な目的は次のとおりです。
- 大規模ファイルの意味論をサポートできる全ファイル・システムに対して、大規模ファイル・サポートを提供すること (すなわち、UFS、NFS
、CacheFS )
- LFS (Large Files Summit) が指定した最終 API に準拠すること (LFS は標準化のため最終仕様を近日中に
X/Open に提出予定)
- 既存のインタフェースを使用して大規模ファイルへアクセスできるようにコンパイル時環境を提供すること
- 以下で示すユーティリティとライブラリを改修して提供すること
制限事項
- この実装は、次の機能に対するサポートを提供しません。
- 通常の UNIX ファイル以外の大規模ファイル
- キャラクタ・デバイスのマッピング。理由は、mmap() を使用してこれらのデバイスをマッピングすると、ddi-dki
インタフェースに問題が生ずるからです。ただし、これらのデバイスに対する読み取りと書き込みについては、オフセットが 2 GB
を超える場合も、最大値 (1 テラバイト) までサポートします。
- 64-bit のブロック・デバイス
コンパイル環境
コンパイル時にあるシンボルを別のシンボルに変更するためには、新しいコンパイラ指令 #pragma redefine_extname
を使用します。これにより、元の名前を参照している箇所では新しい名前を用いるようにシンボル・テーブルが変更されます。その効果は
#define と似ていますが、文字列の全出現箇所をソース・レベルで置き換えるのではない点が異なります。たとえば、myfunc()
が 32-bit 用の既存のインタフェースで、大規模ファイル対応可能に修正済みだとします。そして、大規模ファイルを扱うために別のインタフェース
myfunc64() が作成されているとします。
|
.. |
|
#if _FILE_OFFSET_BITS == 64 |
/* large file environment */ |
|
#ifdef __PRAGMA_REDEFINE_EXTNAME |
|
#pragma redefine_extname myfunc myfunc64 |
|
#else |
/* __PRAGMA_REDEFINE_EXTNAME */ |
|
#define myfunc myfunc64 |
|
#endif |
/* __PRAGMA_REDEFINE_EXTNAME */ |
|
#endif |
/* _FILE_OFFSET_BITS == 64 */ |
|
.. |
|
extern off_t myfunc(); |
|
#ifdef _LARGEFILE64_SOURCE |
/* explicit 64-bit interface*/ |
|
extern off64_t myfunc64(); |
|
#endif |
/* _LARGEFILE64_SOURCE */ |
|
.. |
上記の宣言を使用しているアプリケーション・プログラムをコンパイルした場合、次の 4 通りの結果が考えられます。
表1. コンパイル環境
|
コンパイル環境 |
コンパイル時に
定義されているフラグ |
エクスポートされた
ソース・シンボル |
バイナリ・シンボルへのマップ |
|
既存の環境 |
なし |
myfunc |
myfunc |
|
大規模ファイル環境 |
_FILE_OFFSET_BITS = 64 |
myfunc |
myfunc64 |
明示的 64-bit インタフェース
(すなわち混合モード) 環境 |
_LARGEFILE64_SOURCE = 1 |
myfunc
myfunc64 |
myfunc
myfunc64 |
|
無意味なモード |
_FILE_OFFSET_BITS = 64
_LARGEFILE64_SOURCE = 1 |
myfunc
myfunc64 |
myfunc64
myfunc64 |
この #pragma 機能は、Sunの SPARC およびx86用の最新コンパイラ
(ProCompilers 4.2) で提供されています。これらのコンパイラはマクロ __PRAGMA_REDEFINE_EXTNAME
を事前に定義しており、それによって新しい #pragma 機能がサポートされていることを示します。新しい #pragma 機能をサポートしていない他のコンパイラ
(Sun のコンパイラの旧バージョンも含む) を用いて構築されたアプリケーションでは、#define によってソース・レベルのマッピングが実行されます。
#define の使用上注意すべき点は、ある関数のアドレスを別の関数にパラメータとして渡す前に最初の関数名を #undef
している場合は、アプリケーションに異常が生ずるという点です。#pragma redefine_extname ではこの問題は起こりません。
インタフェースの拡張
データ型
一部のデータ構造体が、大規模ファイルを正しく扱うことができるように修正されました。次に、構造体と変更点の一覧を示します。
表2. 大規模ファイルの影響を受けるデータ構造体
|
既存の定義 |
修正された定義/ 新規の定義 |
ヘッダ・ファイル |
|
typedef long b1kcnt_t;
typedef ulong_t fsblkcnt_t;
typedef ulong_t fsfilcnt_t; |
<sys/types.h> |
- struct stat
- long st_blocks;
|
- struct stat
- blkcnt_t st_blocks;
|
<sys/stat.h> |
- struct statvfsu
- u_long f_blocks;
- u_long f_bfree;
- u_long f_bavial;
- u_long f_files;
- u_long f_ffree;
- u_long f_favail;
|
- struct statvfsu
- fsblkcnt_t f_blocks;
- fsblkcnt_t f_bfree;
- fsblkcnt_t f_bavial;
- fsfilcnt_t f_files
- fsfilcnt_t f_ffree;
- fsfilcnt_t f_favail;
|
<sys/statvfs.h> |
|
RLIM_SAVED_MAX
RLIM_SAVED_CUR |
<sys/resource.h> |
|
_PC_FILESIZEBITS |
<sys/unistd.h> |
システム・インタフェース
多くの既存 32-bit システム・インタフェースが、大規模ファイルを正しく扱うことができるように修正されました。次に、これらの関数の一覧とそれぞれの想定動作を示します。
表3. 大規模ファイルの影響を受けるインタフェース
|
既存のインタフェース |
エラー |
備考 |
|
execl(), execv(), execle(), execlp(), execvp() |
|
プロセスのリソース制限値が、保存されたリソース制限値にコピーされる。 |
|
fclose(), fflush(), fprintf(), fputc(), fputs(), fputwc(), fputws(),
fseek(), fwrite(), printf(), putc(), putchar(), puts(), putw(),
putwchar(), vfprintf(), vprintf() |
EFBIG |
出力ストリームまたはストリームのバッファをフラッシュする必要が生じたとき、その開始点がオープン時に設定された最大オフセット以上である場合、関数は異常終了する。 |
|
fcntl() |
EOVERFLOW |
1つまたは複数の値が適合しない。 |
|
fgetc(), fgets(), fgetwc(), fgetws(), fread(), fscanf(), getc(),
gets(), getw(), getwc(), getwchar(), scanf() |
EOVERFLOW |
データの読み取り時に、その開始点がオープン時に設定された最大オフセット以上である場合、関数は異常終了する。 |
|
fgetops() |
EOVERFLOW |
fpos_t が現在のファイル位置を保持できない。 |
|
fopen(), freopen(), tmpfile() |
EOVERFLOW |
off_t がファイルのサイズを保持できない。 |
|
fpathconf(), pathconf() |
|
FILESIZEBITS のサポートが追加された。 |
|
fseek() |
EOVERFLOW |
ファイル・オフセットを long に保存できない。 |
|
fstat(), lstat(), stat() |
EOVERFLOW |
stat 構造体が、ファイル・サイズ (off_t st_size)、i ノード (ino_t st_ino)、またはブロック・カウント
(blkcnt_t st_blocks) を表現できない。 |
|
fstatvfs(), statvfs() |
EOVERFLOW |
statvfs 構造体が、合計ブロック数
(fsblkcnt_t f_blocks)、フリー・ブロック数 (fsblkcnt_t f_bfree)、使用可能ブロック数
(fsblkcnt_t f_bavail)、合計 i ノード数
(fsfilcnt_t f_files)、フリー i ノード数(fsfilcnt_t f_ffree)、または使用可能 i
ノード数 (fsfilcnt_t f_favail) を表現できない。 |
|
ftell() |
EOVERFLOW |
ファイル・オフセットを long に保存できない。 |
|
ftruncate() |
EFBIG |
length がオープン時に設定された最大オフセットを超える場合。 |
|
getrlimit(), setrlimit() |
|
保存されたリソース制限値の使用を指定。 |
|
lockf() |
EOVERFLOW |
ロック・オフセットを off_t に保存できない。 |
|
lseek() |
EOVERFLOW |
ファイル・オフセットを off_t 保持できない。 |
|
open(), creat() |
EOVERFLOW |
off_t がファイル・サイズを保持できない。 |
|
mmap() |
EOVERFLOW |
off + len がオープン時に設定された最大オフセットを超える場合。 |
|
read(), readv(), pread() |
EOVERFLOW |
オープン時に設定された最大オフセットを超えて通常ファイルを読み取ろうとした場合。 |
|
readdir(), readdir_r() |
EOVERFLOW |
dirent 構造体が i ノード番号 (ino_t d_ino) またはオフセット (off_t d_off)
を表現できない。 |
|
write(), writev(), pwrite() |
EFBIG |
オープン時に設定された最大オフセットを超えて通常ファイルに書き込もうとした場合。 |
新しい移行用インタフェース
この項で説明するインタフェース、マクロ、およびデータ型は、標準 API の明示的 64-bit バージョンです。移行用インタフェースの関数プロトタイプと意味論は、それぞれの標準バージョンと同等です。
_LARGEFILE64_SOURCE を 1 に設定すると、これらのインタフェースが使用可能になります。
データ型
次の表は、標準のデータ型および構造体の型と、それらに対応する 64-bitデータ型を示します。詳細については、ヘッダを参照してください。
表4. 64-bit 用の拡張定義
|
標準定義 |
64-bit 定義 |
ヘッダ |
- struct dirent
- ino_t d_ino;
- off_t d_off;
|
- struct dirent64
- ino64_t d_ino;
- off64_t d_off;
|
<sys/dirent.h> |
- struct flock
- off_t l_start;
- off_t l_len;
F_SETLK, F_SETLKW,
F_GETLK, F_FREESP |
- struct flock64
- off64_t l_start;
- off64_t l_len;
F_SETLK64, F_SETLKW64,
F_GETLK64, F_FREESP64,
O_LARGEFILE |
<sys/fcntl.h> |
|
fpos_t |
fpos64_t |
<sys/stdio.h> |
|
rlim_t
- struct rlimit
- rlim_t rlim_cur;
- rlim_t rlim_max;
RLIM_INFINITY,
RLIM_SAVED_MAX,
RLIM_SAVED_CUR |
rlim64_t
- struct rlimit64
- rlim64_t rlim_cur;
- rlim64_t rlim_max;
RLIM64_INFINITY,
RLIM64_SAVED_MAX,
RLIM64_SAVED_CUR |
<sys/resource.h> |
- struct stat
- ino_t st_ino;
- off_t st_size;
- blkcnt_t st_blocks;
|
- struct stat64
- ino64_t st_ino;
- off64_t st_size;
- blkcnt64_t st_blocks;
|
<sys/stat.h> |
- struct statvfs
- fsblkcnt_t f_blocks;
- fsblkcnt_t f_bfree;
- fsblkcnt_t f_bavial;
- fsfilcnt_t f_files;
- fsfilcnt_t f_ffree;
- fsfilcnt_t f_favail;
|
- struct statvfs64
- fsblkcnt64_t f_blocks;
- fsblkcnt64_t f_bfree;
- fsblkcnt64_t f_bavial;
- fsfilcnt64_t f_files;
- fsfilcnt64_t f_ffree;
- fsfilcnt64_t f_favail;
|
<sys/statvfs.h> |
off_t;
ino_t
blkcnt_t;
fsblkcnt_t;
fsfilcnt_t; |
off64_t;
ino64_t;
blkcnt64_t;
fsblkcnt64_t;
fsfilcnt64_t; |
<sys/types.h> |
|
_LFS_LARGEFILE64,
_LFS64_STDIO |
<unistd.h> |
|
_CS_LFS64_CFLAGS,
_CS_LFS64_LDFLAGS,
_CS_LFS64_LIBS,
_CS_LFS64_LINTFLAGS |
<sys/unistd.h> |
システム・インタフェース
次の表は、標準 API とそれに対応する 64-bit インタフェースを示します。インタフェース名と影響を受けるデータ型は太字で示してあります。
表5. 64-bit 用の拡張インタフェース
|
既存のインタフェース |
64-bit 定義 |
ヘッダ・ファイル |
|
struct dirent *readdir() |
struct dirent64
*readdir64() |
<dirent.h> |
int creat()
int open() |
int creat64()
int open64() |
<fcntl.h> |
int ftw(.., const struct stat*, ..)
int nftw(.., const struct stat *, ..) |
int ftw64(.., const struct stat64 *, ..)
int nftw64(.., const struct stat64 *, ..) |
<ftw.h> |
int fgetpos()
FILE *fopen()
FILE *freopen()
int fseeko(.., off_t, ..)NEW
int fsetpos(.., const fpos_t *)
off_t ftello() NEW
FILE *tmpfile() |
int fgetpos64()
FILE *fopen64()
FILE *freopen64()
int fseeko64(.., off64_t, ..)
int fsetpos64(.., const fpos64_t *)
off64_t ftello64()
FILE *tmpfilr64() |
<stdio.h> |
|
void mmap(.., off_t) |
void mmap64(.., off64_t) |
<sys/mman.h> |
int getrlimit(.., struct rlimt *)
int setrlimit(.., const struct rlimit *) |
int getrlimit64(.., struct rlimt64 *)
int setrlimit64(.., const struct rlimit64 *) |
<sys/resource.h> |
int fstat(.., struct stat *)
int lstat(.., struct stat *)
int stat(.., struct stat *) |
int fstat64(.., struct stat64 *)
int lstat64(.., struct stat64 *)
int stat64(.., struct stat64 *) |
<sys/stat.h> |
int statvfs(.., struct statvfs *)
int fstatvfs(.., struct statvfs *) |
int statvfs64(.., struct statvfs64 *)
int fstatvfs64(.., struct statvfs64 *) |
<sys/statvfs.h> |
int lockf(.., off_t)
off_t lseek(.., off_t, ..)
int ftruncate(.., off_t)
int truncate(.., off_t) |
int lockf64(.., off64_t)
off64_t lseek64(.., off64_t, ..)
int ftruncate64(.., off64_t)
int truncate64(.., off64_t) |
<unistd.h> |
Solaris ユーティリティのサポート
大規模ファイル処理可能なユーティリティ
|
adb |
audioconvert |
audioplay |
audiorecord |
awk |
|
bdiff |
cachefslog |
cachefsstat |
cachefswssize |
cat |
|
cfsadmin |
cfsfstype |
cfstagchk |
chgrp |
chmod |
|
chown |
cksum |
clri |
cmp |
compress |
|
cp |
crash |
csh |
csplit |
cut |
|
dcopy |
dd |
df |
du |
edquota |
|
egrep |
ff |
fgrep |
file |
find |
|
fsck |
fsdb |
fsirand |
fstyp |
ftp |
|
getconf |
grep |
head |
in.ftpd |
install |
|
join |
jsh |
ksh |
labelit |
ln |
|
lockfs |
ls |
makedbm |
mkdir |
mkfifo |
|
mkfile |
mkfs |
mknod |
more |
mount |
|
mv |
mvdir |
nawk |
ncheck |
newfs |
|
page |
paste |
pathchk |
pax |
pg |
|
quot |
quota |
quotacheck |
quotaoff |
quotaon |
|
rcp |
remsh |
repquota |
rksh |
rm |
|
rmdir |
rsh |
sed |
sh |
split |
|
sum |
swap |
swapadd |
tail |
tee |
|
test |
touch |
tr |
truss |
tunefs |
|
umount |
uncompress |
volcopy |
wc |
zcat |
|
/usr/ucb/chown/usr/ucb/ln |
/usr/ucb/ls |
/usr/ucb/touch |
大規模ファイル対応可能なユーティリティ
|
accept |
admind |
cancel |
comm |
cpio |
|
diff |
diff3 |
diff3prog |
diffh |
diffmk |
|
dircmp |
disable |
ed |
enable |
from |
|
lp |
lpadmin |
lpfilter |
lpforms |
lpmove |
|
lpr |
lpsched |
lpshut |
lpstat |
lpsystem |
|
lpusers |
mail |
mailcompat |
mailq |
mailstats |
|
mailx |
pack |
pcat |
red |
rmail |
|
sdiff |
sendmail |
tar |
unpack |
uudecode |
|
uuencode |
vi |
view |
|
Solaris ライブラリのサポート
|
libTL |
libadm |
libaio |
libauth |
libbc |
|
libbsm |
libc |
libcmd |
libcrypt |
libcurses |
|
libdevinfo |
libelf |
libeti |
libgen |
libgenIO |
|
libintl |
libkrb |
libkstat |
libkvm |
libmapmalloc |
|
libnisdb |
libnsl |
libpkg |
libplot |
libposix4 |
|
libpthread |
librac |
libresolv |
librpcsvc |
libsocket |
|
libthread |
libthread_db |
libtnf |
libtnfprobe |
libvolmgt |
|
nametoaddr |
nsswitch |
scheme |
ucblib/libcurses |
ucblib/librpcsoc |
|
ucblib/libucb |
ucblib/libtermcap |
|
|