| /******************************************************************************* | |
| * Copyright (c) 2002, 2010 QNX Software Systems and others. | |
| * All rights reserved. This program and the accompanying materials | |
| * are made available under the terms of the Eclipse Public License v1.0 | |
| * which accompanies this distribution, and is available at | |
| * http://www.eclipse.org/legal/epl-v10.html | |
| * | |
| * Contributors: | |
| * QNX Software Systems - initial API and implementation | |
| * Wind River Systems, Inc. | |
| * Mikhail Zabaluev (Nokia) - bug 82744 | |
| * Corey Ashford (IBM) - bug 272370, bug 272372 | |
| *******************************************************************************/ | |
| /* _XOPEN_SOURCE is needed to bring in the header for ptsname */ | |
| #define _XOPEN_SOURCE | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #include <sys/ioctl.h> | |
| #include <fcntl.h> | |
| #include <termios.h> | |
| #include <errno.h> | |
| #include <unistd.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <grp.h> | |
| #include <stdlib.h> | |
| /** | |
| * This is taken from R. W. Stevens book. | |
| * Alain Magloire. | |
| */ | |
| int ptym_open (char *pts_name); | |
| int ptys_open (int fdm, const char * pts_name); | |
| void set_noecho(int fd); | |
| int | |
| openpty(int *amaster, int *aslave, char *name, struct termios *termp, struct winsize *winp) | |
| { | |
| char line[20]; | |
| line[0]=0; | |
| *amaster = ptym_open(line); | |
| if (*amaster < 0) | |
| return -1; | |
| *aslave = ptys_open(*amaster, line); | |
| if (*aslave < 0) { | |
| close(*amaster); | |
| return -1; | |
| } | |
| if (name) | |
| strcpy(name, line); | |
| #ifndef TCSAFLUSH | |
| #define TCSAFLUSH TCSETAF | |
| #endif | |
| if (termp) | |
| (void) tcsetattr(*aslave, TCSAFLUSH, termp); | |
| #ifdef TIOCSWINSZ | |
| if (winp) | |
| (void) ioctl(*aslave, TIOCSWINSZ, (char *)winp); | |
| #endif | |
| return 0; | |
| } | |
| void | |
| set_noecho(int fd) | |
| { | |
| struct termios stermios; | |
| if (tcgetattr(fd, &stermios) < 0) { | |
| return ; | |
| } | |
| /* turn off echo */ | |
| stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); | |
| /* Turn off the NL to CR/NL mapping ou output. */ | |
| /*stermios.c_oflag &= ~(ONLCR);*/ | |
| stermios.c_iflag |= (IGNCR); | |
| tcsetattr(fd, TCSANOW, &stermios); | |
| } | |
| int | |
| ptym_open(char * pts_name) | |
| { | |
| int fdm; | |
| char *ptr; | |
| strcpy(pts_name, "/dev/ptmx"); | |
| fdm = getpt(); | |
| if (fdm < 0) | |
| return -1; | |
| if (grantpt(fdm) < 0) { /* grant access to slave */ | |
| close(fdm); | |
| return -2; | |
| } | |
| if (unlockpt(fdm) < 0) { /* clear slave's lock flag */ | |
| close(fdm); | |
| return -3; | |
| } | |
| ptr = ptsname(fdm); | |
| if (ptr == NULL) { /* get slave's name */ | |
| close (fdm); | |
| return -4; | |
| } | |
| strcpy(pts_name, ptr); /* return name of slave */ | |
| return fdm; /* return fd of master */ | |
| } | |
| int | |
| ptys_open(int fdm, const char * pts_name) | |
| { | |
| int fds; | |
| /* following should allocate controlling terminal */ | |
| fds = open(pts_name, O_RDWR); | |
| if (fds < 0) { | |
| close(fdm); | |
| return -5; | |
| } | |
| #if defined(TIOCSCTTY) | |
| /* TIOCSCTTY is the BSD way to acquire a controlling terminal. */ | |
| if (ioctl(fds, TIOCSCTTY, (char *)0) < 0) { | |
| // ignore error: this is expected in console-mode | |
| } | |
| #endif | |
| return fds; | |
| } |