OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "nacl_io/devfs/tty_node.h" | 5 #include "nacl_io/devfs/tty_node.h" |
6 | 6 |
7 #include <assert.h> | 7 #include <assert.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <signal.h> | 9 #include <signal.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
11 #include <string.h> | 11 #include <string.h> |
12 #include <sys/ioctl.h> | 12 #include <sys/ioctl.h> |
13 #include <unistd.h> | 13 #include <unistd.h> |
14 | 14 |
15 #include <algorithm> | 15 #include <algorithm> |
16 | 16 |
17 #include "nacl_io/filesystem.h" | 17 #include "nacl_io/filesystem.h" |
18 #include "nacl_io/ioctl.h" | 18 #include "nacl_io/ioctl.h" |
19 #include "nacl_io/kernel_handle.h" | 19 #include "nacl_io/kernel_handle.h" |
20 #include "nacl_io/kernel_intercept.h" | 20 #include "nacl_io/kernel_intercept.h" |
21 #include "nacl_io/log.h" | |
21 #include "nacl_io/pepper_interface.h" | 22 #include "nacl_io/pepper_interface.h" |
22 #include "sdk_util/auto_lock.h" | 23 #include "sdk_util/auto_lock.h" |
23 | 24 |
24 #define CHECK_LFLAG(TERMIOS, FLAG) (TERMIOS.c_lflag& FLAG) | 25 #define CHECK_LFLAG(TERMIOS, FLAG) (TERMIOS.c_lflag& FLAG) |
25 | 26 |
26 #define IS_ECHO CHECK_LFLAG(termios_, ECHO) | 27 #define IS_ECHO CHECK_LFLAG(termios_, ECHO) |
27 #define IS_ECHOE CHECK_LFLAG(termios_, ECHOE) | 28 #define IS_ECHOE CHECK_LFLAG(termios_, ECHOE) |
28 #define IS_ECHONL CHECK_LFLAG(termios_, ECHONL) | 29 #define IS_ECHONL CHECK_LFLAG(termios_, ECHONL) |
29 #define IS_ECHOCTL CHECK_LFLAG(termios_, ECHOCTL) | 30 #define IS_ECHOCTL CHECK_LFLAG(termios_, ECHOCTL) |
30 #define IS_ICANON CHECK_LFLAG(termios_, ICANON) | 31 #define IS_ICANON CHECK_LFLAG(termios_, ICANON) |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
160 Error error = Write(data, string, count, &wrote); | 161 Error error = Write(data, string, count, &wrote); |
161 if (error != 0 || wrote != count) { | 162 if (error != 0 || wrote != count) { |
162 // TOOD(sbc): Do something more useful in response to a | 163 // TOOD(sbc): Do something more useful in response to a |
163 // failure to echo. | 164 // failure to echo. |
164 return error; | 165 return error; |
165 } | 166 } |
166 | 167 |
167 return 0; | 168 return 0; |
168 } | 169 } |
169 | 170 |
170 Error TtyNode::ProcessInput(struct tioc_nacl_input_string* message) { | 171 Error TtyNode::ProcessInput(PP_Var message) { |
172 if (message.type != PP_VARTYPE_ARRAY_BUFFER) { | |
173 LOG_ERROR("ProcessInput: expected ArrayBuffer but got %d.", message.type); | |
174 return EINVAL; | |
175 } | |
176 | |
177 PepperInterface* ppapi = filesystem_->ppapi(); | |
178 if (!ppapi) { | |
179 LOG_ERROR("ProcessInput: ppapi is NULL."); | |
180 return EINVAL; | |
181 } | |
182 | |
183 VarArrayBufferInterface* buffer_iface = ppapi->GetVarArrayBufferInterface(); | |
184 if (!buffer_iface) { | |
185 LOG_ERROR("ProcessInput: ArrayBuffer interface pointer is NULL."); | |
186 return EINVAL; | |
187 } | |
Sam Clegg
2014/06/17 22:29:28
I hate to do this to you now, but I think the actu
binji
2014/06/17 22:55:22
Done.
| |
188 | |
189 uint32_t num_bytes; | |
190 if (buffer_iface->ByteLength(message, &num_bytes) != PP_TRUE) { | |
191 LOG_ERROR("ProcessInput: unable to get ArrayBuffer length."); | |
192 return EINVAL; | |
193 } | |
194 | |
195 const char* buffer = static_cast<const char*>(buffer_iface->Map(message)); | |
196 Error error = ProcessInput(buffer, num_bytes); | |
197 buffer_iface->Unmap(message); | |
198 return error; | |
199 } | |
200 | |
201 Error TtyNode::ProcessInput(const char* buffer, size_t num_bytes) { | |
171 AUTO_LOCK(emitter_->GetLock()) | 202 AUTO_LOCK(emitter_->GetLock()) |
172 | 203 |
173 const char* buffer = message->buffer; | |
174 size_t num_bytes = message->length; | |
175 | |
176 for (size_t i = 0; i < num_bytes; i++) { | 204 for (size_t i = 0; i < num_bytes; i++) { |
177 char c = buffer[i]; | 205 char c = buffer[i]; |
178 // Transform characters according to input flags. | 206 // Transform characters according to input flags. |
179 if (c == '\r') { | 207 if (c == '\r') { |
180 if (termios_.c_iflag & IGNCR) | 208 if (termios_.c_iflag & IGNCR) |
181 continue; | 209 continue; |
182 if (termios_.c_iflag & ICRNL) | 210 if (termios_.c_iflag & ICRNL) |
183 c = '\n'; | 211 c = '\n'; |
184 } else if (c == '\n') { | 212 } else if (c == '\n') { |
185 if (termios_.c_iflag & INLCR) | 213 if (termios_.c_iflag & INLCR) |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
241 AUTO_LOCK(output_lock_); | 269 AUTO_LOCK(output_lock_); |
242 if (arg == NULL) { | 270 if (arg == NULL) { |
243 output_handler_.handler = NULL; | 271 output_handler_.handler = NULL; |
244 return 0; | 272 return 0; |
245 } | 273 } |
246 if (output_handler_.handler != NULL) | 274 if (output_handler_.handler != NULL) |
247 return EALREADY; | 275 return EALREADY; |
248 output_handler_ = *arg; | 276 output_handler_ = *arg; |
249 return 0; | 277 return 0; |
250 } | 278 } |
251 case TIOCNACLINPUT: { | 279 case NACL_IOC_HANDLEMESSAGE: { |
252 // This ioctl is used to deliver data from the user to this tty node's | 280 struct PP_Var* message = va_arg(args, struct PP_Var*); |
253 // input buffer. | 281 return ProcessInput(*message); |
254 struct tioc_nacl_input_string* message = | |
255 va_arg(args, struct tioc_nacl_input_string*); | |
256 return ProcessInput(message); | |
257 } | 282 } |
258 case TIOCSWINSZ: { | 283 case TIOCSWINSZ: { |
259 struct winsize* size = va_arg(args, struct winsize*); | 284 struct winsize* size = va_arg(args, struct winsize*); |
260 { | 285 { |
261 AUTO_LOCK(node_lock_); | 286 AUTO_LOCK(node_lock_); |
262 if (rows_ == size->ws_row && cols_ == size->ws_col) | 287 if (rows_ == size->ws_row && cols_ == size->ws_col) |
263 return 0; | 288 return 0; |
264 rows_ = size->ws_row; | 289 rows_ = size->ws_row; |
265 cols_ = size->ws_col; | 290 cols_ = size->ws_col; |
266 } | 291 } |
267 ki_kill(getpid(), SIGWINCH); | 292 ki_kill(getpid(), SIGWINCH); |
268 { | 293 { |
269 // Wake up any thread waiting on Read with POLLERR then immediate | 294 // Wake up any thread waiting on Read with POLLERR then immediate |
270 // clear it to signal EINTR. | 295 // clear it to signal EINTR. |
271 AUTO_LOCK(emitter_->GetLock()) | 296 AUTO_LOCK(emitter_->GetLock()) |
272 emitter_->RaiseEvents_Locked(POLLERR); | 297 emitter_->RaiseEvents_Locked(POLLERR); |
273 emitter_->ClearEvents_Locked(POLLERR); | 298 emitter_->ClearEvents_Locked(POLLERR); |
274 } | 299 } |
275 return 0; | 300 return 0; |
276 } | 301 } |
277 case TIOCGWINSZ: { | 302 case TIOCGWINSZ: { |
278 struct winsize* size = va_arg(args, struct winsize*); | 303 struct winsize* size = va_arg(args, struct winsize*); |
279 size->ws_row = rows_; | 304 size->ws_row = rows_; |
280 size->ws_col = cols_; | 305 size->ws_col = cols_; |
281 return 0; | 306 return 0; |
282 } | 307 } |
308 default: { | |
309 LOG_ERROR("TtyNode:VIoctl: Unknown request: %#x", request); | |
310 } | |
283 } | 311 } |
284 | 312 |
285 return EINVAL; | 313 return EINVAL; |
286 } | 314 } |
287 | 315 |
288 Error TtyNode::Tcgetattr(struct termios* termios_p) { | 316 Error TtyNode::Tcgetattr(struct termios* termios_p) { |
289 AUTO_LOCK(node_lock_); | 317 AUTO_LOCK(node_lock_); |
290 *termios_p = termios_; | 318 *termios_p = termios_; |
291 return 0; | 319 return 0; |
292 } | 320 } |
293 | 321 |
294 Error TtyNode::Tcsetattr(int optional_actions, | 322 Error TtyNode::Tcsetattr(int optional_actions, |
295 const struct termios* termios_p) { | 323 const struct termios* termios_p) { |
296 AUTO_LOCK(node_lock_); | 324 AUTO_LOCK(node_lock_); |
297 termios_ = *termios_p; | 325 termios_ = *termios_p; |
298 return 0; | 326 return 0; |
299 } | 327 } |
300 | 328 |
301 } // namespace nacl_io | 329 } // namespace nacl_io |
OLD | NEW |