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