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/files/file.h"
      8 #include "base/memory/shared_memory.h"
      9 #include "base/pickle.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       open_flags_(0),
     26       file_io_(0) {
     27 }
     28 
     29 SerializedHandle::SerializedHandle(Type type_param)
     30     : type_(type_param),
     31       shm_handle_(base::SharedMemory::NULLHandle()),
     32       size_(0),
     33       descriptor_(IPC::InvalidPlatformFileForTransit()),
     34       open_flags_(0),
     35       file_io_(0) {
     36 }
     37 
     38 SerializedHandle::SerializedHandle(const base::SharedMemoryHandle& handle,
     39                                    uint32 size)
     40     : type_(SHARED_MEMORY),
     41       shm_handle_(handle),
     42       size_(size),
     43       descriptor_(IPC::InvalidPlatformFileForTransit()),
     44       open_flags_(0),
     45       file_io_(0) {
     46 }
     47 
     48 SerializedHandle::SerializedHandle(
     49     Type type,
     50     const IPC::PlatformFileForTransit& socket_descriptor)
     51     : type_(type),
     52       shm_handle_(base::SharedMemory::NULLHandle()),
     53       size_(0),
     54       descriptor_(socket_descriptor),
     55       open_flags_(0),
     56       file_io_(0) {
     57 }
     58 
     59 bool SerializedHandle::IsHandleValid() const {
     60   switch (type_) {
     61     case SHARED_MEMORY:
     62       return base::SharedMemory::IsHandleValid(shm_handle_);
     63     case SOCKET:
     64     case FILE:
     65       return !(IPC::InvalidPlatformFileForTransit() == descriptor_);
     66     case INVALID:
     67       return false;
     68     // No default so the compiler will warn us if a new type is added.
     69   }
     70   return false;
     71 }
     72 
     73 void SerializedHandle::Close() {
     74   if (IsHandleValid()) {
     75     switch (type_) {
     76       case INVALID:
     77         NOTREACHED();
     78         break;
     79       case SHARED_MEMORY:
     80         base::SharedMemory::CloseHandle(shm_handle_);
     81         break;
     82       case SOCKET:
     83       case FILE:
     84         base::File file_closer = IPC::PlatformFileForTransitToFile(descriptor_);
     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_flags) || !pickle->WriteInt(hdr.file_io))
    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, 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_flags = 0;
    125       PP_Resource file_io = 0;
    126       if (!iter->ReadInt(&open_flags) || !iter->ReadInt(&file_io))
    127         return false;
    128       hdr->open_flags = open_flags;
    129       hdr->file_io = file_io;
    130       valid_type = true;
    131     }
    132     case SOCKET:
    133     case INVALID:
    134       valid_type = true;
    135       break;
    136     // No default so the compiler will warn us if a new type is added.
    137   }
    138   if (valid_type)
    139     hdr->type = Type(type);
    140   return valid_type;
    141 }
    142 
    143 }  // namespace proxy
    144 }  // namespace ppapi
    145