WRITE(2)

名称
write, writev, pwrite - 出力の書込み

ライブラリ
libc

書式
<sys/types.h> <sys/uio.h> <unistd.h> ssize_t write(int d, const void *buf, size_t nbytes) ssize_t writev(int d, const struct iovec *iov, int iovcnt) ssize_t pwrite(int d, const void *buf, size_t nbytes, off_t offset)

解説
write() システムコールは、 buf が指すバッファから記述子 d が参照するオブジェクトに nbytes のデータを書き込もうとします。 writev() システムコールは同様の動作をしますが、iov[0], iov[1], ..., iov[iovcnt-1] という iov 配列のメンバが指定する iovcnt バッファから出力データを集めます。 pwrite() システムコールは同じ機能を実行しますが、ファイルポインタを修正せずに、 ファイルの特定場所に書き込みます。

writev() では、 iovec 構造体が以下のように定義されています:

    struct iovec {
    	void   *iov_base;    /* ベースアドレス */
    	size_t  iov_len;     /* 長さ */
    };

各 iovec エントリは、書き込むデータがあるメモリのベースアドレスと 領域の長さを指定します。 writev() システムコールは、常に領域全体を書き込んでから次に進みます。

シーク機能があるオブジェクトでは、 write() は d に関連するポインタが指定する位置で開始します。 lseek(2) を参照してください。 write() から戻ると、ポインタは書き込まれたバイト数だけ進みます。

シーク機能がないオブジェクトでは、常に現在位置から書き込みます。 このようなオブジェクトに関連するポインタの値は未定義です。

実ユーザがスーパユーザでない場合、 write() は、ユーザ ID 設定ビットをファイルでクリアします。 これにより、スーパユーザが所有する書込み可能なユーザ ID 設定ファイルを “捕えた” ユーザは、システムセキュリティを突破できなくなります。

ソケットのように、フロー制御の影響を受けるオブジェクトで 非ブロッキング I/O を使用すると、 write() と writev() は、要求したより少ないバイト数を書き込むことがあります。 戻り値に注意し、可能な場合にはオペレーションの残りを再度試してください。

戻り値
処理が正常に完了すると、書き込まれたバイト数が返されます。 そうでない場合は -1 が返され、エラーを示すためにグローバル変数 errno が設定されます。

エラー
write(), writev() および pwrite() システムコールは、以下の場合にエラーとなり、 ファイルポインタは変更されずに残ります:

[EBADF]
    d 引数が、書込み用に開かれた有効な記述子ではありません。

[EPIPE]
    プロセスによる読取り用に開かれていないパイプに書き込もうとしました。

[EPIPE]
    通信相手のソケットに接続していないタイプ SOCK_STREAM のソケットに書き込もうとしました。

[EFBIG]
    プロセスのファイルサイズ制限か最大ファイルサイズを越えたファイルに 書き込もうとしました。

[EFAULT]
    iov の一部、またはファイルに書き込むデータは、 プロセスに割り当てられたアドレス空間の範囲外を指しています。

[EINVAL]
    d に関連するポインタが負になっています。

[ENOSPC]
    ファイルを含むファイルシステムに、充分なスペースが残っていません。

[EDQUOT]
    ファイルを含むファイルシステムのユーザのディスクブロック割当量が 使い尽くされています。

[EIO]
    ファイルシステムに読み書きしている間に入出力エラーが発生しました。

[EINTR]
    書込みが完了する前にシグナルが割り込みました。

[EAGAIN]
    ファイルは非ブロッキング入出力の印がついた状態で、しかも、 すぐにデータを書き込める状態ではありません。

[EROFS]
    スライスの先頭にあるディスクラベル領域に書込みを行おうとしました。 ディスクラベル領域への書込みを有効にするには disklabel(8) -W を参照してください。

writev() は、以下のエラーを戻すことがあります:

[EDESTADDRREQ]
    connect(2) を使用して書込み先アドレスを設定した UNIX ドメインデータグラムソケットに書き込む場合に、書込み先が使用できません。

[EINVAL]
    iovcnt 引数が 0 以下になっているか、 IOV_MAX より、大きくなっています。

[EINVAL]
    iov 配列 iov_len 値の 1 つが負になっています。

[EINVAL]
    iov 配列 iov_len 値の合計が、32 ビット整数をオーバフローしました。

[ENOBUFS]
    ソケットに書き出している時に mbuf のプールを使い尽くしました。

pwrite() システムコールは、以下のエラーを戻すことがあります:

[EINVAL]
    offset の値が負です。

[ESPIPE]
    ファイル記述子が、パイプ、ソケット、FIFO に関連しています。

関連項目
fcntl(2), lseek(2), open(2), pipe(2), select(2)

規格
write() システムコールは、 p1003.1-90 に適合しています。 writev() システムコールと pwrite() システムコールは、 xpg4.2 に適合しています。

歴史
pwrite() 関数は、 AT&T UNIX で登場しました。 writev() システムコールは、 4.2BSD で登場しました。 write() 関数は、 AT&T UNIX で登場しました。