1// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "platform/globals.h"
6#if defined(HOST_OS_ANDROID)
7
8#include "bin/stdio.h"
9
10#include <errno.h> // NOLINT
11#include <sys/ioctl.h> // NOLINT
12#include <termios.h> // NOLINT
13
14#include "bin/fdutils.h"
15#include "platform/signal_blocker.h"
16
17namespace dart {
18namespace bin {
19
20bool Stdin::ReadByte(intptr_t fd, int* byte) {
21 unsigned char b;
22 ssize_t s = TEMP_FAILURE_RETRY(read(fd, &b, 1));
23 if (s < 0) {
24 return false;
25 }
26 *byte = (s == 0) ? -1 : b;
27 return true;
28}
29
30bool Stdin::GetEchoMode(intptr_t fd, bool* enabled) {
31 struct termios term;
32 int status = NO_RETRY_EXPECTED(tcgetattr(fd, &term));
33 if (status != 0) {
34 return false;
35 }
36 *enabled = ((term.c_lflag & ECHO) != 0);
37 return true;
38}
39
40bool Stdin::SetEchoMode(intptr_t fd, bool enabled) {
41 struct termios term;
42 int status = NO_RETRY_EXPECTED(tcgetattr(fd, &term));
43 if (status != 0) {
44 return false;
45 }
46 if (enabled) {
47 term.c_lflag |= (ECHO | ECHONL);
48 } else {
49 term.c_lflag &= ~(ECHO | ECHONL);
50 }
51 status = NO_RETRY_EXPECTED(tcsetattr(fd, TCSANOW, &term));
52 return (status == 0);
53}
54
55bool Stdin::GetLineMode(intptr_t fd, bool* enabled) {
56 struct termios term;
57 int status = NO_RETRY_EXPECTED(tcgetattr(fd, &term));
58 if (status != 0) {
59 return false;
60 }
61 *enabled = ((term.c_lflag & ICANON) != 0);
62 return true;
63}
64
65bool Stdin::SetLineMode(intptr_t fd, bool enabled) {
66 struct termios term;
67 int status = NO_RETRY_EXPECTED(tcgetattr(fd, &term));
68 if (status != 0) {
69 return false;
70 }
71 if (enabled) {
72 term.c_lflag |= ICANON;
73 } else {
74 term.c_lflag &= ~(ICANON);
75 }
76 status = NO_RETRY_EXPECTED(tcsetattr(fd, TCSANOW, &term));
77 return (status == 0);
78}
79
80static bool TermIsKnownToSupportAnsi() {
81 const char* term = getenv("TERM");
82 if (term == NULL) {
83 return false;
84 }
85
86 return strstr(term, "xterm") != NULL || strstr(term, "screen") != NULL ||
87 strstr(term, "rxvt") != NULL;
88}
89
90bool Stdin::AnsiSupported(intptr_t fd, bool* supported) {
91 *supported = isatty(fd) && TermIsKnownToSupportAnsi();
92 return true;
93}
94
95bool Stdout::GetTerminalSize(intptr_t fd, int size[2]) {
96 struct winsize w;
97 int status = NO_RETRY_EXPECTED(ioctl(fd, TIOCGWINSZ, &w));
98 if ((status == 0) && ((w.ws_col != 0) || (w.ws_row != 0))) {
99 size[0] = w.ws_col;
100 size[1] = w.ws_row;
101 return true;
102 }
103 return false;
104}
105
106bool Stdout::AnsiSupported(intptr_t fd, bool* supported) {
107 *supported = isatty(fd) && TermIsKnownToSupportAnsi();
108 return true;
109}
110
111} // namespace bin
112} // namespace dart
113
114#endif // defined(HOST_OS_ANDROID)
115