• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

KDEsu

kdesu_pty.cpp

Go to the documentation of this file.
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 <qglobal.h>
00041 #include <qcstring.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_PTSNAME)
00098 
00099     // 1: UNIX98: preferred way
00100     ptyfd = ::getpt();
00101     ttyname = ::ptsname(ptyfd);
00102     return ptyfd;
00103 
00104 #elif defined(HAVE_OPENPTY)
00105     // 2: BSD interface
00106     // More preferred than the linux hacks
00107     char name[30];
00108     int master_fd, slave_fd;
00109     if (openpty(&master_fd, &slave_fd, name, 0L, 0L) != -1)  {
00110     ttyname = name;
00111     name[5]='p';
00112     ptyname = name;
00113         close(slave_fd); // We don't need this yet // Yes, we do.
00114     ptyfd = master_fd;
00115     return ptyfd;
00116     }
00117     ptyfd = -1;
00118     kdDebug(900) << k_lineinfo << "Opening pty failed.\n";
00119     return -1;
00120 
00121 #elif defined(HAVE__GETPTY)
00122     // 3: Irix interface
00123     int master_fd;
00124     ttyname = _getpty(&master_fd,O_RDWR,0600,0);
00125     if (ttyname)
00126     ptyfd = master_fd;
00127     else{
00128     ptyfd = -1;
00129     kdDebug(900) << k_lineinfo << "Opening pty failed.error" << errno << '\n';
00130     }
00131     return ptyfd;
00132 
00133 #else
00134 
00135     // 4: Open terminal device directly
00136     // 4.1: Try /dev/ptmx first. (Linux w/ Unix98 PTYs, Solaris)
00137 
00138     ptyfd = open("/dev/ptmx", O_RDWR);
00139     if (ptyfd >= 0) {
00140     ptyname = "/dev/ptmx";
00141 #ifdef HAVE_PTSNAME
00142     ttyname = ::ptsname(ptyfd);
00143     return ptyfd;
00144 #elif defined (TIOCGPTN)
00145     int ptyno;
00146     if (ioctl(ptyfd, TIOCGPTN, &ptyno) == 0) {
00147         ttyname.sprintf("/dev/pts/%d", ptyno);
00148         return ptyfd;
00149     }
00150 #endif
00151     close(ptyfd);
00152     }
00153 
00154     // 4.2: Try /dev/pty[p-e][0-f] (Linux w/o UNIX98 PTY's)
00155 
00156     for (const char *c1 = "pqrstuvwxyzabcde"; *c1 != '\0'; c1++)
00157     {
00158     for (const char *c2 = "0123456789abcdef"; *c2 != '\0'; c2++)
00159     {
00160         ptyname.sprintf("/dev/pty%c%c", *c1, *c2);
00161         ttyname.sprintf("/dev/tty%c%c", *c1, *c2);
00162         if (access(ptyname, F_OK) < 0)
00163         goto linux_out;
00164         ptyfd = open(ptyname, O_RDWR);
00165         if (ptyfd >= 0)
00166         return ptyfd;
00167     }
00168     }
00169 linux_out:
00170 
00171     // 4.3: Try /dev/pty%d (SCO, Unixware)
00172 
00173     for (int i=0; i<256; i++)
00174     {
00175     ptyname.sprintf("/dev/ptyp%d", i);
00176     ttyname.sprintf("/dev/ttyp%d", i);
00177     if (access(ptyname, F_OK) < 0)
00178         break;
00179     ptyfd = open(ptyname, O_RDWR);
00180     if (ptyfd >= 0)
00181         return ptyfd;
00182     }
00183 
00184 
00185     // Other systems ??
00186     ptyfd = -1;
00187     kdDebug(900) << k_lineinfo << "Unknown system or all methods failed.\n";
00188     return -1;
00189 
00190 #endif // HAVE_GETPT && HAVE_PTSNAME
00191 
00192 }
00193 
00194 
00195 int PTY::grantpt()
00196 {
00197     if (ptyfd < 0)
00198     return -1;
00199 
00200 #ifdef HAVE_GRANTPT
00201 
00202     return ::grantpt(ptyfd);
00203 
00204 #elif defined(HAVE_OPENPTY)
00205 
00206     // the BSD openpty() interface chowns the devices properly for us,
00207     // no need to do this at all
00208     return 0;
00209 
00210 #else
00211 
00212     // konsole_grantpty only does /dev/pty??
00213     if (ptyname.left(8) != "/dev/pty")
00214     return 0;
00215 
00216     // Use konsole_grantpty:
00217     if (KStandardDirs::findExe("konsole_grantpty").isEmpty())
00218     {
00219     kdError(900) << k_lineinfo << "konsole_grantpty not found.\n";
00220     return -1;
00221     }
00222 
00223     // As defined in konsole_grantpty.c
00224     const int pty_fileno = 3;
00225 
00226     pid_t pid;
00227     if ((pid = fork()) == -1)
00228     {
00229     kdError(900) << k_lineinfo << "fork(): " << perror << "\n";
00230     return -1;
00231     }
00232 
00233     if (pid)
00234     {
00235     // Parent: wait for child
00236     int ret;
00237     waitpid(pid, &ret, 0);
00238         if (WIFEXITED(ret) && !WEXITSTATUS(ret))
00239         return 0;
00240     kdError(900) << k_lineinfo << "konsole_grantpty returned with error: "
00241              << WEXITSTATUS(ret) << "\n";
00242     return -1;
00243     } else
00244     {
00245     // Child: exec konsole_grantpty
00246     if (ptyfd != pty_fileno && dup2(ptyfd, pty_fileno) < 0)
00247         _exit(1);
00248     execlp("konsole_grantpty", "konsole_grantpty", "--grant", (void *)0);
00249     kdError(900) << k_lineinfo << "exec(): " << perror << "\n";
00250     _exit(1);
00251     }
00252 
00253     // shut up, gcc
00254     return 0;
00255 
00256 #endif // HAVE_GRANTPT
00257 }
00258 
00259 
00264 int PTY::unlockpt()
00265 {
00266     if (ptyfd < 0)
00267     return -1;
00268 
00269 #ifdef HAVE_UNLOCKPT
00270 
00271     // (Linux w/ glibc 2.1, Solaris, ...)
00272 
00273     return ::unlockpt(ptyfd);
00274 
00275 #elif defined(TIOCSPTLCK)
00276 
00277     // Unlock pty (Linux w/ UNIX98 PTY's & glibc 2.0)
00278     int flag = 0;
00279     return ioctl(ptyfd, TIOCSPTLCK, &flag);
00280 
00281 #else
00282 
00283     // Other systems (Linux w/o UNIX98 PTY's, ...)
00284     return 0;
00285 
00286 #endif
00287 
00288 }
00289 
00290 
00295 QCString PTY::ptsname()
00296 {
00297     if (ptyfd < 0)
00298     return 0;
00299 
00300     return ttyname;
00301 }
00302 

KDEsu

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

API Reference

Skip menu "API Reference"
  • dcop
  • DNSSD
  • interfaces
  • Kate
  • kconf_update
  • KDECore
  • KDED
  • kdefx
  • KDEsu
  • kdeui
  • KDocTools
  • KHTML
  • KImgIO
  • KInit
  • kio
  • kioslave
  • KJS
  • KNewStuff
  • KParts
  • KUtils
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal