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

Unified Diff: native_client_sdk/src/libraries/nacl_io/mount_node_tty.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 side-by-side diff with in-line comments
Download patch
Index: native_client_sdk/src/libraries/nacl_io/mount_node_tty.cc
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_tty.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_tty.cc
index acb6bc67247f8561e58a58b54c2235080cebb125..534e53a28dac1605d6bea6ee82a1a8ff026d6163 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_tty.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_tty.cc
@@ -6,8 +6,11 @@
#include <assert.h>
#include <errno.h>
+#include <signal.h>
#include <stdio.h>
#include <string.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
#include <algorithm>
@@ -24,10 +27,17 @@
#define IS_ECHOCTL CHECK_LFLAG(termios_, ECHOCTL)
#define IS_ICANON CHECK_LFLAG(termios_, ICANON)
+#define DEFAULT_TTY_COLS 80
+#define DEFAULT_TTY_ROWS 30
+
namespace nacl_io {
MountNodeTty::MountNodeTty(Mount* mount) : MountNodeCharDevice(mount),
- is_readable_(false) {
+ is_readable_(false),
+ did_resize_(false),
+ rows_(DEFAULT_TTY_ROWS),
+ cols_(DEFAULT_TTY_COLS) {
+ output_handler_.handler = NULL;
pthread_cond_init(&is_readable_cond_, NULL);
InitTermios();
}
@@ -68,49 +78,37 @@ Error MountNodeTty::Write(size_t offs,
const void* buf,
size_t count,
int* out_bytes) {
- return Write(offs, buf, count, out_bytes, false);
-}
-
-Error MountNodeTty::Write(size_t offs,
- const void* buf,
- size_t count,
- int* out_bytes,
- bool locked) {
+ AUTO_LOCK(output_lock_);
*out_bytes = 0;
- if (!mount_->ppapi())
- return ENOSYS;
-
- MessagingInterface* msg_intr = mount_->ppapi()->GetMessagingInterface();
- VarInterface* var_intr = mount_->ppapi()->GetVarInterface();
+ // No handler registered.
+ if (output_handler_.handler == NULL)
+ return EIO;
- if (!(var_intr && msg_intr))
- return ENOSYS;
+ int rtn = output_handler_.handler(static_cast<const char*>(buf),
+ count,
+ output_handler_.user_data);
- // We append the prefix_ to the data in buf, then package it up
- // and post it as a message.
- const char* data = static_cast<const char*>(buf);
- std::string message;
- if (locked) {
- message = prefix_;
- } else {
- AUTO_LOCK(node_lock_);
- message = prefix_;
- }
+ // Negative return value means an error occured and the return
+ // value is a negated errno value.
+ if (rtn < 0)
+ return -rtn;
- message.append(data, count);
- uint32_t len = static_cast<uint32_t>(message.size());
- struct PP_Var val = var_intr->VarFromUtf8(message.data(), len);
- msg_intr->PostMessage(mount_->ppapi()->GetInstance(), val);
- var_intr->Release(val);
- *out_bytes = count;
+ *out_bytes = rtn;
return 0;
}
Error MountNodeTty::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
AUTO_LOCK(node_lock_);
+ did_resize_ = false;
while (!is_readable_) {
pthread_cond_wait(&is_readable_cond_, node_lock_.mutex());
+ if (!is_readable_ && did_resize_) {
+ // If an async resize event occured then return the failure and
+ // set EINTR.
+ *out_bytes = 0;
+ return EINTR;
+ }
}
size_t bytes_to_copy = std::min(count, input_buffer_.size());
@@ -151,7 +149,7 @@ Error MountNodeTty::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
Error MountNodeTty::Echo(const char* string, int count) {
int wrote;
- Error error = Write(0, string, count, &wrote, true);
+ Error error = Write(0, string, count, &wrote);
if (error != 0 || wrote != count) {
// TOOD(sbc): Do something more useful in response to a
// failure to echo.
@@ -163,15 +161,11 @@ Error MountNodeTty::Echo(const char* string, int count) {
Error MountNodeTty::ProcessInput(struct tioc_nacl_input_string* message) {
AUTO_LOCK(node_lock_);
- if (message->length < prefix_.size() ||
- strncmp(message->buffer, prefix_.data(), prefix_.size()) != 0) {
- return ENOTTY;
- }
- const char* buffer = message->buffer + prefix_.size();
- int num_bytes = message->length - prefix_.size();
+ const char* buffer = message->buffer;
+ size_t num_bytes = message->length;
- for (int i = 0; i < num_bytes; i++) {
+ for (size_t i = 0; i < num_bytes; i++) {
char c = buffer[i];
// Transform characters according to input flags.
if (c == '\r') {
@@ -233,28 +227,56 @@ Error MountNodeTty::ProcessInput(struct tioc_nacl_input_string* message) {
RaiseEvent(POLLIN);
pthread_cond_broadcast(&is_readable_cond_);
}
+
return 0;
}
Error MountNodeTty::Ioctl(int request, char* arg) {
- if (request == TIOCNACLPREFIX) {
- // This ioctl is used to change the prefix for this tty node.
- // The prefix is used to distinguish messages intended for this
- // tty node from all the other messages cluttering up the
- // javascript postMessage() channel.
- AUTO_LOCK(node_lock_);
- prefix_ = arg;
- return 0;
- } else if (request == TIOCNACLINPUT) {
- // This ioctl is used to deliver data from the user to this tty node's
- // input buffer. We check if the prefix in the input data matches the
- // prefix for this node, and only deliver the data if so.
- struct tioc_nacl_input_string* message =
- reinterpret_cast<struct tioc_nacl_input_string*>(arg);
- return ProcessInput(message);
- } else {
- return EINVAL;
+ switch (request) {
+ case TIOCNACLOUTPUT: {
+ AUTO_LOCK(output_lock_);
+ if (arg == NULL) {
+ output_handler_.handler = NULL;
+ return 0;
+ }
+ if (output_handler_.handler != NULL)
+ return EALREADY;
+ output_handler_ = *reinterpret_cast<tioc_nacl_output*>(arg);
+ return 0;
+ }
+ case TIOCNACLINPUT: {
+ // This ioctl is used to deliver data from the user to this tty node's
+ // input buffer.
+ struct tioc_nacl_input_string* message =
+ reinterpret_cast<struct tioc_nacl_input_string*>(arg);
+ return ProcessInput(message);
+ }
+ case TIOCSWINSZ: {
+ struct winsize* size = reinterpret_cast<struct winsize*>(arg);
+ {
+ AUTO_LOCK(node_lock_);
+ rows_ = size->ws_row;
+ cols_ = size->ws_col;
+ }
+ kill(getpid(), SIGWINCH);
+
+ // Wake up any thread waiting on Read
+ {
+ AUTO_LOCK(node_lock_);
+ did_resize_ = true;
+ pthread_cond_broadcast(&is_readable_cond_);
+ }
+ return 0;
+ }
+ case TIOCGWINSZ: {
+ struct winsize* size = reinterpret_cast<struct winsize*>(arg);
+ size->ws_row = rows_;
+ size->ws_col = cols_;
+ return 0;
+ }
}
+
+ return EINVAL;
}
Error MountNodeTty::Tcgetattr(struct termios* termios_p) {
« no previous file with comments | « native_client_sdk/src/libraries/nacl_io/mount_node_tty.h ('k') | native_client_sdk/src/libraries/ppapi_simple/ps_instance.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698