Home | History | Annotate | Download | only in BsdSocketLib
      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