bionic (2) accept.2.gz

Provided by: manpages-ja-dev_0.5.0.0.20161015+dfsg-1_all bug

名前

       accept, accept4 - ソケットへの接続を受ける

書式

       #include <sys/types.h>          /* 「注意」参照 */
       #include <sys/socket.h>

       int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

       #define _GNU_SOURCE             /* feature_test_macros(7) 参照 */
       #include <sys/socket.h>

       int accept4(int sockfd, struct sockaddr *addr,
                   socklen_t *addrlen, int flags);

説明

       accept()   システムコールは、接続指向のソケット型  (SOCK_STREAM,  SOCK_SEQPACKET) で用いられる。 この関数
       は、接続待ちソケット socket 宛ての保留状態の接続要求が入っているキューから 先頭の接続要求を取り出し、接続
       済みソケットを新規に生成し、  そのソケットを参照する新しいファイルディスクリプターを返す。 新規に生成され
       たソケットは、接続待ち (listen) 状態ではない。 もともとのソケット sockfd はこの呼び出しによって影響を受け
       ない。

       引き数   sockfd  は、  socket(2)   によって生成され、  bind(2)   によってローカルアドレスにバインドされ、
       listen(2)  を経て接続を待っているソケットである。

       addr 引き数は sockaddr 構造体へのポインターである。  この構造体には接続相手のソケットのアドレスが入ってい
       る。     addr    引き数で返されるアドレスの正確なフォーマットは、    ソケットのアドレス種別によって変わる
       (socket(2)  およびそれぞれのプロトコルの man ページを参照)。 addr が NULL  の場合、  addr  には何も入らな
       い。この場合、 addrlen は使用されず、この引き数は NULL にしておくべきである。

       addrlen  引き数は入出力両用の引き数である。呼び出し時には、呼び出し元が addr が指す構造体のサイズ (バイト
       単位) で初期化しておかなければならない。 返ってくる時には、接続相手のアドレスの実際の大きさが格納される。

       渡されたバッファーが小さ過ぎた場合は、返されるアドレスの末尾が切り詰められる。 この場合には、 addrlen  に
       は、呼び出し時に指定された値よりも大きな値が格納される。

       キューに保留となっている接続要求がなく、  かつソケットが非停止になっていないときは、 accept()  は接続が発
       生するまで呼び出し元を停止 (block) する。 ソケットが非停止になっていて、 待ち状態の接続要求がキューに無い
       ときは、 accept()  はエラー EAGAINEWOULDBLOCK で失敗する。

       ソケットへの接続到着を知るには、 select(2)  または poll(2)  を用いればよい。 新しい接続要求が来るとソケッ
       トは読み込み可能になるので、 そうしたら accept()  を呼んでその接続に対するソケットを取得すればよい。 ある
       いはソケットに設定を行い、何らかのアクションがあったときに  SIGIO を配送 (deliver) させるようにすることも
       できる。詳細は socket(7)  を参照のこと。

       明示的な接続確認 (confirmation) を必要とするようなプロトコル (DECNet など) では、 accept() は単に次の接続
       要求をキューから取り出すだけであり、  接続確認は行わないことに注意せよ。接続確認は、 新しいファイルディス
       クリプターに対する 通常の読み取り/書き込みによってなされ、接続拒否 (rejection)   は新しいソケットをクロー
       ズすることによってなされる。  現在のところ、  Linux  上でこれらのセマンティクスを持つのは DECNet だけであ
       る。

       flags が 0 の場合、 accept4()  は accept()  と同じである。 flags に以下の値をビット毎の論理和 (OR) で指定
       することで、 異なる動作をさせることができる。

       SOCK_NONBLOCK   新しく生成されるオープンファイル記述 (open file description) の O_NONBLOCK ファイルステー
                       タスフラグをセットする。 このフラグを使うことで、 O_NONBLOCK をセットするために  fcntl(2)
                       を追加で呼び出す必要がなくなる。

       SOCK_CLOEXEC    新しいファイルディスクリプターに対して  close-on-exec  (FD_CLOEXEC)  フラグをセットする。
                       このフラグが役に立つ理由については、 open(2)  の O_CLOEXEC フラグの説明を参照のこと。

返り値

       成功した場合、これらのシステムコールは 受け付けたソケットのディスクリプターである非負の整数値を返す。  エ
       ラーが発生した場合は -1 を返し、 errno を適切に設定する。

   エラー処理
       Linux  の  accept()   (と accept4())  は、新しいソケットにおける、発生済みのネットワークエラーを accept()
       からのエラーコードとして渡す。 この振舞いは BSD  ソケットの実装とは異なる。  信頼性の高い動作を行うために
       は、  アプリケーションはプロトコルで定義されているネットワークエラーの検知を accept()  のあとに行い、それ
       らのエラーを EAGAIN と同じように扱い、再試行 (retry) を行うべきである。 TCP/IP では、以下のエラーが該当す
       る: ENETDOWN, EPROTO, ENOPROTOOPT, EHOSTDOWN, ENONET, EHOSTUNREACH, EOPNOTSUPP, ENETUNREACH

