1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     socket_Berkeley.h
4 
5   Copyright (C)2010 Nintendo Co., Ltd.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Rev: 35776 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_SOCKET_SOCKET_BERKLEY_H_
17 #define NN_SOCKET_SOCKET_BERKLEY_H_
18 
19 #include <nn/socket/socket_Types.h>
20 #include <nn/socket/socket_Const.h>
21 #include <nn/socket/socket_IpcWrapper.h>
22 #include <nn/socket/socket_Result.h>
23 
24 /*
25     IPC を介することによって返り値や引数が変わってしまうのを吸収する
26  */
27 
28 namespace nn {
29 namespace socket {
30     /*!
31       @name         ソケット
32 
33       @{
34      */
35 
36     /*!
37       @brief        新しいソケット記述子を作成します。
38 
39                     現在のバージョンでは少なくとも 8 個のソケットを同時に作成することができます。
40 
41       @param[in]    af          @ref PF_INET を指定してください。
42       @param[in]    type        作成するソケットの種類を指定します。
43                                 現時点では @ref SOCK_STREAM と @ref SOCK_DGRAM をサポートしています。
44 
45       @param[in]    protocol    ソケットに用いるプロトコルを指定します。protocol が 0 の場合、
46                                 指定したプロトコルファミリとタイプに対するデフォルトのプロトコルが使われます。
47                                 現時点では  0 を指定してください。
48 
49       @retval       1以上        新しいソケット記述子。
50       @retval       ENETRESET   ソケットライブラリが初期化されていません。
51       @retval       ENETDOWN    ネットワークが利用できません。
52       @retval       EAFNOSUPPORT    サポートされていないアドレスファミリ。
53       @retval       EPROTONOSUPPORT サポートされていないプロトコル。
54       @retval       EMFILE      ソケット記述子をこれ以上作れません。
55       @retval       ENOMEM      メモリ不足。
56       @retval       EPROTOTYPE  サポートされていないソケットタイプ。
57 
58       @see          Close
59     */
Socket(s32 af,s32 type,s32 protocol)60     inline s32 Socket(s32 af, s32 type, s32 protocol)
61     {
62         s32 rval = 0;
63         Result result = detail::Socket(&rval, af, type, protocol);
64         NN_SOCKET_RETURN_IF_FAILED(result);
65         return rval;
66     }
67 
68     /*!
69       @brief        ストリームソケット ( @ref SOCK_STREAM ) を使って接続要求の受付を開始します。
70 
71       @param[in]    s           ソケット記述子を指定します。@ref Socket によって作成したソケット記述子を指定して下さい。
72       @param[in]    backlog     ソケットのリッスンバックログキューに保持する未処理の接続の最大数を指定します。
73                                 backlogが 0 または負の場合、最大数は 1 に設定されます。
74 
75       @retval       0           処理に成功しました。
76       @retval       ENETRESET   ソケットライブラリが初期化されていません。
77       @retval       ENETDOWN    ネットワークが利用できません。
78       @retval       EBADF       不正なソケット記述子。
79       @retval       EOPNOTSUPP  サポートされていない処理。
80       @retval       EINVAL      無効な処理。
81       @retval       ENOBUFS     リソース不足。
82 
83       @see          Bind, Accept
84     */
Listen(s32 s,s32 backlog)85     inline s32 Listen(s32 s, s32 backlog)
86     {
87         s32 rval = 0;
88         Result result = detail::Listen(&rval, s, backlog);
89         NN_SOCKET_RETURN_IF_FAILED(result);
90         return rval;
91     }
92 
93     /*!
94       @brief        着信を受付けます。
95 
96                     接続キューから最初の新しいソケットを接続を取り出し、指定したソケットと同じ
97                     ソケットタイプ、プロトコル、アドレスファミリーの新しいソケットを作成し、
98                     新しいソケット記述子を返します。元のソケットはさらに接続要求を受け付けられる
99                     ようにそのまま残ります。
100 
101                     ソケット記述子が @ref Fcntl によって非封鎖モードに設定されていなければ、
102                     Accept は未処理の接続がキューになければブロックします。
103 
104                     なお、取り出した新しいソケットの代わりにバックログを一つ確保しますが、メモリ不足
105                     などでバックログが確保できなかった場合、着信の有無にかかわらず @ref ENOMEM を返します。
106 
107       @param[in]    s           ソケット記述子を指定します。
108                                 @ref Socket によって作成し、
109                                 @ref Bindによってアドレスをバインドし、
110                                 @ref Listen の呼び出しに成功したソケット記述子を指定して下さい。
111 
112       @param[out]   sockAddr    受け付けた接続相手のソケットアドレスを記録するための
113                                 ソケットアドレス構造体へのポインタを指定します。
114 
115 
116       @retval       1以上       受け付けた接続のソケット記述子。
117       @retval       EINVAL      無効な処理。
118       @retval       ENETRESET   ソケットライブラリが初期化されていません。
119       @retval       ENETDOWN    ネットワークが利用できません。
120       @retval       EBADF       不正なソケット記述子。
121       @retval       EOPNOTSUPP  サポートされていない処理。
122       @retval       ENOBUFS     リソース不足。
123       @retval       EAGAIN      O_NONBLOCK がソケット記述子に設定されていて、
124                                 かつ現在受け付けられる接続がありません。
125       @retval       ECONNABORTED    接続がキャンセルされました。
126       @retval       ENOMEM      メモリ不足
127 
128       @see          Fcntl, GetPeerName, Listen
129     */
Accept(s32 s,SockAddrIn * sockAddr)130     inline s32 Accept(s32 s, SockAddrIn* sockAddr)
131     {
132         s32 rval = 0;
133         Result result = detail::Accept(&rval, s, reinterpret_cast<u8*>(sockAddr), sizeof(SockAddrIn));
134         NN_SOCKET_RETURN_IF_FAILED(result);
135         return rval;
136     }
137 
138     /*!
139       @brief        ソケットにローカルソケットアドレスを割り当てます。
140 
141                     ローカルソケットアドレスは通信元のアドレスのことです。
142                     @ref Socket で作成されたばかりのソケットは、いずれのアドレスにもバインドされません。
143                     <br/>
144                     既ににバインド済みのソケット記述子を指定すると失敗します。
145                     割り当てたローカルソケットアドレスは @ref GetSockName にて取得できます。
146 
147       @param[in]    s           ソケット記述子を指定します。@ref Socket によって作成したソケット記述子を指定して下さい。
148       @param[in]    sockAddr    割り当てるアドレス情報を保持しているソケットアドレス構造体 @ref SockAddrIn へのポインタを指定します。
149 
150       @retval       0           処理に成功しました。
151       @retval       ENETRESET   ソケットライブラリが初期化されていません。
152       @retval       ENETDOWN    ネットワークが利用できません。
153       @retval       EBADF       不正なソケット記述子。
154       @retval       EOPNOTSUPP  サポートされていない処理。
155       @retval       EINVAL      無効な処理。(ソケットがすでにアドレスにバインド済み、など)
156       @retval       EAFNOSUPPORT    サポートされていないアドレスファミリー。
157       @retval       EADDRINUSE  アドレスがすでに使用中。
158 
159       @see          Socket, GetSockName
160     */
Bind(s32 s,const SockAddrIn * sockAddr)161     inline s32 Bind(s32 s, const SockAddrIn* sockAddr)
162     {
163         s32 rval = 0;
164         Result result = detail::Bind(&rval, s, reinterpret_cast<const u8*>(sockAddr), sizeof(SockAddrIn));
165         NN_SOCKET_RETURN_IF_FAILED(result);
166         return rval;
167     }
168 
169     /*!
170       @brief        指定したソケット記述子を使用し指定したリモートホストにへ接続を試みます。
171 
172                     @ref Bind によってソケットにローカルアドレスがバインドされていなかった場合、
173                     @ref Connect によってソケットには使われていないローカルアドレスがバインドされます。
174                     <br/>
175                     ソケットがストリームソケット ( @ref SOCK_STREAM ) の場合には通常は接続が確立するまで
176                     ブロックしますが、 @ref Fcntl によって非封鎖モードに設定されている場合には
177                     可能な限り早く返ります。
178                     この場合 @ref Poll によって接続の確立を調べることができます。
179                     接続の確立に失敗した場合、まず Poll の返す値に POLLRDNORM と POLLWRNORM が立ちます。
180                     接続の失敗は、続けて呼び出したデータ送信関数またはデータ受信関数がエラーを返すこと
181                     で知ることができます。
182                     <br/>
183                     ソケットがデータグラムソケット ( @ref SOCK_DGRAM ) の場合には、データグラムの
184                     送信先ソケットアドレスが変更されるだけですので、 封鎖モードと非封鎖モードでの動作に
185                     違いはありません。
186 
187 
188       @param[in]    s           ソケット記述子を指定します。@ref Socket によって作成したソケット記述子を指定して下さい。
189       @param[in]    sockAddr    通信先のアドレス情報を保持しているソケットアドレス構造体へのポインタを指定します。
190 
191       @retval       0           処理に成功しました。
192       @retval       ENETRESET   ソケットライブラリが初期化されていません。
193       @retval       ENETDOWN    ネットワークが利用できません。
194       @retval       EBADF       不正なソケット記述子。
195 
196       @see
197     */
Connect(s32 s,const SockAddrIn * sockAddr)198     inline s32 Connect(s32 s, const SockAddrIn* sockAddr)
199     {
200         s32 rval = 0;
201         Result result = detail::Connect(&rval, s, reinterpret_cast<const u8*>(sockAddr), sizeof(SockAddrIn));
202         NN_SOCKET_RETURN_IF_FAILED(result);
203         return rval;
204     }
205 
206     /*!
207       @brief        ソケットを通じてリモートホストからデータ(メッセージ)の受信を試みます。
208 
209                     通常はソケットがメッセージを受信するまでブロックしますが、@ref Fcntl によって
210                     非封鎖モードに設定されている場合、もしくは flags に MSG_DONTWAIT  を 指定した場合には、
211                     関数を呼び出した時点で受信されていたデータのみを取得し、ブロックしません。
212                     <br/>
213                     データグラムソケット ( @ref SOCK_DGRAM ) では、メッセージ全体が単一処理で読み出されます。
214                     メッセージが与えられたバッファに収まらず、flags に @ref MSG_PEEK が 指定されていない場合には、
215                     超過した分のデータは破棄されます。
216                     <br/>
217                     ストリームソケット ( @ref SOCK_STREAM ) では、メッセージ境界は無視されます。
218                     この場合、データは利用可能になり次第ユーザーへ返ります。
219 
220       @param[in]    s           ソケット記述子を指定します。@ref Socket もしくは @ref Accept によって作成したソケット記述子を指定して下さい。
221       @param[in]    buf         受信データを読み出すバッファへのポインタを指定します。
222       @param[in]    len         受信データを読み出すバッファのサイズをバイト単位で指定します。
223 
224       @param[in]    flags       メッセージの伝達種別を指定します。
225       @param[out]   sockFrom    通信先のアドレス情報を取得するソケットアドレス構造体へのポインタを指定します。
226                                 ソケットアドレスの len フィールドは適切に初期化 ( 例: sizeof( @ref SockAddrIn ) ) しておく必要があります。
227 
228       @retval       0           ストリームソケット ( @ref SOCK_STREAM ) では、リモートホストがメッセージの送信を終了したため
229                                 これ以上メッセージの受信ができないことを示します。
230                                 データグラムソケット ( @ref SOCK_DGRAM ) では、0 は返りません。
231 
232       @retval       1 以上      受信したメッセージのバイト数です。
233 
234       @retval       ENETRESET   ソケットライブラリが初期化されていません。
235       @retval       EBADF       不正なソケット記述子。
236       @retval       EAGAIN      O_NONBLOCK がソケット記述子に設定されていて(もしくは MSG_DONTWAIT が flags 指定されていて)、
237                                 受信を待つデータもしくは帯域外データがありません。
238 
239       @retval       EINVAL      無効な処理。
240       @retval       EOPNOTSUPP  サポートされていない処理。
241       @retval       ENOTCONN    接続されていません。
242       @retval       ECONNRESET  接続がリセットされました。
243       @retval       EINTR       中止されました。
244       @retval       ETIMEDOUT   時間切れ。
245       @retval       ENETDOWN    ネットワークが利用できません。
246 
247       @see
248     */
RecvFrom(s32 s,void * buf,s32 len,s32 flags,SockAddrIn * sockFrom)249     inline s32 RecvFrom(s32 s, void* buf, s32 len, s32 flags, SockAddrIn* sockFrom)
250     {
251         s32 rval;
252         Result result;
253         if (len <= detail::COPY_OR_MAP_THRESHOLD)
254         {
255             result = detail::RecvFromSmall(&rval, s, reinterpret_cast<u8*>(buf), len, flags, reinterpret_cast<u8*>(sockFrom), sizeof(SockAddrIn));
256         }
257         else
258         {
259             result = detail::RecvFrom(&rval, s, reinterpret_cast<u8*>(buf), len, flags, reinterpret_cast<u8*>(sockFrom), sizeof(SockAddrIn));
260         }
261         NN_SOCKET_RETURN_IF_FAILED(result);
262         return rval;
263     }
264 
265     /*!
266       @brief        ソケットを通じてリモートホストからデータ(メッセージ)の受信を試みます。
267 
268                     受信対象のホストを指定しない以外は @ref RecvFrom と同じです。
269                     詳しくは @ref RecvFrom を参照してください。
270 
271       @param[in]    s           @ref RecvFrom の説明を参照してください。
272       @param[in]    buf         @ref RecvFrom の説明を参照してください。
273       @param[in]    len         @ref RecvFrom の説明を参照してください。
274       @param[in]    flags       @ref RecvFrom の説明を参照してください。
275 
276       @see          RecvFrom
277     */
Recv(s32 s,void * buf,s32 len,s32 flags)278     inline s32 Recv(s32 s, void* buf, s32 len, s32 flags)
279     {
280         return RecvFrom(s, buf, len, flags, NULL);
281     }
282 
283     /*!
284       @brief        ソケットを通じてリモートホストからデータ(メッセージ)の受信を試みます。
285 
286                     受信対象のホストとフラグを指定しない以外は @ref RecvFrom と同じです。
287                     詳しくは @ref RecvFrom を参照してください。
288 
289       @param[in]    s           @ref RecvFrom の説明を参照してください。
290       @param[in]    buf         @ref RecvFrom の説明を参照してください。
291       @param[in]    len         @ref RecvFrom の説明を参照してください。
292 
293       @see          RecvFrom
294     */
Read(s32 s,void * buf,s32 len)295     inline s32 Read(s32 s, void* buf, s32 len)
296     {
297         return RecvFrom(s, buf, len, 0, NULL);
298     }
299 
300     /*!
301       @brief        ソケットを通じてリモートホストへデータ(メッセージ)の送信を試みます。
302 
303                     通常はソケットの送信バッファにメッセージを格納するだけの空きが生じるまでブロックしますが、
304                     @ref Fcntl によって非封鎖モードに設定されている場合、
305                     もしくは flags に MSG_DONTWAIT  を指定した場合にはブロックしません。
306                     <br/>
307                     データグラムソケット ( @ref SOCK_DGRAM ) では、メッセージ全体が単一処理で読み出されます。
308                     メッセージが与えられたバッファに収まらず、flags に MSG_PEEK が 指定されていない場合には、
309                     超過した分のデータは破棄されます。
310                     <br/>
311                     ストリームソケット ( @ref SOCK_STREAM ) では、メッセージ境界は無視されます。
312                     この場合、データは利用可能になり次第ユーザーへ返ります。
313 
314 
315       @param[in]    s           ソケット記述子を指定します。@ref Socket もしくは @ref Accept によって作成したソケット記述子を指定して下さい。
316       @param[in]    buf         送信データを保持しているバッファへのポインタを指定します。
317       @param[in]    len         送信するデータのサイズをバイト単位で指定します。
318       @param[in]    flags       メッセージの伝達種別を指定します。
319       @param[in]    sockTo      通信先のアドレス情報を保持しているソケットアドレス構造体へのポインタを指定します。
320 
321       @retval       0           処理に成功しました。
322       @retval       ENETRESET   ソケットライブラリが初期化されていません。
323       @retval       ENETDOWN    ネットワークが利用できません。
324       @retval       EBADF       不正なソケット記述子。
325 
326       @see
327     */
SendTo(s32 s,const void * buf,s32 len,s32 flags,const SockAddrIn * sockTo)328     inline s32 SendTo(s32 s, const void* buf, s32 len, s32 flags, const SockAddrIn* sockTo)
329     {
330         s32 rval;
331         Result result;
332         if (len <= detail::COPY_OR_MAP_THRESHOLD)
333         {
334             result = detail::SendToSmall(&rval, s,
335                                          reinterpret_cast<const u8*>(buf), len,
336                                          flags,
337                                          reinterpret_cast<const u8*>(sockTo), sizeof(SockAddrIn));
338         }
339         else
340         {
341             result = detail::SendTo(&rval, s,
342                                     reinterpret_cast<const u8*>(buf), len,
343                                     flags,
344                                     reinterpret_cast<const u8*>(sockTo), sizeof(SockAddrIn));
345         }
346         NN_SOCKET_RETURN_IF_FAILED(result);
347         return rval;
348     }
349 
SendToMulti(s32 s,const void * buf,s32 len,s32 flags,const SockAddrIn * sockTo,s32 saCount)350     inline s32 SendToMulti(s32 s, const void* buf, s32 len, s32 flags, const SockAddrIn* sockTo, s32 saCount)
351     {
352         s32 rval;
353         Result result;
354         result = detail::SendToSmallMulti(&rval, s,
355                                           reinterpret_cast<const u8*>(buf), len,
356                                           flags,
357                                           reinterpret_cast<const u8*>(sockTo), sizeof(SockAddrIn), sizeof(SockAddrIn) * saCount);
358         NN_SOCKET_RETURN_IF_FAILED(result);
359         return rval;
360     }
361     /*!
362       @brief        ソケットを通じてリモートホストへデータ(メッセージ)の送信を試みます。
363 
364                     送信対象のホストを指定しない以外は @ref SendTo と同じです。
365                     詳しくは @ref SendTo を参照してください。
366 
367       @param[in]    s           @ref SendTo の説明を参照してください。
368       @param[in]    buf         @ref SendTo の説明を参照してください。
369       @param[in]    len         @ref SendTo の説明を参照してください。
370       @param[in]    flags       @ref SendTo の説明を参照してください。
371 
372       @see          SendTo
373     */
Send(s32 s,const void * buf,s32 len,s32 flags)374     inline s32 Send(s32 s, const void* buf, s32 len, s32 flags)
375     {
376         return SendTo(s, buf, len, flags, NULL);
377     }
378 
379     /*!
380       @brief        ソケットを通じてリモートホストへデータ(メッセージ)の送信を試みます。
381 
382                     送信対象のホストとフラグを指定しない以外は @ref SendTo と同じです。
383                     詳しくは @ref SendTo を参照してください。
384 
385       @param[in]    s           @ref SendTo の説明を参照してください。
386       @param[in]    buf         @ref SendTo の説明を参照してください。
387       @param[in]    len         @ref SendTo の説明を参照してください。
388 
389       @see          SendTo
390     */
Write(s32 s,const void * buf,s32 len)391     inline s32 Write(s32 s, const void* buf, s32 len)
392     {
393         return SendTo(s, buf, len, 0, NULL);
394     }
395 
396     /*!
397       @brief        ソケットを閉じます。閉じられたソケットは以後使用できなくなります。
398 
399                     閉じる対象となるソケットを用いた関数呼び出しがブロックされている場合、
400                     ブロックは解除され、それぞれ所定のエラーを返します。
401                     <br/>
402                     @ref Fcntl  によって非封鎖モードに設定されていないストリームソケット ( SOCK_STREAM  ) を
403                     閉じる場合は、 @ref Linger オプション設定に従って接続が閉じられます。
404                     <br/>
405                     デフォルトでは、Close はブロックせずすぐに処理を返します。
406                     そして、バックグランドで残送信データを自動的に転送してからソケットが使用していたリソースを解放します。
407 
408       @param[in]    s           ソケット記述子を指定します。@ref Socket もしくは @ref Accept によって作成したソケット記述子を指定して下さい。
409 
410       @retval       0           処理に成功しました。
411       @retval       ENETRESET   ソケットライブラリが初期化されていません。
412       @retval       ENETDOWN    ネットワークが利用できません。
413       @retval       EBADF       不正なソケット記述子。
414       @retval       ENOTCONN    接続されていません。
415       @retval       EINVAL      無効な処理。
416 
417       @see          Socket, Fcntl, Shutdown
418     */
Close(s32 s)419     inline s32 Close(s32 s)
420     {
421         s32 rval = 0;
422         Result result = detail::Close(&rval, s);
423         NN_SOCKET_RETURN_IF_FAILED(result);
424         return rval;
425     }
426 
427     /*!
428       @brief        ソケットの送受信処理の一部もしくは全てを遮断します。
429 
430 
431       @param[in]    s           ソケット記述子を指定します。@ref Socket もしくは @ref Accept によって作成したソケット記述子を指定して下さい。
432       @param[in]    how         遮断方法の種類を指定します。 <br/>
433                                 - SHUT_RD 以降の受信処理を不可にします。<br/>
434                                 - SHUT_WR 以降の送信処理を不可にします。<br/>
435                                 - SHUT_RDWR 以降の送受信処理を不可にします。<br/>
436       @retval       0           処理に成功しました。
437       @retval       ENETRESET   ソケットライブラリが初期化されていません。
438       @retval       ENETDOWN    ネットワークが利用できません。
439       @retval       EBADF       不正なソケット記述子。
440       @retval       ENOTCONN    接続されていません。
441       @retval       EINVAL      無効な処理。
442       @see
443     */
Shutdown(s32 s,s32 how)444     inline s32 Shutdown(s32 s, s32 how)
445     {
446         s32 rval = 0;
447         Result result = detail::Shutdown(&rval, s, how);
448         NN_SOCKET_RETURN_IF_FAILED(result);
449         return rval;
450     }
451 
452     /*!
453       @brief        ソケットの内部設定値や内部状態情報を取得します。
454 
455       @param[in]    s           ソケット記述子を指定します。@ref Socket もしくは @ref Accept によって作成したソケット記述子を指定して下さい。
456       @param[in]    level       対象のプロトコル層 @ref SocketLevel を指定します。
457       @param[in]    optname     対象のオプション @ref SocketOptionType を指定します。
458       @param[out]   optval      設定の格納先バッファを指定します。
459       @param[in,out] optlen     optname に応じた optval のバッファ長を指定します。
460 
461       @retval       0           処理に成功しました。
462       @retval       ENETRESET   ソケットライブラリが初期化されていません。
463       @retval       ENETDOWN    ネットワークが利用できません。
464       @retval       EBADF       不正なソケット記述子。
465       @retval       EINVAL      無効な処理。
466       @see          SetSockOpt
467     */
GetSockOpt(s32 s,s32 level,int optname,void * optval,int * optlen)468     inline s32 GetSockOpt(s32 s, s32 level, int optname, void* optval, int* optlen)
469     {
470         s32 rval = 0;
471         Result result = detail::GetSockOpt(&rval, s, level, optname, reinterpret_cast<u8*>(optval), optlen);
472         NN_SOCKET_RETURN_IF_FAILED(result);
473         return rval;
474     }
475 
476     /*!
477       @brief        ソケットの内部設定値や内部状態情報を変更します。
478 
479       @param[in]    s           ソケット記述子を指定します。@ref Socket もしくは @ref Accept によって作成したソケット記述子を指定して下さい。
480       @param[in]    level       対象のプロトコル層 @ref SocketLevel を指定します。
481       @param[in]    optname     対象のオプション @ref SocketOptionType を指定します。
482       @param[out]   optval      オプション情報を保持しているバッファへのポインタを指定します。
483       @param[in,out] optlen     optname に応じた optval のバッファ長を指定します。
484 
485       @retval       0           処理に成功しました。
486       @retval       ENETRESET   ソケットライブラリが初期化されていません。
487       @retval       ENETDOWN    ネットワークが利用できません。
488       @retval       EBADF       不正なソケット記述子。
489       @retval       EINVAL      無効な処理。
490       @see          GetSockOpt
491     */
SetSockOpt(s32 s,s32 level,s32 optname,const void * optval,s32 optlen)492     inline s32 SetSockOpt(s32 s, s32 level, s32 optname, const void* optval, s32 optlen)
493     {
494         s32 rval = 0;
495         Result result = detail::SetSockOpt(&rval, s, level, optname, reinterpret_cast<const u8*>(optval), optlen);
496         NN_SOCKET_RETURN_IF_FAILED(result);
497         return rval;
498     }
499 
500     /*!
501       @brief        ソケットの動作設定フラグを制御します。
502 
503       @param[in]    s           ソケット記述子を指定します。@ref Socket もしくは @ref Accept によって作成したソケット記述子を指定して下さい。
504       @param[in]    cmd         動作設定フラグの制御方法を指定します。<br/>
505                                 F_GETFL 動作設定フラグを読み出します。 <br/>
506                                 F_SETFL 動作設定フラグを変更します。
507       @param[in]    val         制御方法により必要な追加の引数を指定します。
508                                 cmd が F_GETFL の場合は必要な追加引数はありませんので、
509                                 この引数は無視されます。
510                                 cmd が F_SETFL の場合は動作設定フラグを指定します。
511                                 0 もしくは以下の値の論理和です。<br/>
512                                 O_NONBLOCK
513                                     ソケットを非封鎖モードに設定します。
514                                     このフラグを設定しない場合にはソケットは封鎖モードになります。 なお、デフォルトではソケットは作成された時に封鎖モードに設定されます。
515 
516       @retval       0           処理に成功しました。
517       @retval       ENETRESET   ソケットライブラリが初期化されていません。
518       @retval       ENETDOWN    ネットワークが利用できません。
519       @retval       EBADF       不正なソケット記述子。
520 
521       @see          Accept, Connect, Recv, Send
522     */
Fcntl(s32 s,s32 cmd,s32 val)523     inline s32 Fcntl( s32 s, s32 cmd, s32 val )
524     {
525         s32 rval = 0;
526         Result result = detail::Fcntl(&rval, s, cmd, val);
527         NN_SOCKET_RETURN_IF_FAILED(result);
528         return rval;
529     }
530 
531     /*!
532       @brief        複数のソケット記述子を指定し、その中に読み出しや書き込みが可能な状態のソケットがあるかを一度に調べます。
533 
534                     ソケットの状態変化を監視し、通常は指定した条件のソケットが見つかるまでブロックします。
535                     指定した条件のソケットが見つからないままタイムアウト時間が過ぎた場合、 @ref Shutdown や @ref Close を使って
536                     ソケットの送受信処理を遮断する場合、ソケットになんらかの異常が検知された場合などにも
537                     ブロックが解除されます。
538 
539       @param[in]    fds         調査の対象となるソケット及び調査条件を指定し、調査結果を取得する @ref PollFd  の配列を指定します。
540       @param[in]    nfds        fds で指定する配列の要素数を指定します。
541       @param[in]    timeout     ソケットが見つからない状態が続いた時のタイムアウト時間をミリ秒単位で指定します。
542                                 0 以上の値、もしくは以下の定数を指定して下さい。
543                                 <br/>
544                                 - INFTIM タイムアウトしません。<br/>
545 
546       @retval       正の数      読み込みあるいは書き込み可能になったソケット記述子の数。
547       @retval       0           呼び出しがタイムアウトしました。
548       @retval       ENETRESET   ソケットライブラリが初期化されていません。
549       @retval       ENETDOWN    ネットワークが利用できません。
550       @retval       EBADF       不正なソケット記述子。
551       @retval       EINVAL      無効な処理。
552 
553       @see
554     */
Poll(PollFd fds[],u32 nfds,s32 timeout)555     inline s32 Poll( PollFd fds[], u32 nfds, s32 timeout )
556     {
557         s32 rval = 0;
558         Result result = detail::Poll(&rval, fds, nfds, timeout);
559         NN_SOCKET_RETURN_IF_FAILED(result);
560         return rval;
561     }
562 
563     /*!
564       @brief        指定したソケットに帯域外データマークにあるかどうかを調べます。
565 
566                     ソケットの読み出し可能なバッファの先頭が TCP の緊急データの最後の 1 バイトかどうかを調べるために使用することができます。
567 
568       @param[in]    s           ソケット記述子を指定します。@ref Socket もしくは @ref Accept によって作成したソケット記述子を指定して下さい。
569 
570       @retval       1           ソケットに帯域外のデータを受信したマークがされています。
571                                 当関数呼び出しに続けて MSG_OOB を指定した @ref Recv を呼び出すことで
572                                 帯域外のデータを読み出すことができます。
573                                 プロトコルが TCP の場合には、緊急データの最後の 1 バイトが
574                                 読み出し可能なバッファの先頭に存在することを示します。
575 
576       @retval       0           ソケットには帯域外のデータを受信したマークがされていません。
577                                 プロトコルが TCP の場合には、緊急データの存在は読み出し可能なバッファの先頭が
578                                 TCP の緊急データの最後の 1 バイトになるまで検出できない点に注意して下さい。
579 
580       @retval       ENETRESET   ソケットライブラリが初期化されていません。
581       @retval       ENETDOWN    ネットワークが利用できません。
582       @retval       EBADF       不正なソケット記述子。
583       @retval       EINVAL      無効な処理。
584 
585       @see          Recv, RecvFrom
586     */
SockAtMark(s32 s)587     inline s32 SockAtMark( s32 s )
588     {
589         s32 rval = 0;
590         Result result = detail::SockAtMark(&rval, s);
591         NN_SOCKET_RETURN_IF_FAILED(result);
592         return rval;
593     }
594 
595     /*!
596       @brief        自ホストのプライマリ IPv4 アドレスを取得します。
597 
598       @retval       0           通信が利用可能な状態ではありません。(自ホストに IPv4 アドレスが割り当てられていません。)
599       @retval       0 以外      ホストのプライマリ IPv4 アドレスをネットワークバイトオーダーの 32 ビット数値で返します。
600       @see
601     */
GetHostId(void)602     inline u32 GetHostId( void )
603     {
604         u32 rval = 0;
605         detail::GetHostId(&rval);
606         return rval;
607     }
608 
609     /*!
610       @brief        ソケットのローカルアドレスを取得します。
611 
612                     ローカルアドレスは通信元のアドレスとして使用されます。
613                     ローカルアドレスは @ref Bind, @ref Connect を呼び出すと確定します。
614                     ローカルアドレスが確定されていない場合、TCP ソケットではエラーになります。
615                     UDP ソケットでは、デフォルト値の 0.0.0.0 が取得できます。
616 
617       @param[in]    s           ソケット記述子を指定します。@ref Socket もしくは @ref Accept によって作成したソケット記述子を指定して下さい。
618       @param[in]    sockAddr    バインドされたアドレス情報を取得するソケットアドレス構造体へのポインタを指定します。
619 
620       @retval       0           処理に成功しました。
621       @retval       ENETRESET   ソケットライブラリが初期化されていません。
622       @retval       ENETDOWN    ネットワークが利用できません。
623       @retval       EBADF       不正なソケット記述子。
624       @retval       EINVAL      無効な処理。
625 
626       @see          GetPeerName
627     */
GetSockName(s32 s,SockAddrIn * sockAddr)628     inline s32 GetSockName( s32 s, SockAddrIn* sockAddr )
629     {
630         s32 rval = 0;
631         Result result = detail::GetSockName(&rval, s, reinterpret_cast<u8*>(sockAddr), sizeof(SockAddrIn));
632         NN_SOCKET_RETURN_IF_FAILED(result);
633         return rval;
634     }
635 
636     /*!
637       @brief        ソケットのリモートアドレスを取得します。
638 
639                     リモートアドレスはソケットの通信先となるアドレスです。
640 
641       @param[in]    s           ソケット記述子を指定します。@ref Socket もしくは @ref Accept によって作成したソケット記述子を指定して下さい。
642       @param[in]    sockAddr    通信先のアドレス情報を取得するソケットアドレス構造体へのポインタを指定します。
643 
644       @retval       0           処理に成功しました。
645       @retval       ENETRESET   ソケットライブラリが初期化されていません。
646       @retval       ENETDOWN    ネットワークが利用できません。
647       @retval       EBADF       不正なソケット記述子。
648       @retval       ENOTCONN    接続されていないか、前もって指定した相手がありませんでした。
649 
650       @see          GetSockName
651     */
GetPeerName(s32 s,SockAddrIn * sockAddr)652     inline s32 GetPeerName( s32 s, SockAddrIn* sockAddr )
653     {
654         s32 rval = 0;
655         Result result = detail::GetPeerName(&rval, s, reinterpret_cast<u8*>(sockAddr), sizeof(SockAddrIn));
656         NN_SOCKET_RETURN_IF_FAILED(result);
657         return rval;
658     }
659 
GetNetworkOpt(s32 level,s32 optname,void * optval,s32 * optlen)660     inline s32 GetNetworkOpt( s32 level, s32 optname, void* optval, s32* optlen )
661     {
662         s32 rval = 0;
663         Result result = detail::GetNetworkOpt(&rval, level, optname, reinterpret_cast<u8*>(optval), optlen);
664         NN_SOCKET_RETURN_IF_FAILED(result);
665         return rval;
666     }
667 
GetResolverInfo(nn::socket::DnsServerInfo * pDnsServerInfo)668     inline s32 GetResolverInfo( nn::socket::DnsServerInfo* pDnsServerInfo )
669     {
670         s32 rval = 0;
671         Result result = detail::GetResolverInfo(&rval, pDnsServerInfo);
672         NN_SOCKET_RETURN_IF_FAILED(result);
673         return rval;
674     }
675 
676     // DnsUserClient
677     /*!
678       @brief        ホストの名前を元に、ホストの情報を検索します。
679 
680                     DNS サーバに問い合わせを行う可能性があり、検索が完了するまでブロックします。
681                     GetHostByName 関数は再入可能でもスレッドセーフでもありません。
682                     複数のスレッドから呼び出す場合は @ref GetAddrInfo を使用して下さい。
683 
684       @param[in]    name        ホスト名文字列、もしくはドット十進記法で IPv4 ホストアドレスを表現した
685                                 文字列へのポインタを指定します。 文字列は NULL で終端されている必要があります。
686 
687       @return       処理に成功した場合は、ホストの情報を格納した @ref HostEnt 構造体へのポインタを返します。
688                     構造体の実体はライブラリの内部バッファです。
689 
690                     処理に失敗した場合には NULL を返します。
691 
692       @see          GetHostByAddr, GetAddrInfo
693     */
694     HostEnt* GetHostByName(const char8* name);
695 
696     /*!
697       @brief        ホストのアドレスを元に、ホストの情報を検索します。
698 
699                     DNS サーバに問い合わせを行う可能性があり、検索が完了するまでブロックします。
700 
701       @param[in]    addr        len バイトの数値形式のホストアドレスを保持しているバッファへのポインタを指定します。
702       @param[in]    len         数値形式のホストアドレスの長さ ( バイト単位 ) を指定します。
703                                 AF_INET  では IP_ALEN を指定して下さい。
704       @param[in]    type        ホストアドレスのアドレスファミリーを指定します。
705                                 @ref AF_INET
706 
707       @return       処理に成功した場合は、ホストの情報を格納した @ref HostEnt 構造体へのポインタを返します。
708                     構造体の実体はライブラリの内部バッファです。
709 
710                     処理に失敗した場合には NULL を返します。
711       @see          GetHostByName, GetNameInfo
712     */
713     HostEnt* GetHostByAddr(const void* addr, s32 len, s32 type);
714 
715     /*!
716       @brief        ホストのホスト名及びサービス名を元に、ホストの情報を検索します。
717 
718                     DNS サーバに問い合わせを行う可能性があり、検索が完了するまでブロックします。
719                     <br/>
720                     検索結果を保持するバッファは、@ref Initialize で指定したワーク領域から新たに確保されます。
721                     検索結果を解放するには @ref FreeAddrInfo を使用します。
722 
723       @param[in]    nodeName    ホスト名文字列、もしくはドット十進記法で IPv4 ホストアドレスを表現した文字列へのポインタを指定します。
724                                 文字列は NULL で終端されている必要があります。
725       @param[in]    servName    サービス名文字列、もしくはポート番号を数値記法で表現した文字列へのポインタを指定します。
726                                 文字列は NULL で終端されている必要があります。
727       @param[in]    hints       検索時の動作設定を行う @ref AddrInfo 構造体へのポインタを指定します。
728       @param[in]    res         検索結果を格納される @ref AddrInfo へのポインタが格納される変数へのポインタを指定します。
729 
730       @retval       0           処理に成功しました。
731       @retval       EAI_FAIL    以下のいずれかの理由で処理できません。<br/>
732                                 - hints に指定したソケットの種類がサポートされていません。<br/>
733                                 - hints に指定したソケットのプロトコルがサポートされていません。<br/>
734                                 - hints に @ref AI_NUMERICHOST が指定されているにも関わらず nodeName をドット十進記法の文字列として解釈できません。<br/>
735                                 - hints に @ref AI_NUMERICSERV が指定されているにも関わらず servName を数値記法の文字列として解釈できません。<br/>
736                                 - nodeName に指定したホスト名の長さが @ref MAXDNAME を越えています。<br/>
737                                 - servName に指定したサービス名が既知のサービス名として解釈できません。
738 
739       @retval       EAI_MEMORY  処理に必要なメモリを確保できません。
740       @retval       EAI_NONAME  検索対象のホストが見つかりません。
741 
742       @see          FreeAddrInfo
743     */
744     s32 GetAddrInfo(const char8* nodeName, const char8* servName, const AddrInfo* hints, AddrInfo** res);
745 
746     /*!
747       @brief        @ref GetAddrInfo を使用してホスト情報を検索した際に
748                     検索結果を保持するために確保されたバッファを解放します。
749 
750       @param[in]    head        @ref GetAddrInfo によって得たホスト情報のリスト @ref AddrInfo の先頭への
751                                 ポインタを指定します。
752                                 NULL ポインタを指定した場合は FreeAddrInfo 関数は何も処理を行いません。
753 
754       @see          GetAddrInfo
755     */
756     void FreeAddrInfo(AddrInfo* head);
757 
758     /*!
759       @brief        ホストのアドレス情報を元に、ホスト名及びサービス名を検索します。
760 
761                     DNS サーバに問い合わせを行う可能性があり、検索が完了するまでブロックします。
762 
763       @param[in]    sa          検索するホストのアドレス情報を保持しているソケットアドレス構造体へのポインタを指定します。
764       @param[in]    node        ホスト名を取得するバッファへのポインタを指定します。
765       @param[in]    nodeLen     ホスト名を取得するバッファの大きさをバイト単位で指定します。
766       @param[in]    service     サービス名を取得するバッファへのポインタを指定します。
767       @param[in]    serviceLen  サービス名を取得するバッファの大きさをバイト単位で指定します。
768       @param[in]    flags       検索時の動作設定フラグを指定します。0 もしくは以下の値の論理和です。
769                                 - NI_NOFQDN
770                                   - 完全修飾ドメイン名 ( FQDN ) のうちノード名の部分だけをホスト名として取得します。<br/>
771                                 - NI_NUMERICHOST
772                                   - ホスト名はソケットアドレス構造体に含まれているホストアドレスをドット十進記法による文字列に変換して取得します。<br/>
773                                 - NI_NAMEREQD
774                                   - 検索対象のホストが見つからない場合に、数値形式のホストアドレスを文字列に変換することで代替せずにエラー ( SO_EAI_NONAME ) として扱います。<br/>
775                                 - NI_NUMERICSERV
776                                   -サービス名はソケットアドレス構造体に含まれているサービス ( ポート番号 ) を数値記法による文字列に変換して取得します。
777 
778       @retval       0           処理に成功しました。
779       @retval       EAI_FAMILY  sockAddr に指定したソケットアドレスに含まれるプロトコルファミリーがサポートされていません。
780       @retval       EAI_NONAME  nodeLen 及び serviceLen  に指定したバッファの大きさが不正であるか、 flags に NI_NAMEREQD  を指定した呼び出しで検索対象のホストが見つかりません。
781 
782       @see          GetAddrInfo, GetHostByAddr
783     */
784     s32 GetNameInfo(const void* sa, char8* node, s32 nodeLen, char8* service, s32 serviceLen, s32 flags);
785 
786     /*!
787       @}
788 
789       @name         バイトオーダ・アドレス変換
790       @{
791      */
792 
793     // InetUtils
794     /*!
795       @brief        ドット十進記法の IPv4 ホストアドレスを数値形式に変換します。
796 
797                     @ref Initialize を呼び出していなくても使用することができます。
798 
799       @param[in]    cp          ドット十進記法で IPv4 アドレスを表現した文字列へのポインタを指定します。
800                                 文字列は NUL で終端されている必要があります。
801       @param[in]    inp         数値形式のアドレスを取得する @ref InAddr へのポインタを指定します。
802 
803       @retval       1           処理に成功しました。
804       @retval       0           cp に指定した文字列がドット十進記法で解釈できません。
805 
806       @see          InetNtoA, InetPtoN
807     */
808     s32 InetAtoN(const char* cp, InAddr* inp);
809 
810     /*!
811       @brief        数値形式の IPv4 ホストアドレスをドット十進記法の文字列に変換します。
812 
813                     @ref Initialize を呼び出していなくても使用することができます。
814                     <br/>
815                     InetNtoA は再入可能でもスレッドセーフでもありません。
816                     複数のスレッドから呼び出す場合は @ref InetNtoP を使用して下さい。
817 
818       @param[in]    in          数値形式の IPv4 ホストアドレスを保持する @ref InAddr を指定します
819 
820       @return       変換結果の文字列へのポインタを返します。
821                     文字列の実体は静的に割り当てられたライブラリ内部のバッファです。
822 
823       @see          InetAtoN, InetNtoP
824     */
825     char* InetNtoA(InAddr in);
826 
827     /*!
828       @brief        スタンダードテキスト表記のホストアドレスを数値形式に変換します。
829 
830                     @ref Initialize を呼び出していなくても使用することができます。
831 
832       @param[in]    af          変換するホストアドレスのアドレスファミリーを指定します。
833       @param[in]    src         スタンダードテキスト表記でホストアドレスを表現した文字列へのポインタを指定します。
834                                 文字列は NUL で終端されている必要があります。
835                                 - AF_INET
836 
837       @param[in]    dst         数値形式のアドレスを取得する構造体へのポインタを指定します。
838                                 @ref AF_INET では、@ref InAddr へのポインタを指定して下さい。
839 
840       @retval       1           処理に成功しました。
841       @retval       0           src に指定した文字列がスタンダードテキスト表記で解釈できません。
842       @retval       EAFNOSUPPORT    サポートされていないアドレスファミリーです。
843 
844       @see          InetNtoP
845     */
846     s32 InetPtoN(int af, const char* src, void* dst);
847 
848     /*!
849       @brief        数値形式のホストアドレスをスタンダードテキスト表記の文字列に変換します。
850 
851                     @ref Initialize を呼び出していなくても使用することができます。
852 
853       @param[in]    af          変換するホストアドレスのアドレスファミリーを指定します。
854                                 - AF_INET
855 
856       @param[in]    src         数値形式のホストアドレスを保持する構造体へのポインタを指定します。
857                                 @ref AF_INET では、@ref InAddr へのポインタを指定して下さい。
858 
859 
860       @param[in]    dst         スタンダードテキスト表記の文字列を取得するバッファへのポインタを指定します。
861                                 @ref AF_INET では、スタンダードテキスト表記はドット十進記法となります。
862 
863       @param[in]    len         dst に指定するバッファの大きさをバイト単位で指定します。
864                                 AF_INET では、ドット十進記法の IPv4 ホストアドレス文字列の最大長 ( INET_ADDRSTRLEN ) のバッファを用意して下さい。
865 
866       @return       処理に成功した場合は、変換結果の文字列へのポインタを返します。
867                     文字列の実体は dst に指定したバッファです。
868                     処理に失敗した場合には NULL を返します。
869 
870       @see
871     */
872     const char* InetNtoP(int af, const void* src, char* dst, unsigned len);
873 
874     // byteorder
875     /*!
876       @brief        32 ビットのホストバイトオーダーの値をネットワークバイトオーダーの値に変換します。
877 
878 
879       @param[in]    v           32 ビットのホストバイトオーダーの値を指定します。
880 
881       @return       32 ビットのネットワークバイトオーダーの値を返します。
882 
883       @see          NtoHl, HtoNs
884     */
HtoNl(bit32 v)885     inline bit32 HtoNl(bit32 v)
886     {
887         return NN_SOCKET_HtoNl(v);
888     }
889 
890     /*!
891       @brief        32 ビットのネットワークバイトオーダーの値をホストバイトオーダーの値に変換します。
892 
893       @param[in]    v           32 ビットのネットワークバイトオーダーの値を指定します。
894 
895       @return       32 ビットのホストバイトオーダーの値を返します。
896 
897       @see          HtoNl, NtoHs
898     */
NtoHl(bit32 v)899     inline bit32 NtoHl(bit32 v)
900     {
901         return NN_SOCKET_NtoHl(v);
902     }
903     /*!
904       @brief        16 ビットのホストバイトオーダーの値をネットワークバイトオーダーの値に変換します。
905 
906       @param[in]    v           16 ビットのホストバイトオーダーの値を指定します。
907 
908       @return       16 ビットのネットワークバイトオーダーの値を返します。
909 
910       @see          NtoHs, HtoNl
911     */
HtoNs(bit16 v)912     inline bit16 HtoNs(bit16 v)
913     {
914         return NN_SOCKET_HtoNs(v);
915     }
916     /*!
917       @brief        16 ビットのネットワークバイトオーダーの値をホストバイトオーダーの値に変換します。
918 
919       @param[in]    v           16 ビットのネットワークバイトオーダーの値を指定します。
920 
921       @retval       16 ビットのホストバイトオーダーの値を返します。
922 
923       @see          HtoNs, NtoHl
924     */
NtoHs(bit16 v)925     inline bit16 NtoHs(bit16 v)
926     {
927         return NN_SOCKET_NtoHs(v);
928     }
929 }
930 }
931 
932 #endif  // ifndef NN_SOCKET_SOCKET_BERKLEY_H_
933