]> git.proxmox.com Git - mirror_edk2.git/blame - StdLib/BsdSocketLib/socket.c
Fix send to properly wait while long transmits are in progress
[mirror_edk2.git] / StdLib / BsdSocketLib / socket.c
CommitLineData
d7ce7006 1/** @file\r
2 Implement the socket API.\r
3\r
4 Copyright (c) 2011, Intel Corporation\r
5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <SocketInternals.h>\r
16\r
17\r
18const struct fileops SocketOperations = {\r
19 BslSocketClose, // close\r
20 BslSocketRead, // read\r
21 BslSocketWrite, // write\r
22\r
23 //\r
24 // Not supported\r
25 //\r
26 fnullop_fcntl, // fcntl\r
27 BslSocketPoll, // poll\r
28 fnullop_flush, // flush\r
29\r
30 fbadop_stat, // stat\r
31 fbadop_ioctl, // ioctl\r
32 fbadop_delete, // delete\r
33 fbadop_rmdir, // rmdir\r
34 fbadop_mkdir, // mkdir\r
35 fbadop_rename, // rename\r
36\r
37 NULL // lseek\r
38};\r
39\r
40\r
41/**\r
42 Translate from the socket file descriptor to the socket protocol.\r
43\r
44 @param [in] s Socket file descriptor returned from ::socket.\r
45\r
46 @param [in] ppDescriptor Address to receive the descriptor structure\r
47 address for the file\r
48 @param [in] pErrno Address of the errno variable\r
49\r
50 @returns A pointer to the socket protocol structure or NULL if\r
51 an invalid file descriptor was passed in.\r
52\r
53 **/\r
54EFI_SOCKET_PROTOCOL *\r
55BslFdToSocketProtocol (\r
56 int s,\r
57 struct __filedes ** ppDescriptor,\r
58 int * pErrno\r
59 )\r
60{\r
61 struct __filedes * pDescriptor;\r
62 EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
63\r
64 //\r
65 // Assume failure\r
66 //\r
67 pSocketProtocol = NULL;\r
68\r
69 //\r
70 // Validate the file descriptor\r
71 //\r
72 if ( !ValidateFD ( s, TRUE )) {\r
73 //\r
74 // Bad file descriptor\r
75 //\r
76 *pErrno = EBADF;\r
77 }\r
78 else {\r
79 //\r
80 // Get the descriptor for the file\r
81 //\r
82 pDescriptor = &gMD->fdarray [ s ];\r
83\r
84 //\r
85 // Validate that the descriptor is associated with sockets\r
86 //\r
87 pSocketProtocol = BslValidateSocketFd ( pDescriptor, pErrno );\r
88 if (( NULL != ppDescriptor ) && ( NULL != pSocketProtocol )) {\r
89 *ppDescriptor = pDescriptor;\r
90 }\r
91 }\r
92\r
93 //\r
94 // Return the socket protocol\r
95 //\r
96 return pSocketProtocol;\r
97}\r
98\r
99\r
100/**\r
101 Build a file descriptor for a socket.\r
102\r
103 @param [in] pSocketProtocol Socket protocol structure address\r
104 \r
105 @param [in] pErrno Address of the errno variable\r
106\r
107 @returns The file descriptor for the socket or -1 if an error occurs.\r
108\r
109 **/\r
110int\r
111BslSocketProtocolToFd (\r
112 IN EFI_SOCKET_PROTOCOL * pSocketProtocol,\r
113 IN int * pErrno\r
114 )\r
115{\r
116 int FileDescriptor;\r
117 struct __filedes * pDescriptor;\r
118\r
119 //\r
120 // Assume failure\r
121 //\r
122 FileDescriptor = -1;\r
123\r
124 //\r
125 // Locate a file descriptor\r
126 //\r
127 FileDescriptor = FindFreeFD ( VALID_CLOSED );\r
128 if( FileDescriptor < 0 ) {\r
129 //\r
130 // All available FDs are in use\r
131 //\r
132 errno = EMFILE;\r
133 }\r
134 else {\r
135 //\r
136 // Initialize the file descriptor\r
137 //\r
138 pDescriptor = &gMD->fdarray [ FileDescriptor ];\r
139 pDescriptor->f_offset = 0;\r
140 pDescriptor->f_flag = 0;\r
141 pDescriptor->f_iflags = DTYPE_SOCKET;\r
142 pDescriptor->MyFD = (UINT16)FileDescriptor;\r
143 pDescriptor->Oflags = 0;\r
144 pDescriptor->Omode = S_ACC_READ | S_ACC_WRITE;\r
145 pDescriptor->RefCount = 1;\r
146 FILE_SET_MATURE ( pDescriptor );\r
147\r
148 //\r
149 // Socket specific file descriptor initialization\r
150 //\r
151 pDescriptor->devdata = pSocketProtocol;\r
152 pDescriptor->f_ops = &SocketOperations;\r
153 }\r
154\r
155 //\r
156 // Return the socket's file descriptor\r
157 //\r
158 return FileDescriptor;\r
159}\r
160\r
161\r
162/**\r
163 Creates an endpoint for network communication.\r
164\r
165 The ::Socket routine initializes the communication endpoint by providing\r
166 the support for the socket library function ::socket. The\r
167 <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/socket.html">POSIX</a>\r
168 documentation for the socket routine is available online for reference.\r
169\r
170 @param [in] domain Select the family of protocols for the client or server\r
171 application.\r
172\r
173 @param [in] type Specifies how to make the network connection. The following values\r
174 are supported:\r
175 <ul>\r
176 <li>\r
177 SOCK_STREAM - Connect to TCP, provides a byte stream\r
178 that is manipluated by read, recv, send and write.\r
179 </li>\r
180 <li>\r
181 SOCK_SEQPACKET - Connect to TCP, provides sequenced packet stream\r
182 that is manipulated by read, recv, send and write.\r
183 </li>\r
184 <li>\r
185 SOCK_DGRAM - Connect to UDP, provides a datagram service that is\r
186 manipulated by recvfrom and sendto.\r
187 </li>\r
188 </ul>\r
189\r
190 @param [in] protocol Specifies the lower layer protocol to use. The following\r
191 values are supported:\r
192 <ul>\r
193 <li>IPPROTO_TCP</li> - This value must be combined with SOCK_STREAM.</li>\r
194 <li>IPPROTO_UDP</li> - This value must be combined with SOCK_DGRAM.</li>\r
195 </ul>\r
196\r
197 @returns This routine returns a file descriptor for the socket.\r
198\r
199 **/\r
200INT32\r
201socket (\r
202 IN INT32 domain,\r
203 IN INT32 type,\r
204 IN INT32 protocol\r
205 )\r
206{\r
207 INT32 FileDescriptor;\r
208 EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
209 EFI_STATUS Status;\r
210\r
211 //\r
212 // Assume failure\r
213 //\r
214 FileDescriptor = -1;\r
215\r
216 //\r
217 // Locate the socket protocol\r
218 //\r
219 errno = EslServiceGetProtocol ( &pSocketProtocol );\r
220 if ( 0 == errno ) {\r
221 //\r
222 // Initialize the socket\r
223 //\r
224 Status = pSocketProtocol->pfnSocket ( pSocketProtocol,\r
225 domain,\r
226 type,\r
227 protocol,\r
228 &errno );\r
229 if ( !EFI_ERROR ( Status ))\r
230 {\r
231 //\r
232 // Build the file descriptor for the socket\r
233 //\r
234 FileDescriptor = BslSocketProtocolToFd ( pSocketProtocol,\r
235 &errno );\r
236 }\r
237 }\r
238\r
239 //\r
240 // Return the socket's file descriptor\r
241 //\r
242 return FileDescriptor;\r
243}\r
244\r
245\r
246/**\r
247 Validate the socket's file descriptor\r
248\r
249 @param [in] pDescriptor Descriptor for the file\r
250\r
251 @param [in] pErrno Address of the errno variable\r
252\r
253 @returns A pointer to the socket protocol structure or NULL if\r
254 an invalid file descriptor was passed in.\r
255\r
256 **/\r
257EFI_SOCKET_PROTOCOL *\r
258BslValidateSocketFd (\r
259 struct __filedes * pDescriptor,\r
260 int * pErrno\r
261 )\r
262{\r
263 EFI_SOCKET_PROTOCOL * pSocketProtocol;\r
264\r
265 //\r
266 // Assume failure\r
267 //\r
268 *pErrno = ENOTSOCK;\r
269 pSocketProtocol = NULL;\r
270\r
271 //\r
272 // Validate that the descriptor is associated with sockets\r
273 //\r
274 if ( DTYPE_SOCKET == ( pDescriptor->f_iflags & DTYPE_MASK )) {\r
275 //\r
276 // Locate the socket protocol\r
277 //\r
278 pSocketProtocol = pDescriptor->devdata;\r
279 *pErrno = 0;\r
280 }\r
281\r
282 //\r
283 // Return the socket protocol\r
284 //\r
285 return pSocketProtocol;\r
286}\r