WRITE(2) | Linux Programmer's Manual | WRITE(2) |
write - ファイルディスクリプター (file descriptor) に書き込む
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
write() は、 buf が指すバッファーから、ファイルディスクリプター fd が参照するファイルへ、最大 count バイトを書き込む。
書き込まれるバイト数は count よりも小さくなることがある。 例えば、書き込み対象の物理メディアに十分な領域がない場合、 リソース上限 RLIMIT_FSIZE に達した場合 (setrlimit(2) 参照)、 count バイト未満の書き込みが行われた後で 呼び出しがシグナルハンドラーにより割り込まれた場合、 などである。 (pipe(7) も参照のこと。)
seek 可能なファイル (つまり lseek(2) が適用できるファイル、例えば通常のファイル) では、 書き込みは現在のファイルオフセットから行われ、 ファイルオフセットは実際に書き込みが行われたバイト数分 加算される。ファイルが O_APPEND で open(2) された場合、ファイルオフセットは書き込み前に ファイルの末尾に設定される。 ファイルオフセットの調整と書き込み操作はアトミックな処理として 実行される。
POSIX は write() が行なわれた後に実行した read(2) が 新しいデータを返すことを要求している。 全てのファイルシステムが POSIX 準拠ではない点に注意すること。
成功した場合、書き込まれたバイト数が返される (ゼロは何も書き込まれなかったことを示す)。 エラーならば -1 が返され、errno が適切に設定される。
count が 0 で、 fd が通常のファイル (regular file) を参照している場合、 write() は後述のエラーのいずれかを検出した場合、失敗を返すことがある。 エラーが検出されなかった場合は、 0 を返し、他に何の影響も与えない。 count が 0 で、 fd が通常のファイル以外のファイルを参照している場合、 その結果は規定されていない。
fd に接続されたオブジェクトによっては、他のエラーが起こるかもしれない。
SVr4, 4.3BSD, POSIX.1-2001.
SVr4 では write が割り込まれると、データが書き込まれる直前ではなく、 その時点で EINTR が返る。
write() が成功して返ってきても、データがディスクに記録されたことを 保証するものではない。 実際、データのためのスペースが確保されたことすら保証されないという バグっぽい実装もある。 これを確実にする唯一の方法は、 全てのデータを write した後に fsync(2) を呼び出すことである。
write() が 1 バイトも書き込まないうちにシグナルハンドラーにより割り込まれた場合、 write() はエラー EINTR で失敗する。 1バイトでも書き込んだ後で割り込まれた場合には、 write() は成功し、書き込んだバイト数を返す。
POSIX.1-2008/SUSv4 セクション XSI 2.9.7 ("Thread Interactions with Regular File Operations") によると、
この後に書かれている API の中に write() と writev(2) である。 スレッド(やプロセス) 間でアトミックに適用することが求められる効果の一つとして、 ファイルオフセットの更新がある。 しかしながら、 バージョン 3.14 より前の Linux では、 この限りではない。 オープンファイル記述 (open file description) を共有する 2 つのプロセスが同時に write() (や writev(2)) を実行した場合、 この I/O 操作ではファイルオフセットの更新に関してはアトミックではなく、 2 つのプロセスから出力されるデータブロックが (間違って) 重なる可能性がある。 この問題は Linux 3.14 で修正された。
close(2), fcntl(2), fsync(2), ioctl(2), lseek(2), open(2), pwrite(2), read(2), select(2), writev(2), fwrite(3)
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。
2015-01-22 | Linux |