11573Srgrimes/*-
211681Sbde * Copyright (c) 1990, 1993, 1994
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
51573Srgrimes * Redistribution and use in source and binary forms, with or without
61573Srgrimes * modification, are permitted provided that the following conditions
71573Srgrimes * are met:
81573Srgrimes * 1. Redistributions of source code must retain the above copyright
91573Srgrimes *    notice, this list of conditions and the following disclaimer.
101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111573Srgrimes *    notice, this list of conditions and the following disclaimer in the
121573Srgrimes *    documentation and/or other materials provided with the distribution.
131573Srgrimes * 4. Neither the name of the University nor the names of its contributors
141573Srgrimes *    may be used to endorse or promote products derived from this software
151573Srgrimes *    without specific prior written permission.
161573Srgrimes *
171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271573Srgrimes * SUCH DAMAGE.
281573Srgrimes */
291573Srgrimes
3084225Sdillon#include <sys/cdefs.h>
3184225Sdillon__FBSDID("$FreeBSD$");
3284225Sdillon
331573Srgrimes#if defined(LIBC_SCCS) && !defined(lint)
3428179Ssteve#if 0
3511681Sbdestatic char sccsid[] = "@(#)pty.c	8.3 (Berkeley) 5/16/94";
3628179Ssteve#endif
371573Srgrimes#endif /* LIBC_SCCS and not lint */
381573Srgrimes
391573Srgrimes#include <sys/types.h>
4011681Sbde#include <sys/ioctl.h>
411573Srgrimes#include <sys/stat.h>
4211681Sbde
4311681Sbde#include <errno.h>
441573Srgrimes#include <fcntl.h>
4511681Sbde#include <grp.h>
46116344Smarkm#include <libutil.h>
4711681Sbde#include <stdlib.h>
4811681Sbde#include <string.h>
491573Srgrimes#include <termios.h>
50184634Sdes#include <unistd.h>
511573Srgrimes
52175352Sjhbint
53175352Sjhbopenpty(int *amaster, int *aslave, char *name, struct termios *termp,
54154835Scognet    struct winsize *winp)
55154835Scognet{
56174818Sjhb	const char *slavename;
57154835Scognet	int master, slave;
58154835Scognet
59183565Sed	master = posix_openpt(O_RDWR|O_NOCTTY);
60154835Scognet	if (master == -1)
61154835Scognet		return (-1);
62154835Scognet
63183565Sed	if (grantpt(master) == -1)
64183565Sed		goto bad;
65154835Scognet
66183565Sed	if (unlockpt(master) == -1)
67183565Sed		goto bad;
68183565Sed
69174818Sjhb	slavename = ptsname(master);
70183565Sed	if (slavename == NULL)
71183565Sed		goto bad;
72174818Sjhb
73174818Sjhb	slave = open(slavename, O_RDWR);
74183565Sed	if (slave == -1)
75183565Sed		goto bad;
76154835Scognet
77154835Scognet	*amaster = master;
78154835Scognet	*aslave = slave;
79154835Scognet
80154835Scognet	if (name)
81175352Sjhb		strcpy(name, slavename);
82154835Scognet	if (termp)
83154835Scognet		tcsetattr(slave, TCSAFLUSH, termp);
84154835Scognet	if (winp)
85154835Scognet		ioctl(slave, TIOCSWINSZ, (char *)winp);
86154835Scognet
87154835Scognet	return (0);
88183565Sed
89183565Sedbad:	close(master);
90183565Sed	return (-1);
91154835Scognet}
92154835Scognet
9313137Speterint
94121193Smarkmforkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp)
951573Srgrimes{
961573Srgrimes	int master, slave, pid;
971573Srgrimes
981573Srgrimes	if (openpty(&master, &slave, name, termp, winp) == -1)
991573Srgrimes		return (-1);
1001573Srgrimes	switch (pid = fork()) {
1011573Srgrimes	case -1:
1021573Srgrimes		return (-1);
1031573Srgrimes	case 0:
1048870Srgrimes		/*
1051573Srgrimes		 * child
1061573Srgrimes		 */
1071573Srgrimes		(void) close(master);
1081573Srgrimes		login_tty(slave);
1091573Srgrimes		return (0);
1101573Srgrimes	}
1111573Srgrimes	/*
1121573Srgrimes	 * parent
1131573Srgrimes	 */
1141573Srgrimes	*amaster = master;
1151573Srgrimes	(void) close(slave);
1161573Srgrimes	return (pid);
1171573Srgrimes}
118