• 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(__osf__) || defined(__CYGWIN__)
37 #include <pty.h>
38 #endif
39 
40 #include <tqglobal.h>
41 #include <tqcstring.h>
42 
43 #include <kdebug.h>
44 #include <kstandarddirs.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
53 extern "C" int grantpt(int fd) __THROW;
54 #endif
55 
56 #ifdef HAVE_PTSNAME
57 extern "C" char * ptsname(int fd) __THROW;
58 #endif
59 
60 #ifdef HAVE_UNLOCKPT
61 extern "C" int unlockpt(int fd) __THROW;
62 #endif
63 
64 #ifdef HAVE__GETPTY
65 extern "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 
80 PTY::PTY()
81 {
82  ptyfd = -1;
83 }
84 
85 PTY::~PTY()
86 {
87  if (ptyfd >= 0)
88  close(ptyfd);
89 }
90 
91 
92 // Opens a pty master and returns its filedescriptor.
93 
94 int 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  }
173 linux_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 
199 int 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 
268 int 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 
299 TQCString PTY::ptsname()
300 {
301  if (ptyfd < 0)
302  return 0;
303 
304  return ttyname;
305 }
306 
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::getpt
int getpt()
Allocate a pty.
Definition: tdesu_pty.cpp:94
PTY::~PTY
~PTY()
Destructs the object.
Definition: tdesu_pty.cpp:85
PTY::ptsname
TQCString ptsname()
Get the slave name.
Definition: tdesu_pty.cpp:299
PTY::unlockpt
int unlockpt()
Unlock the slave side.
Definition: tdesu_pty.cpp:268

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdesu by doxygen 1.8.8
This website is maintained by Timothy Pearson.