ACCEPT(2)

名称
accept - ソケット上の接続を受け入れる

ライブラリ
libc

書式
<sys/types.h> <sys/socket.h> int accept(int s, struct sockaddr * restrict addr, socklen_t * restrict addrlen)

解説
引数 s は socket(2) で作成され、 bind(2) でアドレスにバインドされ、 listen(2) も済ませて接続を待ち受けているソケットです。 accept() システムコールは、待ち行列上の最初の接続要求を取り出し、 新しいソケットを作成し、オリジナルのソケット s から O_NONBLOCK プロパティの状態を継承した そのソケットへ新しいファイル記述子を割り当てます。

接続要求が待ち行列上に存在せず、 しかもオリジナルのソケットが非ブロッキングとマークされていない場合、 accept() は接続要求があるまで呼び出し側をブロックします。 オリジナルのソケットが非ブロッキングとマークされており、 しかも待ち行列に接続要求が存在しない場合、 accept() は後述のようにエラーを返します。 接続が成立したソケットは、それ以上の接続を受け入れるために 使用できません。 オリジナルのソケット s は開いたままです。

引数 addr は結果の引数で、 通信レイヤに既知の接続エンティティのアドレスで埋められます。 addr 引数の正確な形式は通信が行われるドメインで決まります。 アドレス情報が要望されない場合には、 addr にヌルポインタを指定することができます。 この場合は addrlen は使用されず、これもヌルであるべきです。 そうでない場合には addrlen は、値と結果の引数です。 これは最初は addr が指す空間のサイズを含んでいなければなりません。 戻り時には、返されるアドレスの実際の長さ (バイト単位) を含むことになります。 この呼び出しは、コネクションをベースとしたソケットタイプ、 現在では SOCK_STREAM とともに使用されます。

読取りでソケットを select(2) することによって、 accept() するソケットを選ぶことができます。

ISO または DATAKIT のような明瞭な確認が必要な特定のプロトコルでは、 accept() は単に次の接続要求を待ち行列から除くだけで、 確認は行わないと考えられます。 確認は、新しいファイル記述子についての 通常の読取りまたは書込みによって行うことができ、 拒絶は新しいソケットを閉じる事によって実現できます。

ある種のアプリケーションにおいては、内向きの接続を accept_filter(9) で前処理することにより、性能が向上するかもしれません。

戻り値
システムコールはエラーがあった場合 -1 を返します。 処理が正常に完了した場合、受け付けたソケットの 記述子である非負整数を返します。

エラー
accept() システムコールは次の場合に失敗します:

[EBADF]
    記述子が有効ではありません。

[EINTR]
    accept() 操作が割り込まれました。

[EMFILE]
    プロセスの記述子テーブルが満杯です。

[ENFILE]
    システムファイルテーブルが満杯です。

[ENOTSOCK]
    記述子がファイルを参照しておりソケットではありません。

[EINVAL]
    listen(2) がソケット記述子に対して呼び出されていません。

[EFAULT]
    addr 引数がユーザアドレス空間の書込み可能な部分にありません。

[EWOULDBLOCK]
    ソケットが非ブロッキングとマークされ、さらに 受け付けるべき接続要求が存在しません。

[ECONNABORTED]
    接続要求が到着しましたが、待ち行列で待機している 間に閉じてしまいました。

関連項目
bind(2), connect(2), getpeername(2), listen(2), select(2), socket(2), accept_filter(9)

歴史
accept() システムコールは 4.2BSD で登場しました。