エラー

       EAGAIN または EWOULDBLOCK
              ソケットが非停止になっていて、  かつ受付け対象の接続が存在しない。 POSIX.1-2001 は、この場合にどち
              らのエラーを返すことも認めており、 これら  2  つの定数が同じ値を持つことも求めていない。  したがっ
              て、移植性が必要なアプリケーションでは、両方の可能性を 確認すべきである。

       EBADF  ディスクリプターが不正。

       ECONNABORTED
              接続が中止された。

       EFAULT addr 引き数がユーザーアドレス空間の書き込み可能領域にない。

       EINTR  有効な接続が到着する前に捕捉されたシグナルによって システムコールが中断された。 signal(7)  参照。

       EINVAL ソケットが接続待ち状態ではない。もしくは、 addrlen が不正である (例えば、負の場合など)。

       EINVAL (accept4())  flags に不正な値が指定されている。

       EMFILE 1プロセスがオープンできるファイルディスクリプター数の上限に達した。

       ENFILE オープンされたファイルの総数がシステム全体の上限に達していた。

       ENOBUFS, ENOMEM
              メモリーが足りない。 多くの場合は、システムメモリーが足りないわけではなく、 ソケットバッファーの大
              きさによるメモリー割り当ての制限である。

       ENOTSOCK
              ディスクリプターはソケットではなくファイルを参照している。

       EOPNOTSUPP
              参照しているソケットの型が SOCK_STREAM でない。

       EPROTO プロトコルエラー。

       上記に加えて、Linux の accept()  は以下のエラーで失敗する:

       EPERM  ファイアウォールのルールにより接続が禁止された。

       この他に、新しいソケットに対するネットワークエラーが返されることもある。 これらはそれぞれのプロトコルで定
       義されている。    いろいろな   Linux   カーネルでは、   以下に示すようなエラーを返すこともある。   ENOSR,
       ESOCKTNOSUPPORT, EPROTONOSUPPORT, ETIMEDOUT.  ERESTARTSYS がトレースの最中に現れることもある。

バージョン

       accept4()  システムコールは Linux 2.6.28 以降で利用可能である。 glibc でのサポートはバージョン 2.10  以降
       で利用可能である。

準拠

       accept(): POSIX.1-2001, SVr4, 4.4BSD, (accept()  は 4.2BSD で初めて実装された).

       accept4()  は非標準の Linux による拡張である。

       Linux   では、   accept()    が返す新しいソケットは   listen   を行っているソケットの  ファイル状態フラグ
       (O_NONBLOCKO_ASYNC など) を継承「しない」。 この動作は標準的な  BSD  ソケットの実装とは異なっている。
       移植性を考慮したプログラムではファイル状態フラグが継承されるかどうかは 前提にせず、常に accept() が返した
       ソケットに対して全ての必要なフラグを明示的に設定するように すべきである。

注意

       POSIX.1-2001 では <sys/types.h> のインクルードは必須とされておらず、 Linux ではこのヘッダーファイルは必要
       ではない。  しかし、歴史的には、いくつかの実装 (BSD 系) でこのヘッダーファイルが 必要であり、移植性が必要
       なアプリケーションではこのファイルを インクルードするのが賢明であろう。

       SIGIO が届けられた後や、 select(2)  または poll(2)  が読み込み可能イベントを返した後に、 必ずしも待機中の
       接続があるとは限らない。 なぜならその接続は、 accept()  が呼ばれる前に、非同期的なネットワークエラーや 他
       のスレッドから呼ばれた  (別の)  accept  によって  削除されているかもしれないからである。   この場合、その
       accept() 呼び出しは停止 (block) し、次の接続の到着を待ちつづける。 accept()  に停止を行わせないようにする
       には、引き数に渡すソケット sockfdO_NONBLOCK フラグをセットしておく必要がある (socket(7)  を見よ)。

   socklen_t 
       accept()  の第 3 引き数は、もともと int * と宣言されていた (libc4 や libc5, 4.x BSD, SunOS 4, SGI  など多
       くのシステムではそうなっている)。  POSIX.1g draft 標準は、 これを size_t * に変更しようとし、SunOS 5 では
       そう宣言されている。 後に POSIX drafts には socklen_t * が含まれるようになり、 Single UNIX  Specification
       や glibc2 ではこのように宣言されるようになった。 Linus Torvald の発言を引用する:

       「まともなライブラリを作りたければ、 "socklen_t" のサイズは int と同じにしなきゃならない。 さもないと BSD
       ソケット層を破壊することになっちゃう。 POSIX は最初こいつを size_t にしたんで、  ぼくは彼らに文句をがなり
       たてた  (多分そういう人は他にもいたと思う。多くはなかったようだけど)。 こいつを size_t にするのは完全にい
       かれてる。 例えば 64 ビットアーキテクチャーでは、 size_t が "int"  と同じサイズだなんてことはほとんどない
       からね。  このサイズは "int" と 同じでなきゃ『ダメ』なんだ。 BSD ソケットインターフェースっていうのはそう
       いうものなんだから。 まあともかく POSIX の人たちも、  "socklen_t"  を作るという解決策をなんとかひねり出し
       た。  そもそも最初から放っておけば良かったんだが、  いじっちゃった以上、 名前付きの型を持たせなきゃならな
       い、と思ったみたいだね。 なんでかはわかんないけど (きっと最初にやっちまった馬鹿な間違いで顔をつぶしたくな
       かったから、 こっそり名前を付け替えて自分たちの大失敗をごまかそうとしたんだろう)。」

       bind(2)  参照。

関連項目

       bind(2), connect(2), listen(2), select(2), socket(2), socket(7)

この文書について

       この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告
       に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。