OLD | NEW |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <pthread.h> | 5 #include <pthread.h> |
6 #include <unistd.h> | 6 #include <unistd.h> |
7 | 7 |
8 #include <sstream> | 8 #include <sstream> |
9 #include <string> | 9 #include <string> |
10 | 10 |
11 #include "native_client/src/untrusted/irt/irt.h" | 11 #include "native_client/src/untrusted/irt/irt.h" |
12 | 12 |
13 #include "ppapi/cpp/completion_callback.h" | 13 #include "ppapi/cpp/completion_callback.h" |
14 #include "ppapi/cpp/instance.h" | 14 #include "ppapi/cpp/instance.h" |
15 #include "ppapi/cpp/module.h" | 15 #include "ppapi/cpp/module.h" |
| 16 #include "ppapi/cpp/tcp_socket.h" |
16 #include "ppapi/cpp/var.h" | 17 #include "ppapi/cpp/var.h" |
| 18 #include "ppapi/utility/completion_callback_factory.h" |
17 | 19 |
18 namespace { | 20 namespace { |
19 | 21 |
20 std::string g_last_error; | 22 std::string g_last_error; |
21 pp::Instance* g_instance = NULL; | 23 pp::Instance* g_instance = NULL; |
22 | 24 |
23 // This should be the same as FileDescriptorSet::kMaxDescriptorsPerMessage in | 25 // This should be the same as FileDescriptorSet::kMaxDescriptorsPerMessage in |
24 // ipc/file_descriptor_set_posix.h. | 26 // ipc/file_descriptor_set_posix.h. |
25 // TODO(yusukes): Once all the NaCl toolchains support C++11, Add | 27 // TODO(yusukes): Once all the NaCl toolchains support C++11, Add |
26 // #include "ipc/file_descriptor_set_posix.h" and remove the constant. | 28 // #include "ipc/file_descriptor_set_posix.h" and remove the constant. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 // returned from open_resource has its own file offset. | 94 // returned from open_resource has its own file offset. |
93 if (!LoadManifestInternal(&nacl_irt_resource_open, key.str(), content)) | 95 if (!LoadManifestInternal(&nacl_irt_resource_open, key.str(), content)) |
94 break; | 96 break; |
95 } | 97 } |
96 } | 98 } |
97 | 99 |
98 void PostReply(void* user_data, int32_t status) { | 100 void PostReply(void* user_data, int32_t status) { |
99 if (!g_last_error.empty()) | 101 if (!g_last_error.empty()) |
100 g_instance->PostMessage(g_last_error.c_str()); | 102 g_instance->PostMessage(g_last_error.c_str()); |
101 else | 103 else |
102 g_instance->PostMessage("Test passed"); | 104 g_instance->PostMessage("PASS"); |
103 } | 105 } |
104 | 106 |
105 void* RunTestsOnBackgroundThread(void* thread_id) { | 107 void* RunTestsOnBackgroundThread(void* thread_id) { |
106 LoadManifest(); | 108 LoadManifest(); |
107 pp::Module::Get()->core()->CallOnMainThread( | 109 pp::Module::Get()->core()->CallOnMainThread( |
108 0, pp::CompletionCallback(&PostReply, NULL)); | 110 0, pp::CompletionCallback(&PostReply, NULL)); |
109 return NULL; | 111 return NULL; |
110 } | 112 } |
111 | 113 |
112 class MyInstance : public pp::Instance { | 114 class MyInstance : public pp::Instance { |
113 public: | 115 public: |
114 explicit MyInstance(PP_Instance instance) : pp::Instance(instance) { | 116 explicit MyInstance(PP_Instance instance) |
| 117 : pp::Instance(instance), socket_(this), factory_(this) { |
115 g_instance = this; | 118 g_instance = this; |
116 } | 119 } |
117 virtual ~MyInstance() { } | 120 virtual ~MyInstance() { } |
118 | 121 |
| 122 void DidBindSocket(int32_t result) { |
| 123 // We didn't ask for socket permission in our manifest, so it should fail. |
| 124 if (result == PP_ERROR_NOACCESS) |
| 125 PostMessage("PASS"); |
| 126 else |
| 127 PostMessage(result); |
| 128 } |
| 129 |
119 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { | 130 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { |
120 pthread_t thread; | 131 pthread_t thread; |
121 // irt_open_resource() isn't allowed to be called on the main thread once | 132 // irt_open_resource() isn't allowed to be called on the main thread once |
122 // Pepper starts, so the test must happen on a background thread. | 133 // Pepper starts, so the test must happen on a background thread. |
123 if (pthread_create(&thread, NULL, &RunTestsOnBackgroundThread, NULL)) { | 134 if (pthread_create(&thread, NULL, &RunTestsOnBackgroundThread, NULL)) { |
124 g_last_error = "pthread_create failed"; | 135 g_last_error = "pthread_create failed"; |
125 PostReply(NULL, 0); | 136 PostReply(NULL, 0); |
126 } | 137 } |
| 138 // Attempt to bind a socket. We don't have permissions, so it should fail. |
| 139 PP_NetAddress_IPv4 ipv4_address = {80, {127, 0, 0, 1} }; |
| 140 pp::NetAddress address(this, ipv4_address); |
| 141 socket_.Bind(address, factory_.NewCallback(&MyInstance::DidBindSocket)); |
127 return true; | 142 return true; |
128 } | 143 } |
| 144 |
| 145 private: |
| 146 pp::TCPSocket socket_; |
| 147 pp::CompletionCallbackFactory<MyInstance> factory_; |
129 }; | 148 }; |
130 | 149 |
131 class MyModule : public pp::Module { | 150 class MyModule : public pp::Module { |
132 public: | 151 public: |
133 MyModule() : pp::Module() { } | 152 MyModule() : pp::Module() { } |
134 virtual ~MyModule() { } | 153 virtual ~MyModule() { } |
135 | 154 |
136 virtual pp::Instance* CreateInstance(PP_Instance instance) { | 155 virtual pp::Instance* CreateInstance(PP_Instance instance) { |
137 return new MyInstance(instance); | 156 return new MyInstance(instance); |
138 } | 157 } |
139 }; | 158 }; |
140 | 159 |
141 } // namespace | 160 } // namespace |
142 | 161 |
143 namespace pp { | 162 namespace pp { |
144 | 163 |
145 Module* CreateModule() { | 164 Module* CreateModule() { |
146 return new MyModule(); | 165 return new MyModule(); |
147 } | 166 } |
148 | 167 |
149 } // namespace pp | 168 } // namespace pp |
OLD | NEW |