Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: console.cc | |
4 | // Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
5 | // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. | |
6 | // | |
7 | // The above named program is free software; you can redistribute it and/or | |
8 | // modify it under the terms of the GNU General Public | |
9 | // License version 2 as published by the Free Software Foundation. | |
10 | // | |
11 | // The above named program is distributed in the hope that it will be | |
12 | // useful, but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | // General Public License for more details. | |
15 | // | |
16 | // You should have received a copy of the GNU General Public | |
17 | // License along with this work; if not, write to the Free Software | |
18 | // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 | // | |
20 | // ========== Copyright Header End ============================================ | |
21 | #include <fcntl.h> | |
22 | #include <termio.h> | |
23 | #include "console.h" | |
24 | ||
25 | ||
26 | bool console::get_pty(char **name, int *sfd, int *mfd){ | |
27 | if ((*mfd = open("/dev/ptmx", O_RDWR|O_NDELAY)) == -1) { | |
28 | fprintf(stderr,"get_pty: Cannot find a pseudo tty.\n"); | |
29 | return false; | |
30 | } | |
31 | ||
32 | if (grantpt(*mfd) < 0) { | |
33 | fprintf(stderr,"get_pty: Could not grant access to slave pseudo tty\n"); | |
34 | perror("grantpt"); | |
35 | close(*mfd); | |
36 | return false; | |
37 | } | |
38 | ||
39 | if (unlockpt(*mfd) < 0) { | |
40 | fprintf(stderr,"get_pty: Unable to unlock pseudo tty.\n"); | |
41 | perror("unlockpt"); | |
42 | close(*mfd); | |
43 | return false; | |
44 | } | |
45 | ||
46 | *name = strdup(ptsname(*mfd)); | |
47 | *sfd = open(*name, O_RDWR | O_NOCTTY); | |
48 | ||
49 | if (*sfd < 0) { | |
50 | fprintf(stderr,"get_pty: Unable to open slave side for %d\n", *mfd); | |
51 | close(*mfd); | |
52 | return false; | |
53 | } | |
54 | ||
55 | if (ioctl(*sfd, I_PUSH, "ptem") < 0) { | |
56 | fprintf(stderr,"get_pty: Ioctl I_PUSH ptem failed\n"); | |
57 | perror("ioctl i_push ptem"); | |
58 | close(*mfd); | |
59 | return false; | |
60 | } | |
61 | ||
62 | if (ioctl(*sfd, I_PUSH, "ldterm") < 0) { | |
63 | fprintf(stderr,"serial: Ioctl I_PUSH ldterm failed\n"); | |
64 | perror("ioctl i_push ldterm"); | |
65 | close(*mfd); | |
66 | return false; | |
67 | } | |
68 | ||
69 | chmod(*name,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); | |
70 | ||
71 | struct termio tty; | |
72 | ||
73 | ioctl(*sfd, TCGETA, &tty); | |
74 | tty.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL); | |
75 | tty.c_cc[VMIN] = 1; | |
76 | tty.c_cc[VTIME] = 0; | |
77 | ioctl(*sfd, TCSETA, &tty); | |
78 | ||
79 | return true; | |
80 | } | |
81 | ||
82 | void console::term_read_ports(fd_set readfds){ | |
83 | unsigned char buf[256]; | |
84 | ||
85 | for(termMapIter = termMap.begin(); termMapIter!= termMap.end(); termMapIter++){ | |
86 | if (FD_ISSET(termMapIter->second->mport_fd, &readfds)) { | |
87 | int nbytes; | |
88 | unsigned char ch; | |
89 | int index = 0; | |
90 | ||
91 | while ((nbytes = read(termMapIter->second->mport_fd, &ch, 1)) == 1){ | |
92 | buf[index++] = ch; | |
93 | buf[index] = 0; | |
94 | termMapIter->second->cbFun(termMapIter->second->cbData, buf, termMapIter->first); | |
95 | index = 0; | |
96 | } | |
97 | } | |
98 | } | |
99 | } | |
100 | //return a unique port identifier and the tty name for tip connection in tty_name | |
101 | int console::getTerminal(char * title, int numScrolLines, inputCallbk cbFun, void * cbData, char ** tty_name, bool pop_win){ | |
102 | ||
103 | console::title = strdup(title); | |
104 | term_lines = numScrolLines; | |
105 | ||
106 | term * t = new term(); | |
107 | int retVal; | |
108 | if(!get_pty(&t->tty_name, &t->port_fd, &t->mport_fd)){ | |
109 | delete t; | |
110 | return -1; | |
111 | } | |
112 | t->cbFun = cbFun; | |
113 | t->cbData = cbData; | |
114 | ||
115 | pthread_mutex_lock(&termMutex); | |
116 | termMap[currentPortNum++] = t; | |
117 | retVal = currentPortNum - 1; | |
118 | pthread_mutex_unlock(&termMutex); | |
119 | ||
120 | if(pop_win) | |
121 | t->pop_term(display, fn, bg, fg, title, numScrolLines, exec); | |
122 | ||
123 | *tty_name = strdup(t->tty_name); | |
124 | return retVal; | |
125 | } | |
126 | ||
127 | void console::term_select(){ | |
128 | ||
129 | fd_set readFd; | |
130 | int n; | |
131 | struct timeval tval; | |
132 | //time out every 1 second, to check if additional consoles have been added. | |
133 | tval.tv_sec = 1; | |
134 | tval.tv_usec = 0; | |
135 | ||
136 | for(;;){ | |
137 | FD_ZERO(&readFd); | |
138 | ||
139 | for(termMapIter = termMap.begin(); termMapIter!= termMap.end(); termMapIter++) | |
140 | FD_SET(termMapIter->second->mport_fd, &readFd); | |
141 | ||
142 | n = select(FD_SETSIZE, &readFd, (fd_set *)0,(fd_set *)0, &tval); | |
143 | ||
144 | switch (n) { | |
145 | case -1: /* error */ | |
146 | break; | |
147 | case 0: /* timeout */ | |
148 | break; | |
149 | default: /* input available */ | |
150 | term_read_ports(readFd); | |
151 | break; | |
152 | } | |
153 | } | |
154 | ||
155 | } | |
156 | ||
157 | ||
158 | ||
159 | void * callTermThread(void * arg){ | |
160 | console * t = (console*)arg; | |
161 | t->term_select(); | |
162 | return (void*)0; | |
163 | } |