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

tdesu

  • tdesu
tdesu_pty.cpp
1 /* vi: ts=8 sts=4 sw=4
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_PTSNAME)
98 
99  // 1: UNIX98: preferred way
100  ptyfd = ::getpt();
101  ttyname = ::ptsname(ptyfd);
102  return ptyfd;
103 
104 #elif defined(HAVE_OPENPTY)
105  // 2: BSD interface
106  // More preferred than the linux hacks
107  char name[30];
108  int master_fd, slave_fd;
109  if (openpty(&master_fd, &slave_fd, name, 0L, 0L) != -1) {
110  ttyname = name;
111  name[5]='p';
112  ptyname = name;
113  close(slave_fd); // We don't need this yet // Yes, we do.
114  ptyfd = master_fd;
115  return ptyfd;
116  }
117  ptyfd = -1;
118  kdDebug(900) << k_lineinfo << "Opening pty failed.\n";
119  return -1;
120 
121 #elif defined(HAVE__GETPTY)
122  // 3: Irix interface
123  int master_fd;
124  ttyname = _getpty(&master_fd,O_RDWR,0600,0);
125  if (ttyname)
126  ptyfd = master_fd;
127  else{
128  ptyfd = -1;
129  kdDebug(900) << k_lineinfo << "Opening pty failed.error" << errno << '\n';
130  }
131  return ptyfd;
132 
133 #else
134 
135  // 4: Open terminal device directly
136  // 4.1: Try /dev/ptmx first. (Linux w/ Unix98 PTYs, Solaris)
137 
138  ptyfd = open("/dev/ptmx", O_RDWR);
139  if (ptyfd >= 0) {
140  ptyname = "/dev/ptmx";
141 #ifdef HAVE_PTSNAME
142  ttyname = ::ptsname(ptyfd);
143  return ptyfd;
144 #elif defined (TIOCGPTN)
145  int ptyno;
146  if (ioctl(ptyfd, TIOCGPTN, &ptyno) == 0) {
147  ttyname.sprintf("/dev/pts/%d", ptyno);
148  return ptyfd;
149  }
150 #endif
151  close(ptyfd);
152  }
153 
154  // 4.2: Try /dev/pty[p-e][0-f] (Linux w/o UNIX98 PTY's)
155 
156  for (const char *c1 = "pqrstuvwxyzabcde"; *c1 != '\0'; c1++)
157  {
158  for (const char *c2 = "0123456789abcdef"; *c2 != '\0'; c2++)
159  {
160  ptyname.sprintf("/dev/pty%c%c", *c1, *c2);
161  ttyname.sprintf("/dev/tty%c%c", *c1, *c2);
162  if (access(ptyname, F_OK) < 0)
163  goto linux_out;
164  ptyfd = open(ptyname, O_RDWR);
165  if (ptyfd >= 0)
166  return ptyfd;
167  }
168  }
169 linux_out:
170 
171  // 4.3: Try /dev/pty%d (SCO, Unixware)
172 
173  for (int i=0; i<256; i++)
174  {
175  ptyname.sprintf("/dev/ptyp%d", i);
176  ttyname.sprintf("/dev/ttyp%d", i);
177  if (access(ptyname, F_OK) < 0)
178  break;
179  ptyfd = open(ptyname, O_RDWR);
180  if (ptyfd >= 0)
181  return ptyfd;
182  }
183 
184 
185  // Other systems ??
186  ptyfd = -1;
187  kdDebug(900) << k_lineinfo << "Unknown system or all methods failed.\n";
188  return -1;
189 
190 #endif // HAVE_GETPT && HAVE_PTSNAME
191 
192 }
193 
194 
195 int PTY::grantpt()
196 {
197  if (ptyfd < 0)
198  return -1;
199 
200 #ifdef HAVE_GRANTPT
201 
202  return ::grantpt(ptyfd);
203 
204 #elif defined(HAVE_OPENPTY)
205 
206  // the BSD openpty() interface chowns the devices properly for us,
207  // no need to do this at all
208  return 0;
209 
210 #else
211 
212  // konsole_grantpty only does /dev/pty??
213  if (ptyname.left(8) != "/dev/pty")
214  return 0;
215 
216  // Use konsole_grantpty:
217  if (TDEStandardDirs::findExe("konsole_grantpty").isEmpty())
218  {
219  kdError(900) << k_lineinfo << "konsole_grantpty not found.\n";
220  return -1;
221  }
222 
223  // As defined in konsole_grantpty.c
224  const int pty_fileno = 3;
225 
226  pid_t pid;
227  if ((pid = fork()) == -1)
228  {
229  kdError(900) << k_lineinfo << "fork(): " << perror << "\n";
230  return -1;
231  }
232 
233  if (pid)
234  {
235  // Parent: wait for child
236  int ret;
237  waitpid(pid, &ret, 0);
238  if (WIFEXITED(ret) && !WEXITSTATUS(ret))
239  return 0;
240  kdError(900) << k_lineinfo << "konsole_grantpty returned with error: "
241  << WEXITSTATUS(ret) << "\n";
242  return -1;
243  } else
244  {
245  // Child: exec konsole_grantpty
246  if (ptyfd != pty_fileno && dup2(ptyfd, pty_fileno) < 0)
247  _exit(1);
248  execlp("konsole_grantpty", "konsole_grantpty", "--grant", (void *)0);
249  kdError(900) << k_lineinfo << "exec(): " << perror << "\n";
250  _exit(1);
251  }
252 
253  // shut up, gcc
254  return 0;
255 
256 #endif // HAVE_GRANTPT
257 }
258 
259 
264 int PTY::unlockpt()
265 {
266  if (ptyfd < 0)
267  return -1;
268 
269 #ifdef HAVE_UNLOCKPT
270 
271  // (Linux w/ glibc 2.1, Solaris, ...)
272 
273  return ::unlockpt(ptyfd);
274 
275 #elif defined(TIOCSPTLCK)
276 
277  // Unlock pty (Linux w/ UNIX98 PTY's & glibc 2.0)
278  int flag = 0;
279  return ioctl(ptyfd, TIOCSPTLCK, &flag);
280 
281 #else
282 
283  // Other systems (Linux w/o UNIX98 PTY's, ...)
284  return 0;
285 
286 #endif
287 
288 }
289 
290 
295 TQCString PTY::ptsname()
296 {
297  if (ptyfd < 0)
298  return 0;
299 
300  return ttyname;
301 }
302 

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.8.1.2
This website is maintained by Timothy Pearson.