pty.c revision 225736
1256752Sbrooks/*- 2256752Sbrooks * Copyright (c) 1990, 1993, 1994 3256752Sbrooks * The Regents of the University of California. All rights reserved. 4256752Sbrooks * 5256752Sbrooks * Redistribution and use in source and binary forms, with or without 6256752Sbrooks * modification, are permitted provided that the following conditions 7256752Sbrooks * are met: 8256752Sbrooks * 1. Redistributions of source code must retain the above copyright 9256752Sbrooks * notice, this list of conditions and the following disclaimer. 10256752Sbrooks * 2. Redistributions in binary form must reproduce the above copyright 11256752Sbrooks * notice, this list of conditions and the following disclaimer in the 12256752Sbrooks * documentation and/or other materials provided with the distribution. 13256752Sbrooks * 4. Neither the name of the University nor the names of its contributors 14256752Sbrooks * may be used to endorse or promote products derived from this software 15256752Sbrooks * without specific prior written permission. 16256752Sbrooks * 17256752Sbrooks * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18256752Sbrooks * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19256752Sbrooks * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20256752Sbrooks * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21256752Sbrooks * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22256752Sbrooks * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23256752Sbrooks * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24256752Sbrooks * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25256752Sbrooks * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26256752Sbrooks * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27256752Sbrooks * SUCH DAMAGE. 28256752Sbrooks */ 29256752Sbrooks 30256752Sbrooks#include <sys/cdefs.h> 31256752Sbrooks__FBSDID("$FreeBSD: stable/9/lib/libutil/pty.c 184634 2008-11-04 13:50:50Z des $"); 32256752Sbrooks 33256752Sbrooks#if defined(LIBC_SCCS) && !defined(lint) 34256752Sbrooks#if 0 35256752Sbrooksstatic char sccsid[] = "@(#)pty.c 8.3 (Berkeley) 5/16/94"; 36256752Sbrooks#endif 37256752Sbrooks#endif /* LIBC_SCCS and not lint */ 38256752Sbrooks 39256752Sbrooks#include <sys/types.h> 40256752Sbrooks#include <sys/ioctl.h> 41256752Sbrooks#include <sys/stat.h> 42256752Sbrooks 43256752Sbrooks#include <errno.h> 44256752Sbrooks#include <fcntl.h> 45256752Sbrooks#include <grp.h> 46256752Sbrooks#include <libutil.h> 47256752Sbrooks#include <stdlib.h> 48256752Sbrooks#include <string.h> 49256752Sbrooks#include <termios.h> 50256752Sbrooks#include <unistd.h> 51256752Sbrooks 52256752Sbrooksint 53256752Sbrooksopenpty(int *amaster, int *aslave, char *name, struct termios *termp, 54256752Sbrooks struct winsize *winp) 55256752Sbrooks{ 56256752Sbrooks const char *slavename; 57256752Sbrooks int master, slave; 58256752Sbrooks 59256752Sbrooks master = posix_openpt(O_RDWR|O_NOCTTY); 60256752Sbrooks if (master == -1) 61256752Sbrooks return (-1); 62256752Sbrooks 63256752Sbrooks if (grantpt(master) == -1) 64256752Sbrooks goto bad; 65256752Sbrooks 66256752Sbrooks if (unlockpt(master) == -1) 67256752Sbrooks goto bad; 68256752Sbrooks 69256752Sbrooks slavename = ptsname(master); 70256752Sbrooks if (slavename == NULL) 71256752Sbrooks goto bad; 72256752Sbrooks 73256752Sbrooks slave = open(slavename, O_RDWR); 74256752Sbrooks if (slave == -1) 75256752Sbrooks goto bad; 76256752Sbrooks 77256752Sbrooks *amaster = master; 78256752Sbrooks *aslave = slave; 79256752Sbrooks 80256752Sbrooks if (name) 81256752Sbrooks strcpy(name, slavename); 82256752Sbrooks if (termp) 83256752Sbrooks tcsetattr(slave, TCSAFLUSH, termp); 84256752Sbrooks if (winp) 85256752Sbrooks ioctl(slave, TIOCSWINSZ, (char *)winp); 86256752Sbrooks 87256752Sbrooks return (0); 88256752Sbrooks 89256752Sbrooksbad: close(master); 90256752Sbrooks return (-1); 91256752Sbrooks} 92256752Sbrooks 93256752Sbrooksint 94256752Sbrooksforkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp) 95256752Sbrooks{ 96256752Sbrooks int master, slave, pid; 97256752Sbrooks 98256752Sbrooks if (openpty(&master, &slave, name, termp, winp) == -1) 99256752Sbrooks return (-1); 100256752Sbrooks switch (pid = fork()) { 101256752Sbrooks case -1: 102256752Sbrooks return (-1); 103256752Sbrooks case 0: 104256752Sbrooks /* 105256752Sbrooks * child 106256752Sbrooks */ 107256752Sbrooks (void) close(master); 108256752Sbrooks login_tty(slave); 109256752Sbrooks return (0); 110256752Sbrooks } 111256752Sbrooks /* 112256752Sbrooks * parent 113256752Sbrooks */ 114256752Sbrooks *amaster = master; 115256752Sbrooks (void) close(slave); 116256752Sbrooks return (pid); 117256752Sbrooks} 118256752Sbrooks