root/opal/util/opal_pty.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. opal_openpty
  2. opal_openpty
  3. opal_openpty
  4. ptym_open
  5. ptys_open

   1 /*
   2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2005 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2018      Cisco Systems, Inc.  All rights reserved
  13  * $COPYRIGHT$
  14  *
  15  * Additional copyrights may follow
  16  *
  17  * $HEADER$
  18  */
  19 /*-
  20  * Copyright (c) 1990, 1993
  21  *      The Regents of the University of California.  All rights reserved.
  22  *
  23  * Redistribution and use in source and binary forms, with or without
  24  * modification, are permitted provided that the following conditions
  25  * are met:
  26  * 1. Redistributions of source code must retain the above copyright
  27  *    notice, this list of conditions and the following disclaimer.
  28  * 2. Redistributions in binary form must reproduce the above copyright
  29  *    notice, this list of conditions and the following disclaimer in the
  30  *    documentation and/or other materials provided with the distribution.
  31  * 4. Neither the name of the University nor the names of its contributors
  32  *    may be used to endorse or promote products derived from this software
  33  *    without specific prior written permission.
  34  *
  35  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  36  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  37  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  38  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  39  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  40  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  41  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  42  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  43  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  44  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  45  * SUCH DAMAGE.
  46  */
  47 
  48 #include "opal_config.h"
  49 
  50 #ifdef HAVE_SYS_CDEFS_H
  51 # include <sys/cdefs.h>
  52 #endif
  53 #ifdef HAVE_SYS_TYPES_H
  54 #include <sys/types.h>
  55 #endif
  56 #include <sys/stat.h>
  57 #ifdef HAVE_SYS_IOCTL_H
  58 #include <sys/ioctl.h>
  59 #endif
  60 #ifdef HAVE_FCNTL_H
  61 #include <fcntl.h>
  62 #endif
  63 #ifdef HAVE_TERMIOS_H
  64 # include <termios.h>
  65 #else
  66 # ifdef HAVE_TERMIO_H
  67 #  include <termio.h>
  68 # endif
  69 #endif
  70 #include <errno.h>
  71 #ifdef HAVE_UNISTD_H
  72 # include <unistd.h>
  73 #endif
  74 #include <stdio.h>
  75 # include <string.h>
  76 #ifdef HAVE_GRP_H
  77 #include <grp.h>
  78 #endif
  79 #ifdef HAVE_PTY_H
  80 #include <pty.h>
  81 #endif
  82 #ifdef HAVE_UTMP_H
  83 #include <utmp.h>
  84 #endif
  85 
  86 #ifdef HAVE_PTSNAME
  87 # include <stdlib.h>
  88 # ifdef HAVE_STROPTS_H
  89 #  include <stropts.h>
  90 # endif
  91 #endif
  92 
  93 #ifdef HAVE_UTIL_H
  94 #include <util.h>
  95 #endif
  96 
  97 #include "opal/util/opal_pty.h"
  98 
  99 /* The only public interface is openpty - all others are to support
 100    openpty() */
 101 
 102 #if OPAL_ENABLE_PTY_SUPPORT == 0
 103 
 104 int opal_openpty(int *amaster, int *aslave, char *name,
 105                  void *termp, void *winpp)
 106 {
 107     return -1;
 108 }
 109 
 110 #elif defined(HAVE_OPENPTY)
 111 
 112 int opal_openpty(int *amaster, int *aslave, char *name,
 113                  struct termios *termp, struct winsize *winp)
 114 {
 115     return openpty(amaster, aslave, name, termp, winp);
 116 }
 117 
 118 #else
 119 
 120 /* implement openpty in terms of ptym_open and ptys_open */
 121 
 122 static int ptym_open(char *pts_name);
 123 static int ptys_open(int fdm, char *pts_name);
 124 
 125 int opal_openpty(int *amaster, int *aslave, char *name,
 126                  struct termios *termp, struct winsize *winp)
 127 {
 128     char line[20];
 129     *amaster = ptym_open(line);
 130     if (*amaster < 0) {
 131         return -1;
 132     }
 133     *aslave = ptys_open(*amaster, line);
 134     if (*aslave < 0) {
 135         close(*amaster);
 136         return -1;
 137     }
 138     if (name) {
 139         // We don't know the max length of name, but we do know the
 140         // max length of the source, so at least use that.
 141         opal_string_copy(name, line, sizeof(line));
 142     }
 143 #ifndef TCSAFLUSH
 144 #define TCSAFLUSH TCSETAF
 145 #endif
 146     if (termp) {
 147         (void) tcsetattr(*aslave, TCSAFLUSH, termp);
 148     }
 149 #ifdef TIOCSWINSZ
 150     if (winp) {
 151         (void) ioctl(*aslave, TIOCSWINSZ, (char *) winp);
 152     }
 153 #endif
 154     return 0;
 155 }
 156 
 157 
 158 static int ptym_open(char *pts_name)
 159 {
 160     int fdm;
 161 #ifdef HAVE_PTSNAME
 162     char *ptr;
 163 
 164 #ifdef _AIX
 165     strcpy(pts_name, "/dev/ptc");
 166 #else
 167     strcpy(pts_name, "/dev/ptmx");
 168 #endif
 169     fdm = open(pts_name, O_RDWR);
 170     if (fdm < 0) {
 171         return -1;
 172     }
 173     if (grantpt(fdm) < 0) {     /* grant access to slave */
 174         close(fdm);
 175         return -2;
 176     }
 177     if (unlockpt(fdm) < 0) {    /* clear slave's lock flag */
 178         close(fdm);
 179         return -3;
 180     }
 181     ptr = ptsname(fdm);
 182     if (ptr == NULL) {          /* get slave's name */
 183         close(fdm);
 184         return -4;
 185     }
 186     strcpy(pts_name, ptr);      /* return name of slave */
 187     return fdm;                 /* return fd of master */
 188 #else
 189     char *ptr1, *ptr2;
 190 
 191     strcpy(pts_name, "/dev/ptyXY");
 192     /* array index: 012345689 (for references in following code) */
 193     for (ptr1 = "pqrstuvwxyzPQRST"; *ptr1 != 0; ptr1++) {
 194         pts_name[8] = *ptr1;
 195         for (ptr2 = "0123456789abcdef"; *ptr2 != 0; ptr2++) {
 196             pts_name[9] = *ptr2;
 197             /* try to open master */
 198             fdm = open(pts_name, O_RDWR);
 199             if (fdm < 0) {
 200                 if (errno == ENOENT) {  /* different from EIO */
 201                     return -1;  /* out of pty devices */
 202                 } else {
 203                     continue;   /* try next pty device */
 204                 }
 205             }
 206             pts_name[5] = 't';  /* chage "pty" to "tty" */
 207             return fdm;         /* got it, return fd of master */
 208         }
 209     }
 210     return -1;                  /* out of pty devices */
 211 #endif
 212 }
 213 
 214 
 215 static int ptys_open(int fdm, char *pts_name)
 216 {
 217     int fds;
 218 #ifdef HAVE_PTSNAME
 219     /* following should allocate controlling terminal */
 220     fds = open(pts_name, O_RDWR);
 221     if (fds < 0) {
 222         close(fdm);
 223         return -5;
 224     }
 225 #if defined(__SVR4) && defined(__sun)
 226     if (ioctl(fds, I_PUSH, "ptem") < 0) {
 227         close(fdm);
 228         close(fds);
 229         return -6;
 230     }
 231     if (ioctl(fds, I_PUSH, "ldterm") < 0) {
 232         close(fdm);
 233         close(fds);
 234         return -7;
 235     }
 236 #endif
 237 
 238     return fds;
 239 #else
 240     int gid;
 241     struct group *grptr;
 242 
 243     grptr = getgrnam("tty");
 244     if (grptr != NULL) {
 245         gid = grptr->gr_gid;
 246     } else {
 247         gid = -1;               /* group tty is not in the group file */
 248     }
 249     /* following two functions don't work unless we're root */
 250     chown(pts_name, getuid(), gid);
 251     chmod(pts_name, S_IRUSR | S_IWUSR | S_IWGRP);
 252     fds = open(pts_name, O_RDWR);
 253     if (fds < 0) {
 254         close(fdm);
 255         return -1;
 256     }
 257     return fds;
 258 #endif
 259 }
 260 
 261 #endif /* #ifdef HAVE_OPENPTY */

/* [<][>][^][v][top][bottom][index][help] */