/*1Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.2All rights reserved.3Copyright (C) 2007-2013, Gabriel Dos Reis.4All rights reserved.56Redistribution and use in source and binary forms, with or without7modification, are permitted provided that the following conditions are8met:910- Redistributions of source code must retain the above copyright11notice, this list of conditions and the following disclaimer.1213- Redistributions in binary form must reproduce the above copyright14notice, this list of conditions and the following disclaimer in15the documentation and/or other materials provided with the16distribution.1718- Neither the name of The Numerical ALgorithms Group Ltd. nor the19names of its contributors may be used to endorse or promote products20derived from this software without specific prior written permission.2122THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS23IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED24TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A25PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER26OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,27EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,28PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR29PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF30LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING31NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS32SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.33*/3435#include "openaxiom-c-macros.h"36#include <stdlib.h>37#include <unistd.h>38#include <stdio.h>39#include <fcntl.h>40#include <string.h>4142#ifdef HAVE_SYS_IOCTL_H43# include <sys/ioctl.h>44#endif45#ifdef HAVE_PTY_H46# include <pty.h>47#endif48#ifdef HAVE_UTIL_H49# include <util.h>50#endif51#ifdef HAVE_TERMIOS_H52# include <termios.h>53#endif54#ifdef HAVE_LIBUTIL_H55# include <sys/types.h>56# include <libutil.h>57#endif585960#include "openpty.h"6162#if defined(SUNplatform)63static void64makeNextPtyNames(char *cont,char * serv)65{66static int channelNo = 0;67static char group[] = "pqrstuvwxyzPQRST";68static int groupNo = 0;6970sprintf(cont, "/dev/pty%c%x", group[groupNo], channelNo);71sprintf(serv, "/dev/tty%c%x", group[groupNo], channelNo);72channelNo++; /* try next */73if (channelNo == 16) { /* move to new group */74channelNo = 0;75groupNo++;76if (groupNo == 16) groupNo = 0; /* recycle */77}78}79#endif808182/*83* The main function is ptyopen. It simply opens up both sides of a84* pseudo-terminal. It uses and saves the pathnames for85* the devices which were actually opened.86*87* If it fails it simply exits the program.88*89*90* ptyopen(controller, server, controllerPath, serverPath)91* int *controller; The file descriptor for controller side of the pty92* int *server; The file descriptor for the server side93* char *serverPath;94*95* The path name vars should be declared of size 11 or more96*/979899int100ptyopen(int *controller,int * server,char * serverPath)101{102#if HAVE_DECL_OPENPTY103return openpty(controller,server, serverPath, NULL, NULL);104#elif defined(SUNplatform)105int looking = 1, i;106int oflag = O_RDWR; /* flag for opening the pty */107char controllerPath[128];108109for (i = 0; looking && i < 1000; i++) {110makeNextPtyNames(controllerPath, serverPath);111if (access(controllerPath, 6) != 0) continue;112*controller = open(controllerPath, oflag, 0);113if (*controller >= 0) {114*server = open(serverPath, oflag, 0);115if (*server > 0)116looking = 0;117else118close(*controller);119}120}121if (looking) {122fprintf(stderr, "Couldn't find a free pty.\n");123exit(-1);124}125return (*controller);126#elif defined(SUN4OS5platform)127extern int grantpt(int);128extern int unlockpt(int);129extern char* ptsname(int);130int fdm,fds;131char *slavename;132133/* open master */134if ((fdm = open("/dev/ptmx", O_RDWR)) < 0 )135perror("ptyopen: Failed to open /dev/ptmx");136else {137/* change permission ofslave */138if (grantpt(fdm) < 0)139perror("ptyopen: Failed to grant access to slave device");140/* unlock slave */141if (unlockpt(fdm) < 0)142perror("ptyopen: Failed to unlock master/slave pair");143/* get name of slave */144if ((slavename = ptsname(fdm)) == NULL)145perror("ptyopen: Failed to get name of slave device");146/* open slave */147if ((fds = open(slavename, O_RDWR)) < 0 )148perror("ptyopen: Failed to open slave");149else {150/* push ptem */151if (ioctl(fds, I_PUSH, "ptem") < 0)152perror("ptyopen: Failed to push ptem");153/* push ldterm */154if (ioctl(fds, I_PUSH, "ldterm") < 0)155perror("ptyopen: Failed to push idterm");156strcpy(serverPath,slavename);157*controller=fdm;158*server=fds;159}160}161return(fdm);162#else163# error "don't know how to open a pty"164#endif165}166167168169170