Home | History | Annotate | Download | only in proxy
      1 // Copyright (c) 2013 The Chromium 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 "ppapi/proxy/serialized_handle.h"
      6 
      7 #include "base/memory/shared_memory.h"
      8 #include "base/pickle.h"
      9 #include "base/platform_file.h"
     10 #include "build/build_config.h"
     11 #include "ipc/ipc_platform_file.h"
     12 
     13 #if defined(OS_NACL)
     14 #include <unistd.h>
     15 #endif
     16 
     17 namespace ppapi {
     18 namespace proxy {
     19 
     20 SerializedHandle::SerializedHandle()
     21     : type_(INVALID),
     22       shm_handle_(base::SharedMemory::NULLHandle()),
     23       size_(0),
     24       descriptor_(IPC::InvalidPlatformFileForTransit()) {
     25 }
     26 
     27 SerializedHandle::SerializedHandle(Type type_param)
     28     : type_(type_param),
     29       shm_handle_(base::SharedMemory::NULLHandle()),
     30       size_(0),
     31       descriptor_(IPC::InvalidPlatformFileForTransit()) {
     32 }
     33 
     34 SerializedHandle::SerializedHandle(const base::SharedMemoryHandle& handle,
     35                                    uint32 size)
     36     : type_(SHARED_MEMORY),
     37       shm_handle_(handle),
     38       size_(size),
     39       descriptor_(IPC::InvalidPlatformFileForTransit()) {
     40 }
     41 
     42 SerializedHandle::SerializedHandle(
     43     Type type,
     44     const IPC::PlatformFileForTransit& socket_descriptor)
     45     : type_(type),
     46       shm_handle_(base::SharedMemory::NULLHandle()),
     47       size_(0),
     48       descriptor_(socket_descriptor) {
     49 }
     50 
     51 bool SerializedHandle::IsHandleValid() const {
     52   switch (type_) {
     53     case SHARED_MEMORY:
     54       return base::SharedMemory::IsHandleValid(shm_handle_);
     55     case SOCKET:
     56     case CHANNEL_HANDLE:
     57     case FILE:
     58       return !(IPC::InvalidPlatformFileForTransit() == descriptor_);
     59     case INVALID:
     60       return false;
     61     // No default so the compiler will warn us if a new type is added.
     62   }
     63   return false;
     64 }
     65 
     66 void SerializedHandle::Close() {
     67   if (IsHandleValid()) {
     68     switch (type_) {
     69       case INVALID:
     70         NOTREACHED();
     71         break;
     72       case SHARED_MEMORY:
     73         base::SharedMemory::CloseHandle(shm_handle_);
     74         break;
     75       case SOCKET:
     76       case CHANNEL_HANDLE:
     77       case FILE:
     78         base::PlatformFile file =
     79             IPC::PlatformFileForTransitToPlatformFile(descriptor_);
     80 #if !defined(OS_NACL)
     81         base::ClosePlatformFile(file);
     82 #else
     83         close(file);
     84 #endif
     85         break;
     86       // No default so the compiler will warn us if a new type is added.
     87     }
     88   }
     89   *this = SerializedHandle();
     90 }
     91 
     92 // static
     93 bool SerializedHandle::WriteHeader(const Header& hdr, Pickle* pickle) {
     94   if (!pickle->WriteInt(hdr.type))
     95     return false;
     96   if (hdr.type == SHARED_MEMORY) {
     97     if (!pickle->WriteUInt32(hdr.size))
     98       return false;
     99   }
    100   if (hdr.type == FILE) {
    101     if (!pickle->WriteInt(hdr.open_flag))
    102       return false;
    103   }
    104   return true;
    105 }
    106 
    107 // static
    108 bool SerializedHandle::ReadHeader(PickleIterator* iter, Header* hdr) {
    109   *hdr = Header(INVALID, 0, 0);
    110   int type = 0;
    111   if (!iter->ReadInt(&type))
    112     return false;
    113   bool valid_type = false;
    114   switch (type) {
    115     case SHARED_MEMORY: {
    116       uint32 size = 0;
    117       if (!iter->ReadUInt32(&size))
    118         return false;
    119       hdr->size = size;
    120       valid_type = true;
    121       break;
    122     }
    123     case FILE: {
    124       int open_flag = 0;
    125       if (!iter->ReadInt(&open_flag))
    126         return false;
    127       hdr->open_flag = open_flag;
    128       valid_type = true;
    129     }
    130     case SOCKET:
    131     case CHANNEL_HANDLE:
    132     case INVALID:
    133       valid_type = true;
    134       break;
    135     // No default so the compiler will warn us if a new type is added.
    136   }
    137   if (valid_type)
    138     hdr->type = Type(type);
    139   return valid_type;
    140 }
    141 
    142 }  // namespace proxy
    143 }  // namespace ppapi
    144