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

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: nits 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),
101 tty_prefix_(NULL) {
100 // Set the single Instance object 102 // Set the single Instance object
101 s_InstanceObject = this; 103 s_InstanceObject = this;
102 104
103 #ifdef NACL_SDK_DEBUG 105 #ifdef NACL_SDK_DEBUG
104 SetVerbosity(PSV_LOG); 106 SetVerbosity(PSV_LOG);
105 #endif 107 #endif
106 108
107 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE | 109 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE |
108 PP_INPUTEVENT_CLASS_KEYBOARD | 110 PP_INPUTEVENT_CLASS_KEYBOARD |
109 PP_INPUTEVENT_CLASS_WHEEL | 111 PP_INPUTEVENT_CLASS_WHEEL |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 nacl_io_init_ppapi(PSGetInstanceId(), PSGetInterface); 202 nacl_io_init_ppapi(PSGetInstanceId(), PSGetInterface);
201 int fd0 = open(getenv("PS_STDIN"), O_RDONLY); 203 int fd0 = open(getenv("PS_STDIN"), O_RDONLY);
202 dup2(fd0, 0); 204 dup2(fd0, 0);
203 205
204 int fd1 = open(getenv("PS_STDOUT"), O_WRONLY); 206 int fd1 = open(getenv("PS_STDOUT"), O_WRONLY);
205 dup2(fd1, 1); 207 dup2(fd1, 1);
206 208
207 int fd2 = open(getenv("PS_STDERR"), O_WRONLY); 209 int fd2 = open(getenv("PS_STDERR"), O_WRONLY);
208 dup2(fd2, 2); 210 dup2(fd2, 2);
209 211
210 const char* tty_prefix = getenv("PS_TTY_PREFIX"); 212 tty_prefix_ = getenv("PS_TTY_PREFIX");
211 if (tty_prefix) { 213 if (tty_prefix_) {
212 fd_tty_ = open("/dev/tty", O_WRONLY); 214 tty_fd_ = open("/dev/tty", O_WRONLY);
213 if (fd_tty_ >= 0) { 215 if (tty_fd_ >= 0) {
214 ioctl(fd_tty_, TIOCNACLPREFIX, const_cast<char*>(tty_prefix)); 216 RegisterMessageHandler(tty_prefix_, MessageHandlerInputStatic, this);
217 const char* tty_resize = getenv("PS_TTY_RESIZE");
218 if (tty_resize)
219 RegisterMessageHandler(tty_resize, MessageHandlerResizeStatic, this);
220
221 tioc_nacl_output handler;
222 handler.handler = TtyOutputHandlerStatic;
223 handler.user_data = this;
224 ioctl(tty_fd_, TIOCNACLOUTPUT, reinterpret_cast<char*>(&handler));
215 } else { 225 } else {
216 Error("Failed to open /dev/tty.\n"); 226 Error("Failed to open /dev/tty.\n");
217 } 227 }
218 } 228 }
219 229
220 // Set line buffering on stdout and stderr 230 // Set line buffering on stdout and stderr
221 #if !defined(WIN32) 231 #if !defined(WIN32)
222 setvbuf(stderr, NULL, _IOLBF, 0); 232 setvbuf(stderr, NULL, _IOLBF, 0);
223 setvbuf(stdout, NULL, _IOLBF, 0); 233 setvbuf(stdout, NULL, _IOLBF, 0);
224 #endif 234 #endif
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 if (resource) { 313 if (resource) {
304 PSInterfaceCore()->AddRefResource(resource); 314 PSInterfaceCore()->AddRefResource(resource);
305 } 315 }
306 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent)); 316 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
307 memset(env, 0, sizeof(*env)); 317 memset(env, 0, sizeof(*env));
308 env->type = type; 318 env->type = type;
309 env->as_resource = resource; 319 env->as_resource = resource;
310 event_queue_.Enqueue(env); 320 event_queue_.Enqueue(env);
311 } 321 }
312 322
323 ssize_t PSInstance::TtyOutputHandler(const char* buf, size_t count) {
324 // We prepend the prefix_ to the data in buf, then package it up
325 // and post it as a message to javascript.
326 const char* data = static_cast<const char*>(buf);
327 std::string message = tty_prefix_;
328 message.append(data, count);
329 PostMessage(pp::Var(message));
330 return count;
331 }
332
333 void PSInstance::MessageHandlerInput(const pp::Var& message) {
334 // Since our message may contain null characters, we can't send it as a
335 // naked C string, so we package it up in this struct before sending it
336 // to the ioctl.
337 assert(message.is_string());
338 std::string buffer = message.AsString();
339
340 struct tioc_nacl_input_string ioctl_message;
341 ioctl_message.length = buffer.size();
342 ioctl_message.buffer = buffer.c_str();
343 int ret =
344 ioctl(tty_fd_, TIOCNACLINPUT, reinterpret_cast<char*>(&ioctl_message));
345 if (ret != 0 && errno != ENOTTY) {
346 Error("ioctl returned unexpected error: %d.\n", ret);
347 }
348 }
349
350 void PSInstance::MessageHandlerResize(const pp::Var& message) {
351 assert(message.is_array());
352 pp::VarArray array(message);
353 assert(array.GetLength() == 2);
354
355 struct winsize size;
356 memset(&size, 0, sizeof(size));
357 size.ws_col = array.Get(0).AsInt();
358 size.ws_row = array.Get(1).AsInt();
359 ioctl(tty_fd_, TIOCSWINSZ, reinterpret_cast<char*>(&size));
360 }
361
362 ssize_t PSInstance::TtyOutputHandlerStatic(const char* buf,
363 size_t count,
364 void* user_data) {
365 PSInstance* instance = reinterpret_cast<PSInstance*>(user_data);
366 return instance->TtyOutputHandler(buf, count);
367 }
368
369 void PSInstance::MessageHandlerInputStatic(const pp::Var& key,
370 const pp::Var& value,
371 void* user_data) {
372 PSInstance* instance = reinterpret_cast<PSInstance*>(user_data);
373 instance->MessageHandlerInput(value);
374 }
375
376 void PSInstance::MessageHandlerResizeStatic(const pp::Var& key,
377 const pp::Var& value,
378 void* user_data) {
379 PSInstance* instance = reinterpret_cast<PSInstance*>(user_data);
380 instance->MessageHandlerResize(value);
381 }
382
383 void PSInstance::RegisterMessageHandler(std::string message_name,
384 MessageHandler_t handler,
385 void* user_data) {
386 if (handler == NULL) {
387 message_handlers_.erase(message_name);
388 return;
389 }
390
391 MessageHandler message_handler = { handler, user_data };
392 message_handlers_[message_name] = message_handler;
393 }
394
313 void PSInstance::PostEvent(PSEventType type, const PP_Var& var) { 395 void PSInstance::PostEvent(PSEventType type, const PP_Var& var) {
314 assert(PSE_INSTANCE_HANDLEMESSAGE == type); 396 assert(PSE_INSTANCE_HANDLEMESSAGE == type);
315 397
316 // If the user has specified a tty_prefix_ (using ioctl), then we'll give the 398 // 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 399 // 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 400 // ioctl() rather then adding them to the event queue.
319 // ENOENT and we'll pass the message through to the event queue. 401 pp::Var event(var);
320 if (fd_tty_ >= 0 && var.type == PP_VARTYPE_STRING) { 402 if (tty_fd_ >= 0 && event.is_string()) {
321 uint32_t message_len; 403 std::string message = event.AsString();
322 const char* message = PSInterfaceVar()->VarToUtf8(var, &message_len); 404 size_t prefix_len = strlen(tty_prefix_);
323 std::string message_str(message, message + message_len); 405 if (message.size() > prefix_len) {
406 if (!strncmp(message.c_str(), tty_prefix_, prefix_len)) {
407 MessageHandlerInput(pp::Var(message.substr(prefix_len)));
408 return;
409 }
410 }
411 }
324 412
325 // Since our message may contain null characters, we can't send it as a 413 // 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 414 // of the specific handlers, then call that handler rather than
327 // to the ioctl. 415 // queuing an event.
328 struct tioc_nacl_input_string ioctl_message; 416 if (tty_fd_ >= 0 && event.is_dictionary()) {
329 ioctl_message.length = message_len; 417 pp::VarDictionary dictionary(var);
330 ioctl_message.buffer = message_str.data(); 418 pp::VarArray keys = dictionary.GetKeys();
331 int ret = 419 if (keys.GetLength() == 1) {
332 ioctl(fd_tty_, TIOCNACLINPUT, reinterpret_cast<char*>(&ioctl_message)); 420 pp::Var key = keys.Get(0);
333 if (ret != 0 && errno != ENOTTY) { 421 MessageHandlerMap::iterator iter =
334 Error("ioctl returned unexpected error: %d.\n", ret); 422 message_handlers_.find(key.AsString());
423 if (iter != message_handlers_.end()) {
424 MessageHandler_t handler = iter->second.handler;
425 void* user_data = iter->second.user_data;
426 handler(key, dictionary.Get(key), user_data);
427 return;
428 }
335 } 429 }
336
337 return;
338 } 430 }
339 431
340 PSInterfaceVar()->AddRef(var); 432 PSInterfaceVar()->AddRef(var);
341 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent)); 433 PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
342 memset(env, 0, sizeof(*env)); 434 memset(env, 0, sizeof(*env));
343 env->type = type; 435 env->type = type;
344 env->as_var = var; 436 env->as_var = var;
345 event_queue_.Enqueue(env); 437 event_queue_.Enqueue(env);
346 } 438 }
347 439
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 505
414 void PSInstance::Graphics3DContextLost() { 506 void PSInstance::Graphics3DContextLost() {
415 Log("Graphics3DContextLost\n"); 507 Log("Graphics3DContextLost\n");
416 PostEvent(PSE_GRAPHICS3D_GRAPHICS3DCONTEXTLOST); 508 PostEvent(PSE_GRAPHICS3D_GRAPHICS3DCONTEXTLOST);
417 } 509 }
418 510
419 void PSInstance::MouseLockLost() { 511 void PSInstance::MouseLockLost() {
420 Log("MouseLockLost\n"); 512 Log("MouseLockLost\n");
421 PostEvent(PSE_MOUSELOCK_MOUSELOCKLOST); 513 PostEvent(PSE_MOUSELOCK_MOUSELOCKLOST);
422 } 514 }
OLDNEW
« no previous file with comments | « native_client_sdk/src/libraries/ppapi_simple/ps_instance.h ('k') | native_client_sdk/src/libraries/sdk_util/auto_lock.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698