1 | /** @file
|
---|
2 | Implement the accept API.
|
---|
3 |
|
---|
4 | Copyright (c) 2011, Intel Corporation
|
---|
5 | All rights reserved. This program and the accompanying materials
|
---|
6 | are licensed and made available under the terms and conditions of the BSD License
|
---|
7 | which accompanies this distribution. The full text of the license may be found at
|
---|
8 | http://opensource.org/licenses/bsd-license.php
|
---|
9 |
|
---|
10 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
---|
11 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
---|
12 |
|
---|
13 | **/
|
---|
14 |
|
---|
15 | #include "SocketInternals.h"
|
---|
16 |
|
---|
17 |
|
---|
18 | /**
|
---|
19 | Worker routine for ::accept and ::AcceptNB
|
---|
20 |
|
---|
21 | @param [in] s Socket file descriptor returned from ::socket.
|
---|
22 |
|
---|
23 | @param [in] bBlockingAllowed TRUE if this is a blocking call
|
---|
24 | @param [in] address Address of a buffer to receive the remote network address.
|
---|
25 |
|
---|
26 | @param [in, out] address_len Address of a buffer containing the Length in bytes
|
---|
27 | of the remote network address buffer. Upon return,
|
---|
28 | contains the length of the remote network address.
|
---|
29 |
|
---|
30 | @return AcceptWork returns zero if successful and -1 when an error occurs.
|
---|
31 | In the case of an error, ::errno contains more details.
|
---|
32 |
|
---|
33 | **/
|
---|
34 | int
|
---|
35 | AcceptWork (
|
---|
36 | int s,
|
---|
37 | BOOLEAN bBlockingAllowed,
|
---|
38 | struct sockaddr * address,
|
---|
39 | socklen_t * address_len
|
---|
40 | )
|
---|
41 | {
|
---|
42 | BOOLEAN bBlocking;
|
---|
43 | INT32 NewSocketFd;
|
---|
44 | struct __filedes * pDescriptor;
|
---|
45 | EFI_SOCKET_PROTOCOL * pNewSocket;
|
---|
46 | EFI_SOCKET_PROTOCOL * pSocketProtocol;
|
---|
47 | EFI_STATUS Status;
|
---|
48 |
|
---|
49 | //
|
---|
50 | // Assume failure
|
---|
51 | //
|
---|
52 | NewSocketFd = -1;
|
---|
53 |
|
---|
54 | //
|
---|
55 | // Locate the context for this socket
|
---|
56 | //
|
---|
57 | pSocketProtocol = BslFdToSocketProtocol ( s,
|
---|
58 | &pDescriptor,
|
---|
59 | &errno );
|
---|
60 | if ( NULL != pSocketProtocol ) {
|
---|
61 | //
|
---|
62 | // Determine if the operation is blocking
|
---|
63 | //
|
---|
64 | bBlocking = (BOOLEAN)( 0 == ( pDescriptor->Oflags & O_NONBLOCK ));
|
---|
65 | bBlocking &= bBlockingAllowed;
|
---|
66 |
|
---|
67 | //
|
---|
68 | // Attempt to accept a new network connection
|
---|
69 | //
|
---|
70 | do {
|
---|
71 | Status = pSocketProtocol->pfnAccept ( pSocketProtocol,
|
---|
72 | address,
|
---|
73 | address_len,
|
---|
74 | &pNewSocket,
|
---|
75 | &errno );
|
---|
76 | } while ( bBlocking && ( EFI_NOT_READY == Status ));
|
---|
77 |
|
---|
78 | //
|
---|
79 | // Convert the protocol to a socket
|
---|
80 | //
|
---|
81 | if ( !EFI_ERROR ( Status )) {
|
---|
82 | NewSocketFd = BslSocketProtocolToFd ( pNewSocket, &errno );
|
---|
83 | if ( -1 == NewSocketFd ) {
|
---|
84 | //
|
---|
85 | // Close the socket
|
---|
86 | //
|
---|
87 | BslSocketCloseWork ( pNewSocket, NULL );
|
---|
88 | }
|
---|
89 | }
|
---|
90 | }
|
---|
91 |
|
---|
92 | //
|
---|
93 | // Return the new socket file descriptor
|
---|
94 | //
|
---|
95 | return NewSocketFd;
|
---|
96 | }
|
---|
97 |
|
---|
98 |
|
---|
99 | /**
|
---|
100 | Accept a network connection.
|
---|
101 |
|
---|
102 | The accept routine waits for a network connection to the socket.
|
---|
103 | It returns the remote network address to the caller if requested.
|
---|
104 |
|
---|
105 | The
|
---|
106 | <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/accept.html">POSIX</a>
|
---|
107 | documentation is available online.
|
---|
108 |
|
---|
109 | @param [in] s Socket file descriptor returned from ::socket.
|
---|
110 |
|
---|
111 | @param [in] address Address of a buffer to receive the remote network address.
|
---|
112 |
|
---|
113 | @param [in, out] address_len Address of a buffer containing the Length in bytes
|
---|
114 | of the remote network address buffer. Upon return,
|
---|
115 | contains the length of the remote network address.
|
---|
116 |
|
---|
117 | @return The accept routine returns zero if successful and -1 when an error occurs.
|
---|
118 | In the case of an error, ::errno contains more details.
|
---|
119 |
|
---|
120 | **/
|
---|
121 | int
|
---|
122 | accept (
|
---|
123 | int s,
|
---|
124 | struct sockaddr * address,
|
---|
125 | socklen_t * address_len
|
---|
126 | )
|
---|
127 | {
|
---|
128 | //
|
---|
129 | // Wait for the accept call to complete
|
---|
130 | //
|
---|
131 | return AcceptWork ( s, TRUE, address, address_len );
|
---|
132 | }
|
---|
133 |
|
---|
134 |
|
---|
135 | /**
|
---|
136 | Non blocking version of ::accept.
|
---|
137 |
|
---|
138 | @param [in] s Socket file descriptor returned from ::socket.
|
---|
139 |
|
---|
140 | @param [in] address Address of a buffer to receive the remote network address.
|
---|
141 |
|
---|
142 | @param [in, out] address_len Address of a buffer containing the Length in bytes
|
---|
143 | of the remote network address buffer. Upon return,
|
---|
144 | contains the length of the remote network address.
|
---|
145 |
|
---|
146 | @return This routine returns zero if successful and -1 when an error occurs.
|
---|
147 | In the case of an error, ::errno contains more details.
|
---|
148 |
|
---|
149 | **/
|
---|
150 | int
|
---|
151 | AcceptNB (
|
---|
152 | int s,
|
---|
153 | struct sockaddr * address,
|
---|
154 | socklen_t * address_len
|
---|
155 | )
|
---|
156 | {
|
---|
157 | //
|
---|
158 | // Attempt to accept a network connection
|
---|
159 | //
|
---|
160 | return AcceptWork ( s, FALSE, address, address_len );
|
---|
161 | }
|
---|