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 #ifndef PPAPI_PROXY_SERIALIZED_HANDLES_H_ 6 #define PPAPI_PROXY_SERIALIZED_HANDLES_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/atomicops.h" 12 #include "base/basictypes.h" 13 #include "base/logging.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/memory/shared_memory.h" 16 #include "build/build_config.h" 17 #include "ipc/ipc_platform_file.h" 18 #include "ppapi/c/pp_resource.h" 19 #include "ppapi/proxy/ppapi_proxy_export.h" 20 21 class Pickle; 22 23 namespace ppapi { 24 namespace proxy { 25 26 // SerializedHandle is a unified structure for holding a handle (e.g., a shared 27 // memory handle, socket descriptor, etc). This is useful for passing handles in 28 // resource messages and also makes it easier to translate handles in 29 // NaClIPCAdapter for use in NaCl. 30 class PPAPI_PROXY_EXPORT SerializedHandle { 31 public: 32 enum Type { INVALID, SHARED_MEMORY, SOCKET, FILE }; 33 // Header contains the fields that we send in IPC messages, apart from the 34 // actual handle. See comments on the SerializedHandle fields below. 35 struct Header { HeaderHeader36 Header() : type(INVALID), size(0), open_flags(0) {} HeaderHeader37 Header(Type type_arg, 38 uint32 size_arg, 39 int32 open_flags_arg, 40 PP_Resource file_io_arg) 41 : type(type_arg), 42 size(size_arg), 43 open_flags(open_flags_arg), 44 file_io(file_io_arg) { 45 } 46 47 Type type; 48 uint32 size; 49 int32 open_flags; 50 PP_Resource file_io; 51 }; 52 53 SerializedHandle(); 54 // Create an invalid handle of the given type. 55 explicit SerializedHandle(Type type); 56 57 // Create a shared memory handle. 58 SerializedHandle(const base::SharedMemoryHandle& handle, uint32 size); 59 60 // Create a socket or file handle. 61 SerializedHandle(const Type type, 62 const IPC::PlatformFileForTransit& descriptor); 63 type()64 Type type() const { return type_; } is_shmem()65 bool is_shmem() const { return type_ == SHARED_MEMORY; } is_socket()66 bool is_socket() const { return type_ == SOCKET; } is_file()67 bool is_file() const { return type_ == FILE; } shmem()68 const base::SharedMemoryHandle& shmem() const { 69 DCHECK(is_shmem()); 70 return shm_handle_; 71 } size()72 uint32 size() const { 73 DCHECK(is_shmem()); 74 return size_; 75 } descriptor()76 const IPC::PlatformFileForTransit& descriptor() const { 77 DCHECK(is_socket() || is_file()); 78 return descriptor_; 79 } open_flags()80 int32 open_flags() const { 81 return open_flags_; 82 } file_io()83 PP_Resource file_io() const { 84 return file_io_; 85 } set_shmem(const base::SharedMemoryHandle & handle,uint32 size)86 void set_shmem(const base::SharedMemoryHandle& handle, uint32 size) { 87 type_ = SHARED_MEMORY; 88 shm_handle_ = handle; 89 size_ = size; 90 91 descriptor_ = IPC::InvalidPlatformFileForTransit(); 92 } set_socket(const IPC::PlatformFileForTransit & socket)93 void set_socket(const IPC::PlatformFileForTransit& socket) { 94 type_ = SOCKET; 95 descriptor_ = socket; 96 97 shm_handle_ = base::SharedMemory::NULLHandle(); 98 size_ = 0; 99 } set_file_handle(const IPC::PlatformFileForTransit & descriptor,int32 open_flags,PP_Resource file_io)100 void set_file_handle(const IPC::PlatformFileForTransit& descriptor, 101 int32 open_flags, 102 PP_Resource file_io) { 103 type_ = FILE; 104 105 descriptor_ = descriptor; 106 shm_handle_ = base::SharedMemory::NULLHandle(); 107 size_ = 0; 108 open_flags_ = open_flags; 109 file_io_ = file_io; 110 } set_null_shmem()111 void set_null_shmem() { 112 set_shmem(base::SharedMemory::NULLHandle(), 0); 113 } set_null_socket()114 void set_null_socket() { 115 set_socket(IPC::InvalidPlatformFileForTransit()); 116 } set_null_file_handle()117 void set_null_file_handle() { 118 set_file_handle(IPC::InvalidPlatformFileForTransit(), 0, 0); 119 } 120 bool IsHandleValid() const; 121 header()122 Header header() const { 123 return Header(type_, size_, open_flags_, file_io_); 124 } 125 126 // Closes the handle and sets it to invalid. 127 void Close(); 128 129 // Write/Read a Header, which contains all the data except the handle. This 130 // allows us to write the handle in a platform-specific way, as is necessary 131 // in NaClIPCAdapter to share handles with NaCl from Windows. 132 static bool WriteHeader(const Header& hdr, Pickle* pickle); 133 static bool ReadHeader(PickleIterator* iter, Header* hdr); 134 135 private: 136 // The kind of handle we're holding. 137 Type type_; 138 139 // We hold more members than we really need; we can't easily use a union, 140 // because we hold non-POD types. But these types are pretty light-weight. If 141 // we add more complex things later, we should come up with a more memory- 142 // efficient strategy. 143 // These are valid if type == SHARED_MEMORY. 144 base::SharedMemoryHandle shm_handle_; 145 uint32 size_; 146 147 // This is valid if type == SOCKET || type == FILE. 148 IPC::PlatformFileForTransit descriptor_; 149 150 // The following fields are valid if type == FILE. 151 int32 open_flags_; 152 // This is non-zero if file writes require quota checking. 153 PP_Resource file_io_; 154 }; 155 156 } // namespace proxy 157 } // namespace ppapi 158 159 #endif // PPAPI_PROXY_SERIALIZED_HANDLES_H_ 160