Fix send to properly wait while long transmits are in progress
[mirror_edk2.git] / StdLib / BsdSocketLib / sendto.c
1 /** @file
2 Implement the sendto 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 Send data using a network connection.
20
21 The ::send routine queues data to the network for transmission.
22 The
23 <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/send.html">POSIX</a>
24 documentation is available online.
25
26 @param [in] s Socket file descriptor returned from ::socket.
27
28 @param [in] buffer Address of a buffer containing the data to send.
29
30 @param [in] length Length of the buffer in bytes.
31
32 @param [in] flags Message control flags
33
34 @param [in] to Remote system address
35
36 @param [in] tolen Length of remote system address structure
37
38 @returns ::send returns the number of data bytes that were
39 sent and -1 when an error occurs. In the case of
40 an error, errno contains more details.
41
42 **/
43 ssize_t
44 sendto (
45 int s,
46 const void * buffer,
47 size_t length,
48 int flags,
49 const struct sockaddr * to,
50 socklen_t tolen
51 )
52 {
53 ssize_t LengthInBytes;
54 CONST UINT8 * pData;
55 struct __filedes * pDescriptor;
56 EFI_SOCKET_PROTOCOL * pSocketProtocol;
57 EFI_STATUS Status;
58
59 //
60 // Assume failure
61 //
62 LengthInBytes = -1;
63
64 //
65 // Locate the context for this socket
66 //
67 pSocketProtocol = BslFdToSocketProtocol ( s,
68 &pDescriptor,
69 &errno );
70 if ( NULL != pSocketProtocol ) {
71 //
72 // Send the data using the socket
73 //
74 pData = buffer;
75 do {
76 errno = 0;
77 Status = pSocketProtocol->pfnSend ( pSocketProtocol,
78 flags,
79 length,
80 pData,
81 (size_t *)&LengthInBytes,
82 to,
83 tolen,
84 &errno );
85 if ( EFI_ERROR ( Status ) && ( EFI_NOT_READY != Status )) {
86 LengthInBytes = -1;
87 break;
88 }
89
90 //
91 // Account for the data sent
92 //
93 pData += LengthInBytes;
94 length -= LengthInBytes;
95 // TODO: Add non-blocking check
96 } while (( 0 != length ) && ( EFI_NOT_READY == Status ));
97 }
98
99 //
100 // Return the number of data bytes sent, -1 for errors
101 //
102 return (INT32)LengthInBytes;
103 }