12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/serialized_handle.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
79ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/memory/shared_memory.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/pickle.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/platform_file.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "build/build_config.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_platform_file.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_NACL)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <unistd.h>
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ppapi {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace proxy {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedHandle::SerializedHandle()
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : type_(INVALID),
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shm_handle_(base::SharedMemory::NULLHandle()),
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_(0),
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      descriptor_(IPC::InvalidPlatformFileForTransit()) {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedHandle::SerializedHandle(Type type_param)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : type_(type_param),
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shm_handle_(base::SharedMemory::NULLHandle()),
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_(0),
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      descriptor_(IPC::InvalidPlatformFileForTransit()) {
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedHandle::SerializedHandle(const base::SharedMemoryHandle& handle,
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   uint32 size)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : type_(SHARED_MEMORY),
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shm_handle_(handle),
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_(size),
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      descriptor_(IPC::InvalidPlatformFileForTransit()) {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SerializedHandle::SerializedHandle(
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Type type,
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const IPC::PlatformFileForTransit& socket_descriptor)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : type_(type),
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shm_handle_(base::SharedMemory::NULLHandle()),
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      size_(0),
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      descriptor_(socket_descriptor) {
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SerializedHandle::IsHandleValid() const {
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (type_) {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHARED_MEMORY:
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return base::SharedMemory::IsHandleValid(shm_handle_);
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SOCKET:
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case CHANNEL_HANDLE:
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case FILE:
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return !(IPC::InvalidPlatformFileForTransit() == descriptor_);
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case INVALID:
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No default so the compiler will warn us if a new type is added.
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SerializedHandle::Close() {
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsHandleValid()) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    switch (type_) {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case INVALID:
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        NOTREACHED();
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case SHARED_MEMORY:
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::SharedMemory::CloseHandle(shm_handle_);
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case SOCKET:
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case CHANNEL_HANDLE:
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case FILE:
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::PlatformFile file =
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            IPC::PlatformFileForTransitToPlatformFile(descriptor_);
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_NACL)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::ClosePlatformFile(file);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        close(file);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // No default so the compiler will warn us if a new type is added.
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *this = SerializedHandle();
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SerializedHandle::WriteHeader(const Header& hdr, Pickle* pickle) {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!pickle->WriteInt(hdr.type))
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (hdr.type == SHARED_MEMORY) {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!pickle->WriteUInt32(hdr.size))
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
100a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  if (hdr.type == FILE) {
101a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    if (!pickle->WriteInt(hdr.open_flag))
102a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return false;
103a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  }
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SerializedHandle::ReadHeader(PickleIterator* iter, Header* hdr) {
109a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  *hdr = Header(INVALID, 0, 0);
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int type = 0;
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!iter->ReadInt(&type))
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool valid_type = false;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  switch (type) {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SHARED_MEMORY: {
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      uint32 size = 0;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!iter->ReadUInt32(&size))
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return false;
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      hdr->size = size;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      valid_type = true;
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
123a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    case FILE: {
124a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      int open_flag = 0;
125a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      if (!iter->ReadInt(&open_flag))
126a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)        return false;
127a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      hdr->open_flag = open_flag;
128a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      valid_type = true;
129a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    }
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case SOCKET:
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case CHANNEL_HANDLE:
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case INVALID:
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      valid_type = true;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No default so the compiler will warn us if a new type is added.
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (valid_type)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    hdr->type = Type(type);
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return valid_type;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace proxy
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace ppapi
144