-rw-r--r-- | noncore/apps/opie-console/MyPty.cpp | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/noncore/apps/opie-console/MyPty.cpp b/noncore/apps/opie-console/MyPty.cpp index 984e347..2570826 100644 --- a/noncore/apps/opie-console/MyPty.cpp +++ b/noncore/apps/opie-console/MyPty.cpp | |||
@@ -22,171 +22,177 @@ | |||
22 | 22 | ||
23 | /*! \file | 23 | /*! \file |
24 | */ | 24 | */ |
25 | 25 | ||
26 | /*! \class TEPty | 26 | /*! \class TEPty |
27 | 27 | ||
28 | \brief Ptys provide a pseudo terminal connection to a program. | 28 | \brief Ptys provide a pseudo terminal connection to a program. |
29 | 29 | ||
30 | Although closely related to pipes, these pseudo terminal connections have | 30 | Although closely related to pipes, these pseudo terminal connections have |
31 | some ability, that makes it nessesary to uses them. Most importent, they | 31 | some ability, that makes it nessesary to uses them. Most importent, they |
32 | know about changing screen sizes and UNIX job control. | 32 | know about changing screen sizes and UNIX job control. |
33 | 33 | ||
34 | Within the terminal emulation framework, this class represents the | 34 | Within the terminal emulation framework, this class represents the |
35 | host side of the terminal together with the connecting serial line. | 35 | host side of the terminal together with the connecting serial line. |
36 | 36 | ||
37 | One can create many instances of this class within a program. | 37 | One can create many instances of this class within a program. |
38 | As a side effect of using this class, a signal(2) handler is | 38 | As a side effect of using this class, a signal(2) handler is |
39 | installed on SIGCHLD. | 39 | installed on SIGCHLD. |
40 | 40 | ||
41 | \par FIXME | 41 | \par FIXME |
42 | 42 | ||
43 | [NOTE: much of the technical stuff below will be replaced by forkpty.] | 43 | [NOTE: much of the technical stuff below will be replaced by forkpty.] |
44 | 44 | ||
45 | publish the SIGCHLD signal if not related to an instance. | 45 | publish the SIGCHLD signal if not related to an instance. |
46 | 46 | ||
47 | clearify TEPty::done vs. TEPty::~TEPty semantics. | 47 | clearify TEPty::done vs. TEPty::~TEPty semantics. |
48 | check if pty is restartable via run after done. | 48 | check if pty is restartable via run after done. |
49 | 49 | ||
50 | \par Pseudo terminals | 50 | \par Pseudo terminals |
51 | 51 | ||
52 | Pseudo terminals are a unique feature of UNIX, and always come in form of | 52 | Pseudo terminals are a unique feature of UNIX, and always come in form of |
53 | pairs of devices (/dev/ptyXX and /dev/ttyXX), which are connected to each | 53 | pairs of devices (/dev/ptyXX and /dev/ttyXX), which are connected to each |
54 | other by the operating system. One may think of them as two serial devices | 54 | other by the operating system. One may think of them as two serial devices |
55 | linked by a null-modem cable. Being based on devices the number of | 55 | linked by a null-modem cable. Being based on devices the number of |
56 | simultanous instances of this class is (globally) limited by the number of | 56 | simultanous instances of this class is (globally) limited by the number of |
57 | those device pairs, which is 256. | 57 | those device pairs, which is 256. |
58 | 58 | ||
59 | Another technic are UNIX 98 PTY's. These are supported also, and prefered | 59 | Another technic are UNIX 98 PTY's. These are supported also, and prefered |
60 | over the (obsolete) predecessor. | 60 | over the (obsolete) predecessor. |
61 | 61 | ||
62 | There's a sinister ioctl(2), signal(2) and job control stuff | 62 | There's a sinister ioctl(2), signal(2) and job control stuff |
63 | nessesary to make everything work as it should. | 63 | nessesary to make everything work as it should. |
64 | */ | 64 | */ |
65 | 65 | ||
66 | 66 | ||
67 | #include <qapplication.h> | 67 | #include <qapplication.h> |
68 | #include <qsocketnotifier.h> | 68 | #include <qsocketnotifier.h> |
69 | #include <qstring.h> | 69 | #include <qstring.h> |
70 | #include <qfile.h> | ||
70 | 71 | ||
71 | #include <stdlib.h> | 72 | #include <stdlib.h> |
72 | #include <stdio.h> | 73 | #include <stdio.h> |
73 | #include <signal.h> | 74 | #include <signal.h> |
74 | #include <fcntl.h> | 75 | #include <fcntl.h> |
75 | #include <unistd.h> | 76 | #include <unistd.h> |
76 | #include <termios.h> | 77 | #include <termios.h> |
77 | #include <sys/types.h> | 78 | #include <sys/types.h> |
78 | #include <sys/ioctl.h> | 79 | #include <sys/ioctl.h> |
79 | #include <sys/wait.h> | 80 | #include <sys/wait.h> |
80 | 81 | ||
81 | #ifdef HAVE_OPENPTY | 82 | #ifdef HAVE_OPENPTY |
82 | #include <pty.h> | 83 | #include <pty.h> |
83 | #endif | 84 | #endif |
84 | 85 | ||
85 | #include "procctl.h" | 86 | #include "procctl.h" |
86 | #include "MyPty.h" | 87 | #include "MyPty.h" |
87 | 88 | ||
88 | 89 | ||
89 | #undef VERBOSE_DEBUG | 90 | #undef VERBOSE_DEBUG |
90 | 91 | ||
91 | 92 | ||
92 | /* -------------------------------------------------------------------------- */ | 93 | /* -------------------------------------------------------------------------- */ |
93 | 94 | ||
94 | /*! | 95 | /*! |
95 | Informs the client program about the | 96 | Informs the client program about the |
96 | actual size of the window. | 97 | actual size of the window. |
97 | */ | 98 | */ |
98 | 99 | ||
99 | void MyPty::setSize(int lines, int columns) | 100 | void MyPty::setSize(int lines, int columns) |
100 | { | 101 | { |
101 | qWarning("setting size"); | 102 | qWarning("setting size"); |
102 | struct winsize wsize; | 103 | struct winsize wsize; |
103 | wsize.ws_row = (unsigned short)lines; | 104 | wsize.ws_row = (unsigned short)lines; |
104 | wsize.ws_col = (unsigned short)columns; | 105 | wsize.ws_col = (unsigned short)columns; |
105 | if(m_fd < 0) return; | 106 | if(m_fd < 0) return; |
106 | ioctl(m_fd,TIOCSWINSZ,(char *)&wsize); | 107 | ioctl(m_fd,TIOCSWINSZ,(char *)&wsize); |
107 | } | 108 | } |
108 | 109 | ||
109 | 110 | ||
110 | void MyPty::donePty() | 111 | void MyPty::donePty() |
111 | { | 112 | { |
112 | // This is code from the Qt DumbTerminal example | 113 | // This is code from the Qt DumbTerminal example |
113 | 114 | ||
114 | ::close(m_fd); | 115 | ::close(m_fd); |
115 | 116 | ||
116 | if (m_cpid) { | 117 | if (m_cpid) { |
117 | kill(m_cpid, SIGHUP); | 118 | kill(m_cpid, SIGHUP); |
118 | //waitpid(m_cpid, &status, 0); | 119 | //waitpid(m_cpid, &status, 0); |
119 | delete m_sn_e; | 120 | delete m_sn_e; |
120 | delete m_sn_r; | 121 | delete m_sn_r; |
121 | m_sn_e = 0l; | 122 | m_sn_e = 0l; |
122 | m_sn_r = 0l; | 123 | m_sn_r = 0l; |
123 | } | 124 | } |
124 | 125 | ||
125 | m_cpid = 0; | 126 | m_cpid = 0; |
126 | m_fd = -1; | 127 | m_fd = -1; |
127 | // emit done(status); | 128 | // emit done(status); |
128 | } | 129 | } |
129 | 130 | ||
130 | 131 | ||
131 | const char* MyPty::deviceName() | 132 | const char* MyPty::deviceName() |
132 | { | 133 | { |
133 | return m_ttynam; | 134 | return m_ttynam; |
134 | } | 135 | } |
135 | 136 | ||
136 | 137 | ||
137 | void MyPty::error() | 138 | void MyPty::error() |
138 | { | 139 | { |
139 | // This is code from the Qt DumbTerminal example | 140 | // This is code from the Qt DumbTerminal example |
140 | donePty(); | 141 | donePty(); |
141 | } | 142 | } |
142 | 143 | ||
143 | void MyPty::start() { | 144 | void MyPty::start() { |
144 | char* cmd = "/bin/sh"; | 145 | char* cmd = "/bin/sh"; |
146 | |||
147 | if ( QFile::exists( "/bin/bash" ) ) { | ||
148 | char* cmd = "/bin/bash"; | ||
149 | } | ||
150 | |||
145 | QStrList lis; | 151 | QStrList lis; |
146 | int r =run(cmd, lis, 0, 0); | 152 | int r =run(cmd, lis, 0, 0); |
147 | r = r; | 153 | r = r; |
148 | } | 154 | } |
149 | /*! | 155 | /*! |
150 | start the client program. | 156 | start the client program. |
151 | */ | 157 | */ |
152 | int MyPty::run(const char* cmd, QStrList &, const char*, int) | 158 | int MyPty::run(const char* cmd, QStrList &, const char*, int) |
153 | { | 159 | { |
154 | // This is code from the Qt DumbTerminal example | 160 | // This is code from the Qt DumbTerminal example |
155 | m_cpid = fork(); | 161 | m_cpid = fork(); |
156 | 162 | ||
157 | if ( !m_cpid ) { | 163 | if ( !m_cpid ) { |
158 | // child - exec shell on tty | 164 | // child - exec shell on tty |
159 | for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL); | 165 | for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL); |
160 | int ttyfd = ::open(m_ttynam, O_RDWR); | 166 | int ttyfd = ::open(m_ttynam, O_RDWR); |
161 | dup2(ttyfd, STDIN_FILENO); | 167 | dup2(ttyfd, STDIN_FILENO); |
162 | dup2(ttyfd, STDOUT_FILENO); | 168 | dup2(ttyfd, STDOUT_FILENO); |
163 | dup2(ttyfd, STDERR_FILENO); | 169 | dup2(ttyfd, STDERR_FILENO); |
164 | // should be done with tty, so close it | 170 | // should be done with tty, so close it |
165 | ::close(ttyfd); | 171 | ::close(ttyfd); |
166 | static struct termios ttmode; | 172 | static struct termios ttmode; |
167 | if ( setsid() < 0 ) | 173 | if ( setsid() < 0 ) |
168 | perror( "failed to set process group" ); | 174 | perror( "failed to set process group" ); |
169 | #if defined (TIOCSCTTY) | 175 | #if defined (TIOCSCTTY) |
170 | // grabbed from APUE by Stevens | 176 | // grabbed from APUE by Stevens |
171 | ioctl(STDIN_FILENO, TIOCSCTTY, 0); | 177 | ioctl(STDIN_FILENO, TIOCSCTTY, 0); |
172 | #endif | 178 | #endif |
173 | tcgetattr( STDIN_FILENO, &ttmode ); | 179 | tcgetattr( STDIN_FILENO, &ttmode ); |
174 | ttmode.c_cc[VINTR] = 3; | 180 | ttmode.c_cc[VINTR] = 3; |
175 | ttmode.c_cc[VERASE] = 8; | 181 | ttmode.c_cc[VERASE] = 8; |
176 | tcsetattr( STDIN_FILENO, TCSANOW, &ttmode ); | 182 | tcsetattr( STDIN_FILENO, TCSANOW, &ttmode ); |
177 | setenv("TERM",m_term,1); | 183 | setenv("TERM",m_term,1); |
178 | setenv("COLORTERM","0",1); | 184 | setenv("COLORTERM","0",1); |
179 | 185 | ||
180 | if (getuid() == 0) { | 186 | if (getuid() == 0) { |
181 | char msg[] = "WARNING: You are running this shell as root!\n"; | 187 | char msg[] = "WARNING: You are running this shell as root!\n"; |
182 | write(ttyfd, msg, sizeof(msg)); | 188 | write(ttyfd, msg, sizeof(msg)); |
183 | } | 189 | } |
184 | execl(cmd, cmd, 0); | 190 | execl(cmd, cmd, 0); |
185 | 191 | ||
186 | donePty(); | 192 | donePty(); |
187 | exit(-1); | 193 | exit(-1); |
188 | } | 194 | } |
189 | 195 | ||
190 | // parent - continue as a widget | 196 | // parent - continue as a widget |
191 | delete m_sn_r; | 197 | delete m_sn_r; |
192 | m_sn_r = new QSocketNotifier(m_fd,QSocketNotifier::Read,this); | 198 | m_sn_r = new QSocketNotifier(m_fd,QSocketNotifier::Read,this); |