pty.c revision 17141
137535Sdes/*- 263012Sdes * Copyright (c) 1990, 1993, 1994 337535Sdes * The Regents of the University of California. All rights reserved. 437535Sdes * 537535Sdes * Redistribution and use in source and binary forms, with or without 637535Sdes * modification, are permitted provided that the following conditions 737535Sdes * are met: 837535Sdes * 1. Redistributions of source code must retain the above copyright 937535Sdes * notice, this list of conditions and the following disclaimer. 1037535Sdes * 2. Redistributions in binary form must reproduce the above copyright 1137535Sdes * notice, this list of conditions and the following disclaimer in the 1237535Sdes * documentation and/or other materials provided with the distribution. 1337535Sdes * 3. All advertising materials mentioning features or use of this software 1437535Sdes * must display the following acknowledgement: 1563012Sdes * This product includes software developed by the University of 1637535Sdes * California, Berkeley and its contributors. 1737535Sdes * 4. Neither the name of the University nor the names of its contributors 1837535Sdes * may be used to endorse or promote products derived from this software 1937535Sdes * without specific prior written permission. 2037535Sdes * 2137535Sdes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2237535Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2337535Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2437535Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2537535Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2637535Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2737535Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2837535Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2984203Sdillon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3084203Sdillon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3184203Sdillon * SUCH DAMAGE. 3263236Sdes */ 3363236Sdes 3463236Sdes#if defined(LIBC_SCCS) && !defined(lint) 3563236Sdesstatic char sccsid[] = "@(#)pty.c 8.3 (Berkeley) 5/16/94"; 3663236Sdes#endif /* LIBC_SCCS and not lint */ 3763236Sdes 3863236Sdes#include <sys/types.h> 3963236Sdes#include <sys/ioctl.h> 4063236Sdes#include <sys/stat.h> 4163236Sdes 4263236Sdes#include <errno.h> 4363236Sdes#include <fcntl.h> 4463236Sdes#include <grp.h> 4563236Sdes#include <stdio.h> 4663236Sdes#include <stdlib.h> 4763236Sdes#include <string.h> 4863236Sdes#include <termios.h> 4990267Sdes#include <unistd.h> 5063236Sdes#include <libutil.h> 5163236Sdes 5263236Sdesint 5363236Sdesopenpty(amaster, aslave, name, termp, winp) 5463236Sdes int *amaster, *aslave; 5563236Sdes char *name; 5663236Sdes struct termios *termp; 5763236Sdes struct winsize *winp; 5863236Sdes{ 5963236Sdes static char line[] = "/dev/ptyXX"; 6063236Sdes register const char *cp1, *cp2; 6163236Sdes register int master, slave, ttygid; 6263236Sdes struct group *gr; 6363236Sdes 6437535Sdes if ((gr = getgrnam("tty")) != NULL) 6560737Sume ttygid = gr->gr_gid; 6637535Sdes else 6763012Sdes ttygid = -1; 6837535Sdes 6963012Sdes for (cp1 = "pqrsPQRS"; *cp1; cp1++) { 7060376Sdes line[8] = *cp1; 7160189Sdes for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) { 7237608Sdes line[5] = 'p'; 7337535Sdes line[9] = *cp2; 7437535Sdes if ((master = open(line, O_RDWR, 0)) == -1) { 7537535Sdes if (errno == ENOENT) 7660376Sdes return (-1); /* out of ptys */ 7737535Sdes } else { 7837535Sdes line[5] = 't'; 7937535Sdes (void) chown(line, getuid(), ttygid); 8040939Sdes (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP); 8141862Sdes (void) revoke(line); 8237535Sdes if ((slave = open(line, O_RDWR, 0)) != -1) { 8363012Sdes *amaster = master; 8463012Sdes *aslave = slave; 8537535Sdes if (name) 8663012Sdes strcpy(name, line); 8763012Sdes if (termp) 8863012Sdes (void) tcsetattr(slave, 8963012Sdes TCSAFLUSH, termp); 9063012Sdes if (winp) 9163012Sdes (void) ioctl(slave, TIOCSWINSZ, 9263012Sdes (char *)winp); 9387317Sdes return (0); 9463012Sdes } 9560196Sdes (void) close(master); 9663012Sdes } 9790267Sdes } 9890267Sdes } 9963012Sdes errno = ENOENT; /* out of ptys */ 10088771Sdes return (-1); 10163012Sdes} 10290267Sdes 10363012Sdesint 10463012Sdesforkpty(amaster, name, termp, winp) 10563012Sdes int *amaster; 10663012Sdes char *name; 10797859Sdes struct termios *termp; 10837535Sdes struct winsize *winp; 10997858Sdes{ 11097866Sdes int master, slave, pid; 11197858Sdes 11297866Sdes if (openpty(&master, &slave, name, termp, winp) == -1) 11397866Sdes return (-1); 11497866Sdes switch (pid = fork()) { 11597858Sdes case -1: 11697858Sdes return (-1); 11797858Sdes case 0: 11863281Sdes /* 11990267Sdes * child 12063012Sdes */ 12137535Sdes (void) close(master); 12237535Sdes login_tty(slave); 12337608Sdes return (0); 12463012Sdes } 12537608Sdes /* 12637608Sdes * parent 12797859Sdes */ 12837608Sdes *amaster = master; 12990267Sdes (void) close(slave); 13090267Sdes return (pid); 13197859Sdes} 13290267Sdes