pty.c revision 184634
119914Swollman/*-
250476Speter * Copyright (c) 1990, 1993, 1994
31558Srgrimes *	The Regents of the University of California.  All rights reserved.
4156905Sru *
5156905Sru * Redistribution and use in source and binary forms, with or without
61558Srgrimes * modification, are permitted provided that the following conditions
725451Speter * are met:
8138593Ssam * 1. Redistributions of source code must retain the above copyright
925451Speter *    notice, this list of conditions and the following disclaimer.
10138593Ssam * 2. Redistributions in binary form must reproduce the above copyright
11138593Ssam *    notice, this list of conditions and the following disclaimer in the
12138593Ssam *    documentation and/or other materials provided with the distribution.
13138593Ssam * 4. Neither the name of the University nor the names of its contributors
14138593Ssam *    may be used to endorse or promote products derived from this software
15138593Ssam *    without specific prior written permission.
16138593Ssam *
17138593Ssam * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18222527Sbz * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19138593Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20222527Sbz * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21222527Sbz * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22138593Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23222527Sbz * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24138593Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25222527Sbz * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26197138Shrs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27222527Sbz * SUCH DAMAGE.
2844764Swpaul */
29138593Ssam
30138593Ssam#include <sys/cdefs.h>
31138593Ssam__FBSDID("$FreeBSD: head/lib/libutil/pty.c 184634 2008-11-04 13:50:50Z des $");
32223735Sbz
33138593Ssam#if defined(LIBC_SCCS) && !defined(lint)
34181224Sthompsa#if 0
35193664Shrsstatic char sccsid[] = "@(#)pty.c	8.3 (Berkeley) 5/16/94";
3677217Sphk#endif
37178354Ssam#endif /* LIBC_SCCS and not lint */
38204329Sru
39194871Sjamie#include <sys/types.h>
40178354Ssam#include <sys/ioctl.h>
41228577Sglebius#include <sys/stat.h>
42159781Smlaier
43142215Sglebius#include <errno.h>
44142215Sglebius#include <fcntl.h>
45146987Sthompsa#include <grp.h>
46168793Sthompsa#include <libutil.h>
47146987Sthompsa#include <stdlib.h>
48222527Sbz#include <string.h>
49222527Sbz#include <termios.h>
50222527Sbz#include <unistd.h>
51222527Sbz
52222527Sbzint
53222527Sbzopenpty(int *amaster, int *aslave, char *name, struct termios *termp,
54156905Sru    struct winsize *winp)
55138593Ssam{
56178354Ssam	const char *slavename;
57178354Ssam	int master, slave;
5880057Sobrien
5980057Sobrien	master = posix_openpt(O_RDWR|O_NOCTTY);
60138593Ssam	if (master == -1)
61138593Ssam		return (-1);
62144130Sbrooks
63202532Sed	if (grantpt(master) == -1)
641558Srgrimes		goto bad;
651558Srgrimes
66	if (unlockpt(master) == -1)
67		goto bad;
68
69	slavename = ptsname(master);
70	if (slavename == NULL)
71		goto bad;
72
73	slave = open(slavename, O_RDWR);
74	if (slave == -1)
75		goto bad;
76
77	*amaster = master;
78	*aslave = slave;
79
80	if (name)
81		strcpy(name, slavename);
82	if (termp)
83		tcsetattr(slave, TCSAFLUSH, termp);
84	if (winp)
85		ioctl(slave, TIOCSWINSZ, (char *)winp);
86
87	return (0);
88
89bad:	close(master);
90	return (-1);
91}
92
93int
94forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp)
95{
96	int master, slave, pid;
97
98	if (openpty(&master, &slave, name, termp, winp) == -1)
99		return (-1);
100	switch (pid = fork()) {
101	case -1:
102		return (-1);
103	case 0:
104		/*
105		 * child
106		 */
107		(void) close(master);
108		login_tty(slave);
109		return (0);
110	}
111	/*
112	 * parent
113	 */
114	*amaster = master;
115	(void) close(slave);
116	return (pid);
117}
118