Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1209)

Side by Side Diff: native_client_sdk/src/libraries/ppapi_simple/ps_instance.cc

Issue 23005005: [NaCl SDK] nacl_io: Add initial implementations of kill and signal (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <errno.h> 5 #include <errno.h>
6 #include <fcntl.h> 6 #include <fcntl.h>
7 #include <pthread.h> 7 #include <pthread.h>
8 #include <stdio.h> 8 #include <stdio.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <sys/ioctl.h>
10 #include <sys/types.h> 11 #include <sys/types.h>
11 #include <sys/stat.h> 12 #include <sys/stat.h>
12 13
13 #include <algorithm> 14 #include <algorithm>
14 #include <cstdlib> 15 #include <cstdlib>
15 #include <cstring> 16 #include <cstring>
16 #include <sstream> 17 #include <sstream>
17 #include <string> 18 #include <string>
18 #include <vector> 19 #include <vector>
19 20
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 return ret; 90 return ret;
90 } 91 }
91 92
92 PSInstance::PSInstance(PP_Instance instance) 93 PSInstance::PSInstance(PP_Instance instance)
93 : pp::Instance(instance), 94 : pp::Instance(instance),
94 pp::MouseLock(this), 95 pp::MouseLock(this),
95 pp::Graphics3DClient(this), 96 pp::Graphics3DClient(this),
96 main_loop_(NULL), 97 main_loop_(NULL),
97 events_enabled_(PSE_NONE), 98 events_enabled_(PSE_NONE),
98 verbosity_(PSV_WARN), 99 verbosity_(PSV_WARN),
99 fd_tty_(-1) { 100 tty_fd_(-1) {
binji 2013/08/22 18:09:36 init tty_prefix_ and tty_resize_ to NULL?
Sam Clegg 2013/08/22 19:52:25 Done.
100 // Set the single Instance object 101 // Set the single Instance object
101 s_InstanceObject = this; 102 s_InstanceObject = this;
102 103
103 #ifdef NACL_SDK_DEBUG 104 #ifdef NACL_SDK_DEBUG
104 SetVerbosity(PSV_LOG); 105 SetVerbosity(PSV_LOG);
105 #endif 106 #endif
106 107
107 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | 108 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE |
108 PP_INPUTEVENT_CLASS_KEYBOARD | 109 PP_INPUTEVENT_CLASS_KEYBOARD |
109 PP_INPUTEVENT_CLASS_WHEEL | 110 PP_INPUTEVENT_CLASS_WHEEL |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 nacl_io_init_ppapi(PSGetInstanceId(), PSGetInterface); 201 nacl_io_init_ppapi(PSGetInstanceId(), PSGetInterface);
201 int fd0 = open(getenv("PS_STDIN"), O_RDONLY); 202 int fd0 = open(getenv("PS_STDIN"), O_RDONLY);
202 dup2(fd0, 0); 203 dup2(fd0, 0);
203 204
204 int fd1 = open(getenv("PS_STDOUT"), O_WRONLY); 205 int fd1 = open(getenv("PS_STDOUT"), O_WRONLY);
205 dup2(fd1, 1); 206 dup2(fd1, 1);
206 207
207 int fd2 = open(getenv("PS_STDERR"), O_WRONLY); 208 int fd2 = open(getenv("PS_STDERR"), O_WRONLY);
208 dup2(fd2, 2); 209 dup2(fd2, 2);
209 210
210 const char* tty_prefix = getenv("PS_TTY_PREFIX"); 211 tty_prefix_ = getenv("PS_TTY_PREFIX");
211 if (tty_prefix) { 212 if (tty_prefix_) {
212 fd_tty_ = open("/dev/tty", O_WRONLY); 213 tty_fd_ = open("/dev/tty", O_WRONLY);
213 if (fd_tty_ >= 0) { 214 if (tty_fd_ >= 0) {
214 ioctl(fd_tty_, TIOCNACLPREFIX, const_cast<char*>(tty_prefix)); 215 RegisterMessageHandler(tty_prefix_, MessageHandlerInputStatic, this);
216 tty_resize_ = getenv("PS_TTY_RESIZE");
217 if (tty_resize_)
binji 2013/08/22 18:09:36 tty_resize_ is only used in this function, does it
Sam Clegg 2013/08/22 19:52:25 Done.
218 RegisterMessageHandler(tty_resize_, MessageHandlerResizeStatic, this);
219
220 char* handler = reinterpret_cast<char*>(TtyOutputHandlerStatic);
221 ioctl(tty_fd_, TIOCNACLOUTPUT, handler);
215 } else { 222 } else {
216 Error("Failed to open /dev/tty.\n"); 223 Error("Failed to open /dev/tty.\n");
217 } 224 }
218 } 225 }
219 226
220 // Set line buffering on stdout and stderr 227 // Set line buffering on stdout and stderr
221 #if !defined(WIN32) 228 #if !defined(WIN32)
222 setvbuf(stderr, NULL, _IOLBF, 0); 229 setvbuf(stderr, NULL, _IOLBF, 0);
223 setvbuf(stdout, NULL, _IOLBF, 0); 230 setvbuf(stdout, NULL, _IOLBF, 0);
224 #endif 231 #endif
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 if (resource) { 310 if (resource) {
304 PSInterfaceCore()->AddRefResource(resource); 311 PSInterfaceCore()->AddRefResource(resource);
305 } 312 }
306 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent)); 313 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
307 memset(env, 0, sizeof(*env)); 314 memset(env, 0, sizeof(*env));
308 env->type = type; 315 env->type = type;
309 env->as_resource = resource; 316 env->as_resource = resource;
310 event_queue_.Enqueue(env); 317 event_queue_.Enqueue(env);
311 } 318 }
312 319
320 void PSInstance::MessageHandlerInput(const pp::Var& message) {
321 // Since our message may contain null characters, we can't send it as a
322 // naked C string, so we package it up in this struct before sending it
323 // to the ioctl.
324 assert(message.is_string());
325 std::string buffer = message.AsString();
326
327 struct tioc_nacl_input_string ioctl_message;
328 ioctl_message.length = buffer.size();
329 ioctl_message.buffer = buffer.c_str();
330 int ret =
331 ioctl(tty_fd_, TIOCNACLINPUT, reinterpret_cast<char*>(&ioctl_message));
332 if (ret != 0 && errno != ENOTTY) {
333 Error("ioctl returned unexpected error: %d.\n", ret);
334 }
335 }
336
337 int PSInstance::TtyOutputHandlerStatic(const char* buf, int count) {
338 return PSInstance::GetInstance()->TtyOutputHandler(buf, count);
339 }
340
341 int PSInstance::TtyOutputHandler(const char* buf, int count) {
342 // We prepend the prefix_ to the data in buf, then package it up
343 // and post it as a message to javascript.
344 const char* data = static_cast<const char*>(buf);
345 std::string message = tty_prefix_;
346 message.append(data, count);
347 PostMessage(pp::Var(message));
348 return count;
349 }
350
351 void PSInstance::MessageHandlerInputStatic(const pp::Var& key,
352 const pp::Var& value,
353 void* user_data) {
354 PSInstance* instance = reinterpret_cast<PSInstance*>(user_data);
355 instance->MessageHandlerInput(value);
356 }
357
358 void PSInstance::MessageHandlerResizeStatic(const pp::Var& key,
binji 2013/08/22 18:09:36 nit: the ordering of functions here is strange, I'
Sam Clegg 2013/08/22 19:52:25 Done.
359 const pp::Var& value,
360 void* user_data) {
361 PSInstance* instance = reinterpret_cast<PSInstance*>(user_data);
362 instance->MessageHandlerResize(value);
363 }
364
365 void PSInstance::MessageHandlerResize(const pp::Var& message) {
366 assert(message.is_array());
binji 2013/08/22 18:09:36 document this message somewhere in the header? va
Sam Clegg 2013/08/22 19:52:25 Done.
367 pp::VarArray array(message);
368 assert(array.GetLength() == 2);
369
370 struct winsize size;
371 memset(&size, 0, sizeof(size));
372 size.ws_col = array.Get(0).AsInt();
373 size.ws_row = array.Get(1).AsInt();
374 ioctl(tty_fd_, TIOCSWINSZ, reinterpret_cast<char*>(&size));
375 }
376
377 void PSInstance::RegisterMessageHandler(std::string message_name,
378 MessageHandler_t handler,
379 void* user_data) {
380 if (handler == NULL) {
381 message_handlers_.erase(message_name);
382 return;
383 }
384
385 MessageHandler message_handler = { handler, user_data };
386 message_handlers_[message_name] = message_handler;
387 }
388
313 void PSInstance::PostEvent(PSEventType type, const PP_Var& var) { 389 void PSInstance::PostEvent(PSEventType type, const PP_Var& var) {
314 assert(PSE_INSTANCE_HANDLEMESSAGE == type); 390 assert(PSE_INSTANCE_HANDLEMESSAGE == type);
315 391
316 // If the user has specified a tty_prefix_ (using ioctl), then we'll give the 392 // If the user has specified a tty_prefix_, then filter out the
317 // tty node a chance to vacuum up any messages beginning with that prefix. If 393 // matching message here and pass them to the tty node via
318 // the message does not start with the prefix, the ioctl call will return 394 // ioctl() rather then adding them to the even queue.
binji 2013/08/22 18:09:36 sp: event
Sam Clegg 2013/08/22 19:52:25 Done.
319 // ENOENT and we'll pass the message through to the event queue. 395 pp::Var event(var);
320 if (fd_tty_ >= 0 && var.type == PP_VARTYPE_STRING) { 396 if (tty_fd_ >= 0 && event.is_string()) {
321 uint32_t message_len; 397 std::string message = event.AsString();
322 const char* message = PSInterfaceVar()->VarToUtf8(var, &message_len); 398 size_t prefix_len = strlen(tty_prefix_);
323 std::string message_str(message, message + message_len); 399 if (message.size() > prefix_len) {
400 if (!strncmp(message.c_str(), tty_prefix_, prefix_len)) {
401 MessageHandlerInput(pp::Var(message.substr(prefix_len)));
402 return;
403 }
404 }
405 }
324 406
325 // Since our message may contain null characters, we can't send it as a 407 // If the message is a dictionary then see if it matches one
326 // naked C string, so we package it up in this struct before sending it 408 // of the specific handlers, then call that handler rather than
327 // to the ioctl. 409 // queuing an event.
328 struct tioc_nacl_input_string ioctl_message; 410 if (tty_fd_ >= 0 && event.is_dictionary()) {
329 ioctl_message.length = message_len; 411 pp::VarDictionary dictionary(var);
330 ioctl_message.buffer = message_str.data(); 412 pp::VarArray keys = dictionary.GetKeys();
331 int ret = 413 if (keys.GetLength() == 1) {
332 ioctl(fd_tty_, TIOCNACLINPUT, reinterpret_cast<char*>(&ioctl_message)); 414 pp::Var key = keys.Get(0);
333 if (ret != 0 && errno != ENOTTY) { 415 std::map<std::string, MessageHandler>::iterator iter =
binji 2013/08/22 18:09:36 I find that this is a bit more readable if you mak
Sam Clegg 2013/08/22 19:52:25 Done.
334 Error("ioctl returned unexpected error: %d.\n", ret); 416 message_handlers_.find(key.AsString());
417 if (iter != message_handlers_.end()) {
418 MessageHandler_t handler = iter->second.handler;
419 void* user_data = iter->second.user_data;
420 handler(key, dictionary.Get(key), user_data);
421 return;
422 }
335 } 423 }
336
337 return;
338 } 424 }
339 425
340 PSInterfaceVar()->AddRef(var); 426 PSInterfaceVar()->AddRef(var);
341 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent)); 427 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
342 memset(env, 0, sizeof(*env)); 428 memset(env, 0, sizeof(*env));
343 env->type = type; 429 env->type = type;
344 env->as_var = var; 430 env->as_var = var;
345 event_queue_.Enqueue(env); 431 event_queue_.Enqueue(env);
346 } 432 }
347 433
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 499
414 void PSInstance::Graphics3DContextLost() { 500 void PSInstance::Graphics3DContextLost() {
415 Log("Graphics3DContextLost\n"); 501 Log("Graphics3DContextLost\n");
416 PostEvent(PSE_GRAPHICS3D_GRAPHICS3DCONTEXTLOST); 502 PostEvent(PSE_GRAPHICS3D_GRAPHICS3DCONTEXTLOST);
417 } 503 }
418 504
419 void PSInstance::MouseLockLost() { 505 void PSInstance::MouseLockLost() {
420 Log("MouseLockLost\n"); 506 Log("MouseLockLost\n");
421 PostEvent(PSE_MOUSELOCK_MOUSELOCKLOST); 507 PostEvent(PSE_MOUSELOCK_MOUSELOCKLOST);
422 } 508 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698