/* * pty_getpty: open a PTY master. * * Copyright 1995, 1996 by the Massachusetts Institute of Technology. * * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby * granted, provided that the above copyright notice appear in all * copies and that both that copyright notice and this permission * notice appear in supporting documentation, and that the name of * M.I.T. not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior * permission. Furthermore if you modify this software you must label * your software as modified software and not distribute it in such a * fashion that it might be confused with the original M.I.T. software. * M.I.T. makes no representations about the suitability * of this software for any purpose. It is provided "as is" without * express or implied warranty. * */ #include "com_err.h" #include "libpty.h" #include "pty-int.h" long ptyint_getpty_ext(int *fd, char *slave, int slavelength, int do_grantpt) { #if !defined(HAVE__GETPTY) && !defined(HAVE_OPENPTY) char *cp; char *p; int i,ptynum; struct stat stb; char slavebuf[1024]; #endif #ifdef HAVE__GETPTY char *slaveret; /*Temporary to hold pointer to slave*/ #endif /*HAVE__GETPTY*/ #ifdef HAVE_OPENPTY int slavefd; if(openpty(fd, &slavefd, slave, (struct termios *) 0, (struct winsize *) 0)) return 1; close(slavefd); return 0; #else /*HAVE_OPENPTY*/ #ifdef HAVE__GETPTY /* This code is included for Irix; as of version 5.3, Irix has /dev/ptmx, * but it fails to work properly; even after calling unlockpt, * root gets permission denied opening the pty. * The code to support _getpty should be removed if Irix gets working * streams ptys in favor of maintaining the least needed code * paths. */ if ((slaveret = _getpty(fd, O_RDWR|O_NDELAY, 0600, 0)) == 0) { *fd = -1; return PTY_GETPTY_NOPTY; } if (strlen(slaveret) > slavelength - 1) { close(*fd); *fd = -1; return PTY_GETPTY_SLAVE_TOOLONG; } else strcpy(slave, slaveret); return 0; #else /*HAVE__GETPTY*/ *fd = open("/dev/ptym/clone", O_RDWR|O_NDELAY); /* HPUX*/ #ifdef HAVE_STREAMS if (*fd < 0) *fd = open("/dev/ptmx",O_RDWR|O_NDELAY); /*Solaris*/ #endif if (*fd < 0) *fd = open("/dev/ptc", O_RDWR|O_NDELAY); /* AIX */ if (*fd < 0) *fd = open("/dev/pty", O_RDWR|O_NDELAY); /* sysvimp */ if (*fd >= 0) { #if defined(HAVE_GRANTPT)&&defined(HAVE_STREAMS) if (do_grantpt) if (grantpt(*fd) || unlockpt(*fd)) return PTY_GETPTY_STREAMS; #endif #ifdef HAVE_PTSNAME p = ptsname(*fd); #else #ifdef HAVE_TTYNAME p = ttyname(*fd); #else /* XXX If we don't have either what do we do */ #endif #endif if (p) { if (strlen(p) > slavelength - 1) { close (*fd); *fd = -1; return PTY_GETPTY_SLAVE_TOOLONG; } strcpy(slave, p); return 0; } if (fstat(*fd, &stb) < 0) { close(*fd); return PTY_GETPTY_FSTAT; } ptynum = (int)(stb.st_rdev&0xFF); sprintf(slavebuf, "/dev/ttyp%x", ptynum); if (strlen(slavebuf) > slavelength - 1) { close(*fd); *fd = -1; return PTY_GETPTY_SLAVE_TOOLONG; } strncpy(slave, slavebuf, slavelength); return 0; } else { for (cp = "pqrstuvwxyzPQRST";*cp; cp++) { sprintf(slavebuf,"/dev/ptyXX"); slavebuf[sizeof("/dev/pty") - 1] = *cp; slavebuf[sizeof("/dev/ptyp") - 1] = '0'; if (stat(slavebuf, &stb) < 0) break; for (i = 0; i < 16; i++) { slavebuf[sizeof("/dev/ptyp") - 1] = "0123456789abcdef"[i]; *fd = open(slavebuf, O_RDWR); if (*fd < 0) continue; /* got pty */ slavebuf[sizeof("/dev/") - 1] = 't'; if (strlen(slavebuf) > slavelength -1) { close(*fd); *fd = -1; return PTY_GETPTY_SLAVE_TOOLONG; } strncpy(slave, slavebuf, slavelength); return 0; } } return PTY_GETPTY_NOPTY; } #endif /*HAVE__GETPTY*/ #endif /* HAVE_OPENPTY */ } long pty_getpty(int *fd, char *slave, int slavelength) { return ptyint_getpty_ext(fd, slave, slavelength, 1); }