pty.c revision 84225
159769Sgrog/*- 259769Sgrog * Copyright (c) 1990, 1993, 1994 324424Swosch * The Regents of the University of California. All rights reserved. 424424Swosch * 524424Swosch * Redistribution and use in source and binary forms, with or without 624424Swosch * modification, are permitted provided that the following conditions 724424Swosch * are met: 824424Swosch * 1. Redistributions of source code must retain the above copyright 924424Swosch * notice, this list of conditions and the following disclaimer. 1024424Swosch * 2. Redistributions in binary form must reproduce the above copyright 1124424Swosch * notice, this list of conditions and the following disclaimer in the 1224424Swosch * documentation and/or other materials provided with the distribution. 1324424Swosch * 3. All advertising materials mentioning features or use of this software 1424424Swosch * must display the following acknowledgement: 1542704Swosch * This product includes software developed by the University of 1642704Swosch * California, Berkeley and its contributors. 1742704Swosch * 4. Neither the name of the University nor the names of its contributors 1824424Swosch * may be used to endorse or promote products derived from this software 1942704Swosch * without specific prior written permission. 2042704Swosch * 2142704Swosch * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2242704Swosch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2342704Swosch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2442704Swosch * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2542704Swosch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2642704Swosch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2742704Swosch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2842704Swosch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2942704Swosch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3059769Sgrog * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3159769Sgrog * SUCH DAMAGE. 3259769Sgrog */ 3359769Sgrog 3459769Sgrog#include <sys/cdefs.h> 3559769Sgrog__FBSDID("$FreeBSD: head/lib/libutil/pty.c 84225 2001-09-30 22:35:07Z dillon $"); 3659769Sgrog 3759769Sgrog#if defined(LIBC_SCCS) && !defined(lint) 3859769Sgrog#if 0 3924424Swoschstatic char sccsid[] = "@(#)pty.c 8.3 (Berkeley) 5/16/94"; 4042704Swosch#endif 4124424Swosch#endif /* LIBC_SCCS and not lint */ 4242704Swosch 4324424Swosch#include <sys/types.h> 4442704Swosch#include <sys/ioctl.h> 4524424Swosch#include <sys/stat.h> 4624424Swosch 4724424Swosch#include <errno.h> 4842704Swosch#include <fcntl.h> 4925031Swosch#include <grp.h> 5059156Swosch#include <stdlib.h> 5125031Swosch#include <string.h> 5225031Swosch#include <termios.h> 5324424Swosch#include <unistd.h> 5424424Swosch#include <libutil.h> 5524424Swosch 5624424Swoschint 5771231Sitojunopenpty(amaster, aslave, name, termp, winp) 5824424Swosch int *amaster, *aslave; 5971231Sitojun char *name; 6025031Swosch struct termios *termp; 6171231Sitojun struct winsize *winp; 6224424Swosch{ 6325031Swosch char line[] = "/dev/ptyXX"; 6425031Swosch register const char *cp1, *cp2; 6571231Sitojun register int master, slave, ttygid; 6625031Swosch struct group *gr; 6771231Sitojun 6870110Swosch if ((gr = getgrnam("tty")) != NULL) 6970110Swosch ttygid = gr->gr_gid; 7070110Swosch else 7170110Swosch ttygid = -1; 7270110Swosch 7370110Swosch for (cp1 = "pqrsPQRS"; *cp1; cp1++) { 7470110Swosch line[8] = *cp1; 7570110Swosch for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) { 7670110Swosch line[5] = 'p'; 7770110Swosch line[9] = *cp2; 7870110Swosch if ((master = open(line, O_RDWR, 0)) == -1) { 7980675Sasmodai if (errno == ENOENT) 8080675Sasmodai break; /* try the next pty group */ 8180675Sasmodai } else { 8280675Sasmodai line[5] = 't'; 8380675Sasmodai (void) chown(line, getuid(), ttygid); 8480675Sasmodai (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP); 8580675Sasmodai (void) revoke(line); 8680675Sasmodai if ((slave = open(line, O_RDWR, 0)) != -1) { 8780675Sasmodai *amaster = master; 8880675Sasmodai *aslave = slave; 8980675Sasmodai if (name) 9080675Sasmodai strcpy(name, line); 9180675Sasmodai if (termp) 9280675Sasmodai (void) tcsetattr(slave, 9380675Sasmodai TCSAFLUSH, termp); 9480675Sasmodai if (winp) 9580675Sasmodai (void) ioctl(slave, TIOCSWINSZ, 9680675Sasmodai (char *)winp); 9780675Sasmodai return (0); 9880675Sasmodai } 9980675Sasmodai (void) close(master); 10080675Sasmodai } 10180675Sasmodai } 10280675Sasmodai } 10380675Sasmodai errno = ENOENT; /* out of ptys */ 10480675Sasmodai return (-1); 10580675Sasmodai} 10680675Sasmodai 10780675Sasmodaiint 10880675Sasmodaiforkpty(amaster, name, termp, winp) 10980675Sasmodai int *amaster; 11080675Sasmodai char *name; 11180675Sasmodai struct termios *termp; 11280675Sasmodai struct winsize *winp; 11380675Sasmodai{ 11480675Sasmodai int master, slave, pid; 11580675Sasmodai 11680675Sasmodai if (openpty(&master, &slave, name, termp, winp) == -1) 11780675Sasmodai return (-1); 11880675Sasmodai switch (pid = fork()) { 11980675Sasmodai case -1: 12080675Sasmodai return (-1); 12180675Sasmodai case 0: 12280675Sasmodai /* 12380675Sasmodai * child 12480675Sasmodai */ 12580675Sasmodai (void) close(master); 12680675Sasmodai login_tty(slave); 12780675Sasmodai return (0); 12880675Sasmodai } 12980675Sasmodai /* 13080675Sasmodai * parent 13180675Sasmodai */ 13280675Sasmodai *amaster = master; 13380675Sasmodai (void) close(slave); 13480675Sasmodai return (pid); 13580675Sasmodai} 13680675Sasmodai