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

Generated by: LCOV version 1.7