• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdesu
 

tdesu

  • tdesu
tdesu_pty.cpp
1/*
2 *
3 * $Id$
4 *
5 * This file is part of the KDE project, module tdesu.
6 * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
7 *
8 * This file contains code from TEShell.C of the KDE konsole.
9 * Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
10 *
11 * This is free software; you can use this library under the GNU Library
12 * General Public License, version 2. See the file "COPYING.LIB" for the
13 * exact licensing terms.
14 *
15 * pty.cpp: Access to PTY's on different systems a la UNIX98.
16 */
17
18
19#ifndef _GNU_SOURCE
20#define _GNU_SOURCE /* Needed for getpt, ptsname in glibc 2.1.x systems */
21#endif
22
23#include <config.h>
24
25#include <stdio.h>
26#include <fcntl.h>
27#include <unistd.h>
28#include <string.h>
29#include <stdlib.h>
30#include <errno.h>
31
32#include <sys/types.h>
33#include <sys/stat.h>
34#include <sys/wait.h>
35#include <sys/ioctl.h>
36#if defined(__CYGWIN__)
37#include <pty.h>
38#endif
39
40#include <tqglobal.h>
41#include <tqcstring.h>
42
43#include <kdebug.h>
44#include <tdestandarddirs.h>
45#include "tdesu_pty.h"
46
47// stdlib.h is meant to declare the prototypes but doesn't :(
48#ifndef __THROW
49#define __THROW
50#endif
51
52#ifdef HAVE_GRANTPT
53extern "C" int grantpt(int fd) __THROW;
54#endif
55
56#ifdef HAVE_PTSNAME
57extern "C" char * ptsname(int fd) __THROW;
58#endif
59
60#ifdef HAVE_UNLOCKPT
61extern "C" int unlockpt(int fd) __THROW;
62#endif
63
64#ifdef HAVE__GETPTY
65extern "C" char *_getpty(int *, int, mode_t, int);
66#endif
67
68#ifdef HAVE_PTY_H
69 #include <pty.h>
70#endif
71
72#include <termios.h>
73
74#ifdef HAVE_LIBUTIL_H
75 #include <libutil.h>
76#elif defined(HAVE_UTIL_H)
77 #include <util.h>
78#endif
79
80PTY::PTY()
81{
82 ptyfd = -1;
83}
84
85PTY::~PTY()
86{
87 if (ptyfd >= 0)
88 close(ptyfd);
89}
90
91
92// Opens a pty master and returns its filedescriptor.
93
94int PTY::getpt()
95{
96
97#if (defined(HAVE_GETPT) || defined(HAVE_POSIX_OPENPT)) && defined(HAVE_PTSNAME)
98
99 // 1: UNIX98: preferred way
100#ifdef HAVE_GETPT
101 ptyfd = ::getpt();
102#elif defined(HAVE_POSIX_OPENPT)
103 ptyfd = ::posix_openpt(O_RDWR);
104#endif
105 ttyname = ::ptsname(ptyfd);
106 return ptyfd;
107
108#elif defined(HAVE_OPENPTY)
109 // 2: BSD interface
110 // More preferred than the linux hacks
111 char name[30];
112 int master_fd, slave_fd;
113 if (openpty(&master_fd, &slave_fd, name, 0L, 0L) != -1) {
114 ttyname = name;
115 name[5]='p';
116 ptyname = name;
117 close(slave_fd); // We don't need this yet // Yes, we do.
118 ptyfd = master_fd;
119 return ptyfd;
120 }
121 ptyfd = -1;
122 kdDebug(900) << k_lineinfo << "Opening pty failed.\n";
123 return -1;
124
125#elif defined(HAVE__GETPTY)
126 // 3: Irix interface
127 int master_fd;
128 ttyname = _getpty(&master_fd,O_RDWR,0600,0);
129 if (ttyname)
130 ptyfd = master_fd;
131 else{
132 ptyfd = -1;
133 kdDebug(900) << k_lineinfo << "Opening pty failed.error" << errno << '\n';
134 }
135 return ptyfd;
136
137#else
138
139 // 4: Open terminal device directly
140 // 4.1: Try /dev/ptmx first. (Linux w/ Unix98 PTYs, Solaris)
141
142 ptyfd = open("/dev/ptmx", O_RDWR);
143 if (ptyfd >= 0) {
144 ptyname = "/dev/ptmx";
145#ifdef HAVE_PTSNAME
146 ttyname = ::ptsname(ptyfd);
147 return ptyfd;
148#elif defined (TIOCGPTN)
149 int ptyno;
150 if (ioctl(ptyfd, TIOCGPTN, &ptyno) == 0) {
151 ttyname.sprintf("/dev/pts/%d", ptyno);
152 return ptyfd;
153 }
154#endif
155 close(ptyfd);
156 }
157
158 // 4.2: Try /dev/pty[p-e][0-f] (Linux w/o UNIX98 PTY's)
159
160 for (const char *c1 = "pqrstuvwxyzabcde"; *c1 != '\0'; c1++)
161 {
162 for (const char *c2 = "0123456789abcdef"; *c2 != '\0'; c2++)
163 {
164 ptyname.sprintf("/dev/pty%c%c", *c1, *c2);
165 ttyname.sprintf("/dev/tty%c%c", *c1, *c2);
166 if (access(ptyname, F_OK) < 0)
167 goto linux_out;
168 ptyfd = open(ptyname, O_RDWR);
169 if (ptyfd >= 0)
170 return ptyfd;
171 }
172 }
173linux_out:
174
175 // 4.3: Try /dev/pty%d (SCO, Unixware)
176
177 for (int i=0; i<256; i++)
178 {
179 ptyname.sprintf("/dev/ptyp%d", i);
180 ttyname.sprintf("/dev/ttyp%d", i);
181 if (access(ptyname, F_OK) < 0)
182 break;
183 ptyfd = open(ptyname, O_RDWR);
184 if (ptyfd >= 0)
185 return ptyfd;
186 }
187
188
189 // Other systems ??
190 ptyfd = -1;
191 kdDebug(900) << k_lineinfo << "Unknown system or all methods failed.\n";
192 return -1;
193
194#endif // HAVE_GETPT && HAVE_PTSNAME
195
196}
197
198
199int PTY::grantpt()
200{
201 if (ptyfd < 0)
202 return -1;
203
204#ifdef HAVE_GRANTPT
205
206 return ::grantpt(ptyfd);
207
208#elif defined(HAVE_OPENPTY)
209
210 // the BSD openpty() interface chowns the devices properly for us,
211 // no need to do this at all
212 return 0;
213
214#else
215
216 // konsole_grantpty only does /dev/pty??
217 if (ptyname.left(8) != "/dev/pty")
218 return 0;
219
220 // Use konsole_grantpty:
221 if (TDEStandardDirs::findExe("konsole_grantpty").isEmpty())
222 {
223 kdError(900) << k_lineinfo << "konsole_grantpty not found.\n";
224 return -1;
225 }
226
227 // As defined in konsole_grantpty.c
228 const int pty_fileno = 3;
229
230 pid_t pid;
231 if ((pid = fork()) == -1)
232 {
233 kdError(900) << k_lineinfo << "fork(): " << perror << "\n";
234 return -1;
235 }
236
237 if (pid)
238 {
239 // Parent: wait for child
240 int ret;
241 waitpid(pid, &ret, 0);
242 if (WIFEXITED(ret) && !WEXITSTATUS(ret))
243 return 0;
244 kdError(900) << k_lineinfo << "konsole_grantpty returned with error: "
245 << WEXITSTATUS(ret) << "\n";
246 return -1;
247 } else
248 {
249 // Child: exec konsole_grantpty
250 if (ptyfd != pty_fileno && dup2(ptyfd, pty_fileno) < 0)
251 _exit(1);
252 execlp("konsole_grantpty", "konsole_grantpty", "--grant", (void *)0);
253 kdError(900) << k_lineinfo << "exec(): " << perror << "\n";
254 _exit(1);
255 }
256
257 // shut up, gcc
258 return 0;
259
260#endif // HAVE_GRANTPT
261}
262
263
268int PTY::unlockpt()
269{
270 if (ptyfd < 0)
271 return -1;
272
273#ifdef HAVE_UNLOCKPT
274
275 // (Linux w/ glibc 2.1, Solaris, ...)
276
277 return ::unlockpt(ptyfd);
278
279#elif defined(TIOCSPTLCK)
280
281 // Unlock pty (Linux w/ UNIX98 PTY's & glibc 2.0)
282 int flag = 0;
283 return ioctl(ptyfd, TIOCSPTLCK, &flag);
284
285#else
286
287 // Other systems (Linux w/o UNIX98 PTY's, ...)
288 return 0;
289
290#endif
291
292}
293
294
299TQCString PTY::ptsname()
300{
301 if (ptyfd < 0)
302 return 0;
303
304 return ttyname;
305}
306
PTY::unlockpt
int unlockpt()
Unlock the slave side.
Definition: tdesu_pty.cpp:268
PTY::PTY
PTY()
Construct a PTY object.
Definition: tdesu_pty.cpp:80
PTY::grantpt
int grantpt()
Grant access to the slave side.
Definition: tdesu_pty.cpp:199
PTY::ptsname
TQCString ptsname()
Get the slave name.
Definition: tdesu_pty.cpp:299
PTY::~PTY
~PTY()
Destructs the object.
Definition: tdesu_pty.cpp:85
PTY::getpt
int getpt()
Allocate a pty.
Definition: tdesu_pty.cpp:94

tdesu

Skip menu "tdesu"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

tdesu

Skip menu "tdesu"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdesu by doxygen 1.9.4
This website is maintained by Timothy Pearson.