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