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