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

kdesu

kdesu_pty.cpp
00001 /* vi: ts=8 sts=4 sw=4
00002  *
00003  * $Id$
00004  *
00005  * This file is part of the KDE project, module kdesu.
00006  * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org>
00007  *
00008  * This file contains code from TEShell.C of the KDE konsole.
00009  * Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
00010  *
00011  * This is free software; you can use this library under the GNU Library
00012  * General Public License, version 2. See the file "COPYING.LIB" for the
00013  * exact licensing terms.
00014  *
00015  * pty.cpp: Access to PTY's on different systems a la UNIX98.
00016  */
00017 
00018 
00019 #ifndef _GNU_SOURCE
00020 #define _GNU_SOURCE   /* Needed for getpt, ptsname in glibc 2.1.x systems */
00021 #endif
00022 
00023 #include <config.h>
00024 
00025 #include <stdio.h>
00026 #include <fcntl.h>
00027 #include <unistd.h>
00028 #include <string.h>
00029 #include <stdlib.h>
00030 #include <errno.h>
00031 
00032 #include <sys/types.h>
00033 #include <sys/stat.h>
00034 #include <sys/wait.h>
00035 #include <sys/ioctl.h>
00036 #if defined(__osf__) || defined(__CYGWIN__)
00037 #include <pty.h>
00038 #endif
00039 
00040 #include <tqglobal.h>
00041 #include <tqcstring.h>
00042 
00043 #include <kdebug.h>
00044 #include <kstandarddirs.h>
00045 #include "kdesu_pty.h"
00046 
00047 // stdlib.h is meant to declare the prototypes but doesn't :(
00048 #ifndef __THROW
00049 #define __THROW
00050 #endif
00051 
00052 #ifdef HAVE_GRANTPT
00053 extern "C" int grantpt(int fd) __THROW;
00054 #endif
00055 
00056 #ifdef HAVE_PTSNAME
00057 extern "C" char * ptsname(int fd) __THROW;
00058 #endif
00059 
00060 #ifdef HAVE_UNLOCKPT
00061 extern "C" int unlockpt(int fd) __THROW;
00062 #endif
00063 
00064 #ifdef HAVE__GETPTY
00065 extern "C" char *_getpty(int *, int, mode_t, int);
00066 #endif
00067 
00068 #ifdef HAVE_PTY_H
00069     #include <pty.h>
00070 #endif
00071 
00072 #include <termios.h>
00073 
00074 #ifdef HAVE_LIBUTIL_H
00075     #include <libutil.h>
00076 #elif defined(HAVE_UTIL_H)
00077     #include <util.h>
00078 #endif
00079 
00080 PTY::PTY()
00081 {
00082     ptyfd = -1;
00083 }
00084 
00085 PTY::~PTY()
00086 {
00087     if (ptyfd >= 0)
00088     close(ptyfd);
00089 }
00090 
00091 
00092 // Opens a pty master and returns its filedescriptor.
00093 
00094 int PTY::getpt()
00095 {
00096 
00097 #if (defined(HAVE_GETPT) || defined(HAVE_POSIX_OPENPT)) && defined(HAVE_PTSNAME)
00098 
00099     // 1: UNIX98: preferred way
00100 #ifdef HAVE_GETPT
00101     ptyfd = ::getpt();
00102 #elif defined(HAVE_POSIX_OPENPT)
00103     ptyfd = ::posix_openpt(O_RDWR);
00104 #endif
00105     ttyname = ::ptsname(ptyfd);
00106     return ptyfd;
00107 
00108 #elif defined(HAVE_OPENPTY)
00109     // 2: BSD interface
00110     // More preferred than the linux hacks
00111     char name[30];
00112     int master_fd, slave_fd;
00113     if (openpty(&master_fd, &slave_fd, name, 0L, 0L) != -1)  {
00114     ttyname = name;
00115     name[5]='p';
00116     ptyname = name;
00117         close(slave_fd); // We don't need this yet // Yes, we do.
00118     ptyfd = master_fd;
00119     return ptyfd;
00120     }
00121     ptyfd = -1;
00122     kdDebug(900) << k_lineinfo << "Opening pty failed.\n";
00123     return -1;
00124 
00125 #elif defined(HAVE__GETPTY)
00126     // 3: Irix interface
00127     int master_fd;
00128     ttyname = _getpty(&master_fd,O_RDWR,0600,0);
00129     if (ttyname)
00130     ptyfd = master_fd;
00131     else{
00132     ptyfd = -1;
00133     kdDebug(900) << k_lineinfo << "Opening pty failed.error" << errno << '\n';
00134     }
00135     return ptyfd;
00136 
00137 #else
00138 
00139     // 4: Open terminal device directly
00140     // 4.1: Try /dev/ptmx first. (Linux w/ Unix98 PTYs, Solaris)
00141 
00142     ptyfd = open("/dev/ptmx", O_RDWR);
00143     if (ptyfd >= 0) {
00144     ptyname = "/dev/ptmx";
00145 #ifdef HAVE_PTSNAME
00146     ttyname = ::ptsname(ptyfd);
00147     return ptyfd;
00148 #elif defined (TIOCGPTN)
00149     int ptyno;
00150     if (ioctl(ptyfd, TIOCGPTN, &ptyno) == 0) {
00151         ttyname.sprintf("/dev/pts/%d", ptyno);
00152         return ptyfd;
00153     }
00154 #endif
00155     close(ptyfd);
00156     }
00157 
00158     // 4.2: Try /dev/pty[p-e][0-f] (Linux w/o UNIX98 PTY's)
00159 
00160     for (const char *c1 = "pqrstuvwxyzabcde"; *c1 != '\0'; c1++)
00161     {
00162     for (const char *c2 = "0123456789abcdef"; *c2 != '\0'; c2++)
00163     {
00164         ptyname.sprintf("/dev/pty%c%c", *c1, *c2);
00165         ttyname.sprintf("/dev/tty%c%c", *c1, *c2);
00166         if (access(ptyname, F_OK) < 0)
00167         goto linux_out;
00168         ptyfd = open(ptyname, O_RDWR);
00169         if (ptyfd >= 0)
00170         return ptyfd;
00171     }
00172     }
00173 linux_out:
00174 
00175     // 4.3: Try /dev/pty%d (SCO, Unixware)
00176 
00177     for (int i=0; i<256; i++)
00178     {
00179     ptyname.sprintf("/dev/ptyp%d", i);
00180     ttyname.sprintf("/dev/ttyp%d", i);
00181     if (access(ptyname, F_OK) < 0)
00182         break;
00183     ptyfd = open(ptyname, O_RDWR);
00184     if (ptyfd >= 0)
00185         return ptyfd;
00186     }
00187 
00188 
00189     // Other systems ??
00190     ptyfd = -1;
00191     kdDebug(900) << k_lineinfo << "Unknown system or all methods failed.\n";
00192     return -1;
00193 
00194 #endif // HAVE_GETPT && HAVE_PTSNAME
00195 
00196 }
00197 
00198 
00199 int PTY::grantpt()
00200 {
00201     if (ptyfd < 0)
00202     return -1;
00203 
00204 #ifdef HAVE_GRANTPT
00205 
00206     return ::grantpt(ptyfd);
00207 
00208 #elif defined(HAVE_OPENPTY)
00209 
00210     // the BSD openpty() interface chowns the devices properly for us,
00211     // no need to do this at all
00212     return 0;
00213 
00214 #else
00215 
00216     // konsole_grantpty only does /dev/pty??
00217     if (ptyname.left(8) != "/dev/pty")
00218     return 0;
00219 
00220     // Use konsole_grantpty:
00221     if (KStandardDirs::findExe("konsole_grantpty").isEmpty())
00222     {
00223     kdError(900) << k_lineinfo << "konsole_grantpty not found.\n";
00224     return -1;
00225     }
00226 
00227     // As defined in konsole_grantpty.c
00228     const int pty_fileno = 3;
00229 
00230     pid_t pid;
00231     if ((pid = fork()) == -1)
00232     {
00233     kdError(900) << k_lineinfo << "fork(): " << perror << "\n";
00234     return -1;
00235     }
00236 
00237     if (pid)
00238     {
00239     // Parent: wait for child
00240     int ret;
00241     waitpid(pid, &ret, 0);
00242         if (WIFEXITED(ret) && !WEXITSTATUS(ret))
00243         return 0;
00244     kdError(900) << k_lineinfo << "konsole_grantpty returned with error: "
00245              << WEXITSTATUS(ret) << "\n";
00246     return -1;
00247     } else
00248     {
00249     // Child: exec konsole_grantpty
00250     if (ptyfd != pty_fileno && dup2(ptyfd, pty_fileno) < 0)
00251         _exit(1);
00252     execlp("konsole_grantpty", "konsole_grantpty", "--grant", (void *)0);
00253     kdError(900) << k_lineinfo << "exec(): " << perror << "\n";
00254     _exit(1);
00255     }
00256 
00257     // shut up, gcc
00258     return 0;
00259 
00260 #endif // HAVE_GRANTPT
00261 }
00262 
00263 
00268 int PTY::unlockpt()
00269 {
00270     if (ptyfd < 0)
00271     return -1;
00272 
00273 #ifdef HAVE_UNLOCKPT
00274 
00275     // (Linux w/ glibc 2.1, Solaris, ...)
00276 
00277     return ::unlockpt(ptyfd);
00278 
00279 #elif defined(TIOCSPTLCK)
00280 
00281     // Unlock pty (Linux w/ UNIX98 PTY's & glibc 2.0)
00282     int flag = 0;
00283     return ioctl(ptyfd, TIOCSPTLCK, &flag);
00284 
00285 #else
00286 
00287     // Other systems (Linux w/o UNIX98 PTY's, ...)
00288     return 0;
00289 
00290 #endif
00291 
00292 }
00293 
00294 
00299 TQCString PTY::ptsname()
00300 {
00301     if (ptyfd < 0)
00302     return 0;
00303 
00304     return ttyname;
00305 }
00306 

kdesu

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

kdesu

Skip menu "kdesu"
  • arts
  • dcop
  • dnssd
  • interfaces
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kdesu by doxygen 1.7.6.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |