LCOV - code coverage report
Current view: directory - src/trusted/desc - nacl_desc_wrapper.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 344 119 34.6 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : // Copyright (c) 2012 The Native Client Authors. All rights reserved.
       2                 : // Use of this source code is governed by a BSD-style license that can be
       3                 : // found in the LICENSE file.
       4                 : 
       5                 : #include <limits>
       6                 : #include <new>
       7                 : #include "native_client/src/include/portability.h"
       8                 : #include "native_client/src/include/portability_string.h"
       9                 : #include "native_client/src/public/imc_types.h"
      10                 : #include "native_client/src/shared/imc/nacl_imc_c.h"
      11                 : #include "native_client/src/shared/platform/nacl_check.h"
      12                 : #include "native_client/src/shared/platform/nacl_log.h"
      13                 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
      14                 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
      15                 : #include "native_client/src/trusted/desc/nacl_desc_conn_cap.h"
      16                 : #include "native_client/src/trusted/desc/nacl_desc_imc.h"
      17                 : #include "native_client/src/trusted/desc/nacl_desc_imc_shm.h"
      18                 : #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
      19                 : #include "native_client/src/trusted/desc/nacl_desc_io.h"
      20                 : #include "native_client/src/trusted/desc/nacl_desc_quota.h"
      21                 : #include "native_client/src/trusted/desc/nacl_desc_rng.h"
      22                 : #include "native_client/src/trusted/desc/nacl_desc_sync_socket.h"
      23                 : #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
      24                 : #include "native_client/src/trusted/desc/nrd_xfer.h"
      25                 : #include "native_client/src/trusted/nacl_base/nacl_refcount.h"
      26                 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
      27                 : #include "native_client/src/trusted/service_runtime/nacl_config.h"
      28                 : 
      29                 : // TODO(polina): follow the style guide and replace "nhdp" and "ndiodp" with
      30                 : //               "host_desc" and "io_desc"
      31                 : 
      32                 : namespace {
      33                 : 
      34              14 : struct NaClDesc* OpenHostFileCommon(const char* fname, int flags, int mode) {
      35              14 :   struct NaClHostDesc* nhdp =
      36              14 :     reinterpret_cast<struct NaClHostDesc*>(calloc(1, sizeof(*nhdp)));
      37              14 :   if (NULL == nhdp) {
      38               0 :     return NULL;
      39                 :   }
      40              14 :   if (0 != NaClHostDescOpen(nhdp, fname, flags, mode)) {
      41               0 :     free(nhdp);
      42               0 :     return NULL;
      43                 :   }
      44              14 :   struct NaClDescIoDesc* ndiodp = NaClDescIoDescMake(nhdp);
      45              14 :   if (NULL == ndiodp) {
      46               0 :     if (0 != NaClHostDescClose(nhdp)) {
      47               0 :       NaClLog(LOG_FATAL, "OpenHostFileCommon: NaClHostDescClose failed\n");
      48               0 :     }
      49               0 :     free(nhdp);
      50               0 :     return NULL;
      51                 :   }
      52              14 :   return reinterpret_cast<struct NaClDesc*>(ndiodp);
      53              14 : }
      54                 : 
      55               0 : struct NaClDesc* MakeQuotaCommon(const uint8_t* file_id,
      56               0 :                                  struct NaClDesc* desc) {
      57               0 :   NaClDescQuota* ndqp =
      58               0 :       reinterpret_cast<NaClDescQuota*>(calloc(1, sizeof *ndqp));
      59               0 :   if ((NULL == ndqp) || !NaClDescQuotaCtor(ndqp, desc, file_id, NULL)) {
      60               0 :     free(ndqp);
      61               0 :     return NULL;
      62                 :   }
      63               0 :   return reinterpret_cast<struct NaClDesc*>(ndqp);
      64               0 : }
      65                 : 
      66                 : }  // namespace
      67                 : 
      68                 : namespace nacl {
      69                 : 
      70                 : // Descriptor creation and manipulation sometimes requires additional
      71                 : // state.  Therefore, we create an object that encapsulates that
      72                 : // state.
      73                 : class DescWrapperCommon {
      74                 :   friend class DescWrapperFactory;
      75                 : 
      76                 :  public:
      77                 :   typedef uint32_t RefCountType;
      78                 : 
      79                 :   // Inform clients that the object was successfully initialized.
      80              55 :   bool is_initialized() const { return is_initialized_; }
      81                 : 
      82                 :   // Manipulate reference count
      83                 :   DescWrapperCommon* Ref() {
      84                 :     // TODO(sehr): replace with a reference count class when we have one.
      85             124 :     NaClXMutexLock(&ref_count_mu_);
      86             124 :     if (std::numeric_limits<RefCountType>::max() == ref_count_) {
      87               0 :       NaClLog(LOG_FATAL, "DescWrapperCommon ref count overflow\n");
      88               0 :     }
      89             124 :     ++ref_count_;
      90             124 :     NaClXMutexUnlock(&ref_count_mu_);
      91             124 :     return this;
      92                 :   }
      93                 : 
      94                 :   void Unref() {
      95             134 :     NaClXMutexLock(&ref_count_mu_);
      96             134 :     if (0 == ref_count_) {
      97               0 :       NaClLog(LOG_FATAL, "DescWrapperCommon ref count already zero\n");
      98               0 :     }
      99             134 :     --ref_count_;
     100             134 :     bool destroy = (0 == ref_count_);
     101             134 :     NaClXMutexUnlock(&ref_count_mu_);
     102             134 :     if (destroy) {
     103             102 :       delete this;
     104              34 :     }
     105             134 :   }
     106                 : 
     107                 :  private:
     108              52 :   DescWrapperCommon() : is_initialized_(false), ref_count_(1) {
     109              52 :     NaClXMutexCtor(&ref_count_mu_);
     110             104 :   }
     111              34 :   ~DescWrapperCommon() {
     112              34 :     NaClMutexDtor(&ref_count_mu_);
     113              68 :   }
     114                 : 
     115                 :   // Set up the state.  Returns true on success.
     116                 :   bool Init();
     117                 : 
     118                 :   // Boolean to indicate the object was successfully initialized.
     119                 :   bool is_initialized_;
     120                 :   // The reference count and the mutex to protect it.
     121                 :   RefCountType ref_count_;
     122                 :   struct NaClMutex ref_count_mu_;
     123                 : 
     124                 :   DISALLOW_COPY_AND_ASSIGN(DescWrapperCommon);
     125                 : };
     126                 : 
     127                 : bool DescWrapperCommon::Init() {
     128                 :   // Successfully initialized.
     129              52 :   is_initialized_ = true;
     130              52 :   return true;
     131                 : }
     132                 : 
     133                 : DescWrapperFactory::DescWrapperFactory() {
     134             208 :   common_data_ = new(std::nothrow) DescWrapperCommon();
     135              52 :   if (NULL == common_data_) {
     136               0 :     return;
     137                 :   }
     138              52 :   if (!common_data_->Init()) {
     139               0 :     delete common_data_;
     140               0 :     common_data_ = NULL;
     141               0 :   }
     142             104 : }
     143                 : 
     144              39 : DescWrapperFactory::~DescWrapperFactory() {
     145              39 :   if (NULL != common_data_) {
     146              39 :     common_data_->Unref();
     147              39 :   }
     148              78 : }
     149                 : 
     150               0 : int DescWrapperFactory::MakeBoundSock(DescWrapper* pair[2]) {
     151               0 :   CHECK(common_data_->is_initialized());
     152                 : 
     153               0 :   struct NaClDesc* descs[2] = { NULL, NULL };
     154               0 :   DescWrapper* tmp_pair[2] = { NULL, NULL };
     155                 : 
     156               0 :   int ret = NaClCommonDescMakeBoundSock(descs);
     157               0 :   if (0 != ret) {
     158               0 :     return ret;
     159                 :   }
     160               0 :   tmp_pair[0] = new(std::nothrow) DescWrapper(common_data_, descs[0]);
     161               0 :   if (NULL == tmp_pair[0]) {
     162               0 :     goto cleanup;
     163                 :   }
     164               0 :   descs[0] = NULL;  // DescWrapper took ownership of descs[0].
     165               0 :   tmp_pair[1] = new(std::nothrow) DescWrapper(common_data_, descs[1]);
     166               0 :   if (NULL == tmp_pair[1]) {
     167               0 :     goto cleanup;
     168                 :   }
     169               0 :   descs[1] = NULL;  // DescWrapper took ownership of descs[1].
     170               0 :   pair[0] = tmp_pair[0];
     171               0 :   pair[1] = tmp_pair[1];
     172               0 :   return 0;
     173                 : 
     174                 :  cleanup:
     175               0 :   NaClDescSafeUnref(descs[0]);
     176               0 :   NaClDescSafeUnref(descs[1]);
     177               0 :   delete tmp_pair[0];
     178               0 :   delete tmp_pair[1];
     179               0 :   return -1;
     180               0 : }
     181                 : 
     182              34 : DescWrapper* DescWrapperFactory::MakeImcSock(NaClHandle handle) {
     183              34 :   struct NaClDescImcDesc* desc =
     184              34 :     reinterpret_cast<NaClDescImcDesc*>(calloc(1, sizeof *desc));
     185              34 :   if (NULL == desc) {
     186               0 :     return NULL;
     187                 :   }
     188              34 :   if (!NaClDescImcDescCtor(desc, handle)) {
     189               0 :     free(desc);
     190               0 :     return NULL;
     191                 :   }
     192                 : 
     193              34 :   return MakeGenericCleanup(reinterpret_cast<struct NaClDesc*>(desc));
     194              34 : }
     195                 : 
     196               0 : DescWrapper* DescWrapperFactory::ImportShmHandle(NaClHandle handle,
     197               0 :                                                  size_t size) {
     198               0 :   struct NaClDesc *desc = NaClDescImcShmMake(handle, size);
     199               0 :   if (desc == NULL) {
     200               0 :     return NULL;
     201                 :   }
     202               0 :   return MakeGenericCleanup(desc);
     203               0 : }
     204                 : 
     205               0 : DescWrapper* DescWrapperFactory::ImportSyncSocketHandle(NaClHandle handle) {
     206               0 :   struct NaClDesc *desc = NaClDescSyncSocketMake(handle);
     207               0 :   if (desc == NULL) {
     208               0 :     return NULL;
     209                 :   }
     210               0 :   return MakeGenericCleanup(desc);
     211               0 : }
     212                 : 
     213               0 : DescWrapper* DescWrapperFactory::MakeGeneric(struct NaClDesc* desc) {
     214               0 :   CHECK(common_data_->is_initialized());
     215               0 :   return new(std::nothrow) DescWrapper(common_data_, desc);
     216               0 : }
     217                 : 
     218                 : 
     219              55 : DescWrapper* DescWrapperFactory::MakeGenericCleanup(struct NaClDesc* desc) {
     220             165 :   CHECK(common_data_->is_initialized());
     221             220 :   DescWrapper* wrapper = new(std::nothrow) DescWrapper(common_data_, desc);
     222              55 :   if (NULL != wrapper) {
     223              55 :       return wrapper;
     224                 :   }
     225               0 :   NaClDescSafeUnref(desc);
     226               0 :   return NULL;
     227              55 : }
     228                 : 
     229               0 : int DescWrapperFactory::MakeSocketPair(DescWrapper* pair[2]) {
     230               0 :   CHECK(common_data_->is_initialized());
     231               0 :   struct NaClDesc* descs[2] = { NULL, NULL };
     232               0 :   DescWrapper* tmp_pair[2] = { NULL, NULL };
     233                 : 
     234               0 :   int ret = NaClCommonDescSocketPair(descs);
     235               0 :   if (0 != ret) {
     236               0 :     return ret;
     237                 :   }
     238               0 :   tmp_pair[0] = new(std::nothrow) DescWrapper(common_data_, descs[0]);
     239               0 :   if (NULL == tmp_pair[0]) {
     240               0 :     goto cleanup;
     241                 :   }
     242               0 :   descs[0] = NULL;  // DescWrapper took ownership of descs[0].
     243               0 :   tmp_pair[1] = new(std::nothrow) DescWrapper(common_data_, descs[1]);
     244               0 :   if (NULL == tmp_pair[1]) {
     245               0 :     goto cleanup;
     246                 :   }
     247               0 :   descs[1] = NULL;  // DescWrapper took ownership of descs[1].
     248               0 :   pair[0] = tmp_pair[0];
     249               0 :   pair[1] = tmp_pair[1];
     250               0 :   return 0;
     251                 : 
     252                 :  cleanup:
     253               0 :   NaClDescSafeUnref(descs[0]);
     254               0 :   NaClDescSafeUnref(descs[1]);
     255               0 :   delete tmp_pair[0];
     256               0 :   delete tmp_pair[1];
     257               0 :   return -1;
     258               0 : }
     259                 : 
     260               0 : DescWrapper* DescWrapperFactory::MakeFileDesc(int host_os_desc, int mode) {
     261               0 :   struct NaClDesc* desc = NaClDescIoDescFromDescAllocCtor(host_os_desc, mode);
     262               0 :   if (NULL == desc) {
     263               0 :     return NULL;
     264                 :   }
     265               0 :   return MakeGenericCleanup(desc);
     266               0 : }
     267                 : 
     268               0 : DescWrapper* DescWrapperFactory::MakeFileDescQuota(int host_os_desc,
     269               0 :                                                    int mode,
     270               0 :                                                    const uint8_t* file_id) {
     271               0 :   struct NaClDesc* desc = NaClDescIoDescFromDescAllocCtor(host_os_desc, mode);
     272               0 :   if (NULL == desc) {
     273               0 :     return NULL;
     274                 :   }
     275               0 :   struct NaClDesc* desc_quota = MakeQuotaCommon(file_id, desc);
     276               0 :   if (desc_quota == NULL) {
     277               0 :     NaClDescSafeUnref(desc);
     278               0 :     return NULL;
     279                 :   }
     280               0 :   return MakeGenericCleanup(desc_quota);
     281               0 : }
     282                 : 
     283              14 : DescWrapper* DescWrapperFactory::OpenHostFile(const char* fname,
     284              14 :                                               int flags,
     285              14 :                                               int mode) {
     286              14 :   struct NaClDesc* desc = OpenHostFileCommon(fname, flags, mode);
     287              14 :   if (NULL == desc) {
     288               0 :     return NULL;
     289                 :   }
     290              14 :   return MakeGenericCleanup(desc);
     291              14 : }
     292                 : 
     293               0 : DescWrapper* DescWrapperFactory::OpenHostFileQuota(const char* fname,
     294               0 :                                                    int flags,
     295               0 :                                                    int mode,
     296               0 :                                                    const uint8_t* file_id) {
     297               0 :   struct NaClDesc* desc = OpenHostFileCommon(fname, flags, mode);
     298               0 :   if (NULL == desc) {
     299               0 :     return NULL;
     300                 :   }
     301               0 :   struct NaClDesc* desc_quota = MakeQuotaCommon(file_id, desc);
     302               0 :   if (NULL == desc_quota) {
     303               0 :     NaClDescSafeUnref(desc);
     304               0 :     return NULL;
     305                 :   }
     306               0 :   return MakeGenericCleanup(desc_quota);
     307               0 : }
     308                 : 
     309                 : DescWrapper* DescWrapperFactory::OpenRng() {
     310               0 :   struct NaClDescRng* nhrp =
     311               0 :     reinterpret_cast<struct NaClDescRng*>(calloc(1, sizeof(*nhrp)));
     312               0 :   if (NULL == nhrp) {
     313               0 :     return NULL;
     314                 :   }
     315               0 :   if (!NaClDescRngCtor(nhrp)) {
     316               0 :     free(nhrp);
     317               0 :     return NULL;
     318                 :   }
     319                 : 
     320               0 :   return MakeGenericCleanup(reinterpret_cast<struct NaClDesc*>(nhrp));
     321               0 : }
     322                 : 
     323                 : DescWrapper* DescWrapperFactory::MakeInvalid() {
     324               0 :   struct NaClDescInvalid *desc =
     325               0 :       const_cast<NaClDescInvalid*>(NaClDescInvalidMake());
     326               0 :   if (NULL == desc) {
     327               0 :     return NULL;
     328                 :   }
     329                 : 
     330               0 :   return MakeGenericCleanup(reinterpret_cast<struct NaClDesc*>(desc));
     331               0 : }
     332                 : 
     333             248 : DescWrapper::DescWrapper(DescWrapperCommon* common_data,
     334             248 :                          struct NaClDesc* desc)
     335             124 :       : common_data_(common_data), desc_(desc) {
     336                 :   // DescWrapper takes ownership of desc from caller, so no Ref call here.
     337             124 :   if (NULL != common_data_) {
     338             124 :     common_data_->Ref();
     339             124 :   }
     340             248 : }
     341                 : 
     342              95 : DescWrapper::~DescWrapper() {
     343              95 :   if (NULL != common_data_) {
     344              95 :     common_data_->Unref();
     345              95 :   }
     346              95 :   NaClDescSafeUnref(desc_);
     347              95 :   desc_ = NULL;
     348             190 : }
     349                 : 
     350               0 : ssize_t DescWrapper::Read(void* buf, size_t len) {
     351               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     352                 :       Read(desc_, buf, len);
     353                 : }
     354                 : 
     355               0 : ssize_t DescWrapper::Write(const void* buf, size_t len) {
     356               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     357                 :       Write(desc_, buf, len);
     358                 : }
     359                 : 
     360               0 : nacl_off64_t DescWrapper::Seek(nacl_off64_t offset, int whence) {
     361               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     362                 :       Seek(desc_,
     363                 :            offset,
     364                 :            whence);
     365                 : }
     366                 : 
     367               0 : int DescWrapper::Fstat(struct nacl_abi_stat* statbuf) {
     368               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     369                 :       Fstat(desc_, statbuf);
     370                 : }
     371                 : 
     372                 : int DescWrapper::Close() {
     373               0 :   NaClRefCountUnref(&desc_->base);
     374               0 :   return 0;
     375                 : }
     376                 : 
     377               0 : ssize_t DescWrapper::Getdents(void* dirp, size_t count) {
     378               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     379                 :       Getdents(desc_,
     380                 :                dirp,
     381                 :                count);
     382                 : }
     383                 : 
     384                 : int DescWrapper::Lock() {
     385               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     386                 :       Lock(desc_);
     387                 : }
     388                 : 
     389                 : int DescWrapper::TryLock() {
     390               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     391                 :       TryLock(desc_);
     392                 : }
     393                 : 
     394                 : int DescWrapper::Unlock() {
     395               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     396                 :       Unlock(desc_);
     397                 : }
     398                 : 
     399               0 : int DescWrapper::Wait(DescWrapper* mutex) {
     400               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     401                 :       Wait(desc_, mutex->desc_);
     402                 : }
     403                 : 
     404               0 : int DescWrapper::TimedWaitAbs(DescWrapper* mutex,
     405               0 :                               struct nacl_abi_timespec* ts) {
     406               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     407                 :       TimedWaitAbs(desc_,
     408                 :                    mutex->desc_,
     409                 :                    ts);
     410                 : }
     411                 : 
     412                 : int DescWrapper::Signal() {
     413               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     414                 :       Signal(desc_);
     415                 : }
     416                 : 
     417                 : int DescWrapper::Broadcast() {
     418               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     419                 :       Broadcast(desc_);
     420                 : }
     421                 : 
     422               0 : ssize_t DescWrapper::SendMsg(const MsgHeader* dgram, int flags) {
     423               0 :   struct NaClImcTypedMsgHdr header;
     424               0 :   ssize_t ret = -NACL_ABI_ENOMEM;
     425               0 :   nacl_abi_size_t diov_length = dgram->iov_length;
     426               0 :   nacl_abi_size_t ddescv_length = dgram->ndescv_length;
     427               0 :   nacl_abi_size_t i;
     428                 : 
     429                 :   // Initialize to allow simple cleanups.
     430               0 :   header.ndescv = NULL;
     431                 :   // Allocate and copy IOV.
     432               0 :   if (NACL_ABI_SIZE_T_MAX / sizeof(NaClImcMsgIoVec) <= diov_length) {
     433               0 :     goto cleanup;
     434                 :   }
     435                 :   header.iov = reinterpret_cast<NaClImcMsgIoVec*>(
     436               0 :       calloc(diov_length, sizeof(*(header.iov))));
     437               0 :   if (NULL == header.iov) {
     438               0 :     goto cleanup;
     439                 :   }
     440               0 :   header.iov_length = diov_length;
     441               0 :   for (i = 0; i < dgram->iov_length; ++i) {
     442               0 :     header.iov[i].base = dgram->iov[i].base;
     443               0 :     header.iov[i].length = dgram->iov[i].length;
     444               0 :   }
     445                 :   // Allocate and copy the descriptor vector, removing DescWrappers.
     446               0 :   if (NACL_HANDLE_COUNT_MAX < dgram->ndescv_length) {
     447               0 :     goto cleanup;
     448                 :   }
     449               0 :   if (NACL_ABI_SIZE_T_MAX / sizeof(header.ndescv[0]) <= ddescv_length) {
     450               0 :     goto cleanup;
     451                 :   }
     452                 :   header.ndescv = reinterpret_cast<NaClDesc**>(
     453               0 :       calloc(ddescv_length, sizeof(*(header.ndescv))));
     454               0 :   if (NULL == header.iov) {
     455               0 :     goto cleanup;
     456                 :   }
     457               0 :   header.ndesc_length = ddescv_length;
     458               0 :   for (i = 0; i < dgram->ndescv_length; ++i) {
     459               0 :     header.ndescv[i] = dgram->ndescv[i]->desc_;
     460               0 :   }
     461                 :   // Send the message.
     462               0 :   ret = NACL_VTBL(NaClDesc, desc_)->SendMsg(desc_, &header, flags);
     463                 : 
     464                 :  cleanup:
     465               0 :   free(header.ndescv);
     466               0 :   free(header.iov);
     467               0 :   return ret;
     468                 : }
     469                 : 
     470              20 : ssize_t DescWrapper::RecvMsg(MsgHeader* dgram, int flags,
     471              20 :                              struct NaClDescQuotaInterface *quota_interface) {
     472              20 :   struct NaClImcTypedMsgHdr header;
     473              20 :   ssize_t ret = -NACL_ABI_ENOMEM;
     474              20 :   nacl_abi_size_t diov_length = dgram->iov_length;
     475              20 :   nacl_abi_size_t ddescv_length = dgram->ndescv_length;
     476              20 :   nacl_abi_size_t i;
     477                 : 
     478                 :   // Initialize to allow simple cleanups.
     479              20 :   header.iov = NULL;
     480              20 :   header.ndescv = NULL;
     481             360 :   for (i = 0; i < dgram->ndescv_length; ++i) {
     482             160 :     dgram->ndescv[i] = NULL;
     483             160 :   }
     484                 : 
     485                 :   // Allocate and copy the IOV.
     486              20 :   if (NACL_ABI_SIZE_T_MAX / sizeof(NaClImcMsgIoVec) <= diov_length) {
     487               0 :     goto cleanup;
     488                 :   }
     489                 :   header.iov = reinterpret_cast<NaClImcMsgIoVec*>(
     490              20 :       calloc(diov_length, sizeof(*(header.iov))));
     491              20 :   if (NULL == header.iov) {
     492               0 :     goto cleanup;
     493                 :   }
     494              20 :   header.iov_length = diov_length;
     495              80 :   for (i = 0; i < dgram->iov_length; ++i) {
     496              20 :     header.iov[i].base = dgram->iov[i].base;
     497              20 :     header.iov[i].length = dgram->iov[i].length;
     498              20 :   }
     499                 :   // Allocate and copy the descriptor vector.
     500              20 :   if (NACL_HANDLE_COUNT_MAX < dgram->ndescv_length) {
     501               0 :     goto cleanup;
     502                 :   }
     503              20 :   if (NACL_ABI_SIZE_T_MAX / sizeof(header.ndescv[0]) <= ddescv_length) {
     504               0 :     goto cleanup;
     505                 :   }
     506                 :   header.ndescv = reinterpret_cast<NaClDesc**>(
     507              20 :       calloc(ddescv_length, sizeof(*(header.ndescv))));
     508              20 :   if (NULL == header.ndescv) {
     509               0 :     goto cleanup;
     510                 :   }
     511              20 :   header.ndesc_length = ddescv_length;
     512                 :   // Receive the message.
     513              20 :   ret = NACL_VTBL(NaClDesc, desc_)->RecvMsg(desc_, &header, flags,
     514                 :                                             quota_interface);
     515              20 :   if (ret < 0) {
     516               0 :     goto cleanup;
     517                 :   }
     518              20 :   dgram->ndescv_length = header.ndesc_length;
     519              20 :   dgram->flags = header.flags;
     520                 :   // Copy the descriptors, creating new DescWrappers around them.
     521             120 :   for (i = 0; i < header.ndesc_length; ++i) {
     522             160 :     dgram->ndescv[i] =
     523                 :         new(std::nothrow) DescWrapper(common_data_, header.ndescv[i]);
     524              40 :     if (NULL == dgram->ndescv[i]) {
     525               0 :       goto cleanup;
     526                 :     }
     527              40 :   }
     528              20 :   free(header.ndescv);
     529              20 :   free(header.iov);
     530              20 :   return ret;
     531                 : 
     532                 :  cleanup:
     533               0 :   for (i = 0; i < ddescv_length; ++i) {
     534               0 :     delete dgram->ndescv[i];
     535               0 :   }
     536               0 :   free(header.ndescv);
     537               0 :   free(header.iov);
     538               0 :   return ret;
     539              20 : }
     540                 : 
     541                 : DescWrapper* DescWrapper::Connect() {
     542              29 :   struct NaClDesc* connected_desc;
     543              29 :   int rv = reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     544                 :       ConnectAddr(desc_,
     545                 :                   &connected_desc);
     546              29 :   if (0 != rv) {
     547                 :     // Connect failed.
     548               0 :     return NULL;
     549                 :   }
     550             116 :   DescWrapper* wrapper =
     551                 :       new(std::nothrow) DescWrapper(common_data_, connected_desc);
     552              29 :   if (NULL == wrapper) {
     553               0 :     NaClDescUnref(connected_desc);
     554               0 :   }
     555              29 :   return wrapper;
     556              29 : }
     557                 : 
     558                 : DescWrapper* DescWrapper::Accept() {
     559               0 :   struct NaClDesc* connected_desc;
     560               0 :   int rv = reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     561                 :       AcceptConn(desc_, &connected_desc);
     562               0 :   if (0 != rv) {
     563                 :     // Accept failed.
     564               0 :     return NULL;
     565                 :   }
     566               0 :   DescWrapper* wrapper =
     567                 :       new(std::nothrow) DescWrapper(common_data_, connected_desc);
     568               0 :   if (NULL == wrapper) {
     569               0 :     NaClDescUnref(connected_desc);
     570               0 :   }
     571               0 :   return wrapper;
     572               0 : }
     573                 : 
     574                 : int DescWrapper::Post() {
     575               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     576                 :       Post(desc_);
     577                 : }
     578                 : 
     579                 : int DescWrapper::SemWait() {
     580               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     581                 :       SemWait(desc_);
     582                 : }
     583                 : 
     584                 : int DescWrapper::GetValue() {
     585               0 :   return reinterpret_cast<struct NaClDescVtbl const *>(desc_->base.vtbl)->
     586                 :       GetValue(desc_);
     587                 : }
     588                 : 
     589                 : }  // namespace nacl

Generated by: LCOV version 1.7