LCOV - code coverage report
Current view: directory - src/shared/imc/linux - nacl_imc.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 72 55 76.4 %
Date: 2014-10-23 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2011 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : 
       8                 : /* NaCl inter-module communication primitives. */
       9                 : 
      10                 : #include "native_client/src/shared/imc/nacl_imc_c.h"
      11                 : #include <assert.h>
      12                 : #include <ctype.h>
      13                 : #include <errno.h>
      14                 : #include <fcntl.h>
      15                 : #include <stdio.h>
      16                 : #include <string.h>
      17                 : #include <unistd.h>
      18                 : #include <sys/mman.h>
      19                 : #include <sys/socket.h>
      20                 : #include <sys/types.h>
      21                 : #include <sys/un.h>
      22                 : 
      23                 : #include "native_client/src/shared/platform/nacl_log.h"
      24                 : 
      25                 : /*
      26                 :  * Gets an array of file descriptors stored in msg.
      27                 :  * The fdv parameter must be an int array of kHandleCountMax elements.
      28                 :  * GetRights() returns the number of file descriptors copied into fdv.
      29                 :  */
      30           19104 : static size_t GetRights(struct msghdr* msg, int* fdv) {
      31                 :   struct cmsghdr* cmsg;
      32           19104 :   size_t count = 0;
      33           19372 :   for (cmsg = CMSG_FIRSTHDR(msg);
      34                 :        cmsg != 0;
      35                 :        cmsg = CMSG_NXTHDR(msg, cmsg)) {
      36             268 :     if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
      37             846 :       while (CMSG_LEN((1 + count) * sizeof(int)) <= cmsg->cmsg_len) {
      38             310 :         *fdv++ = ((int *) CMSG_DATA(cmsg))[count];
      39             310 :         ++count;
      40                 :       }
      41                 :     }
      42                 :   }
      43           19104 :   return count;
      44                 : }
      45                 : 
      46                 : /*
      47                 :  * We keep these no-op implementations of SocketAddress-based
      48                 :  * functions so that sigpipe_test continues to link.
      49                 :  */
      50               0 : NaClHandle NaClBoundSocket(const NaClSocketAddress* address) {
      51                 :   UNREFERENCED_PARAMETER(address);
      52               0 :   NaClLog(LOG_FATAL, "BoundSocket(): Not used on Linux\n");
      53               0 :   return -1;
      54                 : }
      55                 : 
      56               0 : int NaClSendDatagramTo(const NaClMessageHeader* message, int flags,
      57                 :                        const NaClSocketAddress* name) {
      58                 :   UNREFERENCED_PARAMETER(message);
      59                 :   UNREFERENCED_PARAMETER(flags);
      60                 :   UNREFERENCED_PARAMETER(name);
      61               0 :   NaClLog(LOG_FATAL, "SendDatagramTo(): Not used on Linux\n");
      62               0 :   return -1;
      63                 : }
      64                 : 
      65            1118 : int NaClSocketPair(NaClHandle pair[2]) {
      66                 :   /*
      67                 :    * The read operation for a SOCK_SEQPACKET socket returns zero when the
      68                 :    * remote peer closed the connection unlike a SOCK_DGRAM socket. Note
      69                 :    * SOCK_SEQPACKET was introduced with Linux 2.6.4.
      70                 :    */
      71            1118 :   int rv = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair);
      72            1118 :   if (rv != 0) {
      73               0 :     NaClLog(LOG_ERROR, "SocketPair: socketpair failed, errno %d\n", errno);
      74                 :   }
      75            1118 :   return rv;
      76                 : }
      77                 : 
      78            1233 : int NaClClose(NaClHandle handle) {
      79            1233 :   return close(handle);
      80                 : }
      81                 : 
      82           19076 : int NaClSendDatagram(NaClHandle handle, const NaClMessageHeader* message,
      83                 :                      int flags) {
      84                 :   struct msghdr msg;
      85                 :   unsigned char buf[CMSG_SPACE(NACL_HANDLE_COUNT_MAX * sizeof(int))];
      86                 : 
      87           19076 :   if (NACL_HANDLE_COUNT_MAX < message->handle_count) {
      88               0 :     errno = EMSGSIZE;
      89               0 :     return -1;
      90                 :   }
      91                 :   /*
      92                 :    * The following assert was an earlier attempt to remember/check the
      93                 :    * assumption that our struct IOVec -- which we must define to be
      94                 :    * cross platform -- is compatible with struct iovec on *x systems.
      95                 :    * The length field of IOVec was switched to be uint32_t at one point
      96                 :    * to use concrete types, which introduced a problem on 64-bit systems.
      97                 :    *
      98                 :    * Clearly, the assert does not check a strong-enough condition,
      99                 :    * since structure padding would make the two sizes the same.
     100                 :    *
     101                 :   assert(sizeof(struct iovec) == sizeof(NaClIOVec));
     102                 :    *
     103                 :    * Don't do this again!
     104                 :    */
     105                 : 
     106           19076 :   if (!NaClMessageSizeIsValid(message)) {
     107               0 :     errno = EMSGSIZE;
     108               0 :     return -1;
     109                 :   }
     110                 : 
     111           19076 :   msg.msg_iov = (struct iovec *) message->iov;
     112           19076 :   msg.msg_iovlen = message->iov_length;
     113           19076 :   msg.msg_name = 0;
     114           19076 :   msg.msg_namelen = 0;
     115                 : 
     116           19076 :   if (0 < message->handle_count && message->handles != NULL) {
     117                 :     struct cmsghdr* cmsg;
     118             251 :     int size = message->handle_count * sizeof(int);
     119             251 :     msg.msg_control = buf;
     120             251 :     msg.msg_controllen = CMSG_SPACE(size);
     121             251 :     cmsg = CMSG_FIRSTHDR(&msg);
     122             251 :     cmsg->cmsg_level = SOL_SOCKET;
     123             251 :     cmsg->cmsg_type = SCM_RIGHTS;
     124             251 :     cmsg->cmsg_len = CMSG_LEN(size);
     125             251 :     memcpy(CMSG_DATA(cmsg), message->handles, size);
     126             251 :     msg.msg_controllen = cmsg->cmsg_len;
     127                 :   } else {
     128           18825 :     msg.msg_control = 0;
     129           18825 :     msg.msg_controllen = 0;
     130                 :   }
     131           19076 :   msg.msg_flags = 0;
     132                 :   return sendmsg(handle, &msg,
     133           19076 :                  MSG_NOSIGNAL | ((flags & NACL_DONT_WAIT) ? MSG_DONTWAIT : 0));
     134                 : }
     135                 : 
     136           19118 : int NaClReceiveDatagram(NaClHandle handle, NaClMessageHeader* message,
     137                 :                         int flags) {
     138                 :   struct msghdr msg;
     139                 :   unsigned char buf[CMSG_SPACE(NACL_HANDLE_COUNT_MAX * sizeof(int))];
     140                 :   int count;
     141                 : 
     142           19118 :   if (NACL_HANDLE_COUNT_MAX < message->handle_count) {
     143               0 :     errno = EMSGSIZE;
     144               0 :     return -1;
     145                 :   }
     146           19118 :   msg.msg_name = 0;
     147           19118 :   msg.msg_namelen = 0;
     148                 : 
     149                 :   /*
     150                 :    * Make sure we cannot receive more than 2**32-1 bytes.
     151                 :    */
     152           19118 :   if (!NaClMessageSizeIsValid(message)) {
     153               0 :     errno = EMSGSIZE;
     154               0 :     return -1;
     155                 :   }
     156                 : 
     157           19118 :   msg.msg_iov = (struct iovec *) message->iov;
     158           19118 :   msg.msg_iovlen = message->iov_length;
     159           19118 :   if (0 < message->handle_count && message->handles != NULL) {
     160           19107 :     msg.msg_control = buf;
     161           19107 :     msg.msg_controllen = CMSG_SPACE(message->handle_count * sizeof(int));
     162                 :   } else {
     163              11 :     msg.msg_control = 0;
     164              11 :     msg.msg_controllen = 0;
     165                 :   }
     166           19118 :   msg.msg_flags = 0;
     167           19118 :   message->flags = 0;
     168           19118 :   count = recvmsg(handle, &msg, (flags & NACL_DONT_WAIT) ? MSG_DONTWAIT : 0);
     169           19104 :   if (0 <= count) {
     170           19104 :     message->handle_count = GetRights(&msg, message->handles);
     171           19104 :     if (msg.msg_flags & MSG_TRUNC) {
     172               0 :       message->flags |= NACL_MESSAGE_TRUNCATED;
     173                 :     }
     174           19104 :     if (msg.msg_flags & MSG_CTRUNC) {
     175               0 :       message->flags |= NACL_HANDLES_TRUNCATED;
     176                 :     }
     177                 :   }
     178           19104 :   return count;
     179                 : }

Generated by: LCOV version 1.7