1 /* $NetBSD: pty.c,v 1.31 2009/02/20 16:44:06 christos Exp $ */
4 * Copyright (c) 1990, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
33 #if defined(LIBC_SCCS) && !defined(lint)
35 static char sccsid
[] = "@(#)pty.c 8.3 (Berkeley) 5/16/94";
37 __RCSID("$NetBSD: pty.c,v 1.31 2009/02/20 16:44:06 christos Exp $");
39 #endif /* LIBC_SCCS and not lint */
41 #include <sys/types.h>
42 #include <sys/ioctl.h>
56 * XXX: `v' removed until no ports are using console devices which use ttyv0
58 #define TTY_LETTERS "pqrstuwxyzPQRST"
59 #define TTY_OLD_SUFFIX "0123456789abcdef"
60 #define TTY_NEW_SUFFIX "ghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
63 openpty(int *amaster
, int *aslave
, char *name
, struct termios
*term
,
66 char line
[] = "/dev/XtyXX";
67 const char *cp1
, *cp2
, *cp
, *linep
;
71 struct group grs
, *grp
;
74 _DIAGASSERT(amaster
!= NULL
);
75 _DIAGASSERT(aslave
!= NULL
);
76 /* name may be NULL */
77 /* term may be NULL */
78 /* winp may be NULL */
81 if ((master
= open("/dev/ptm", O_RDWR
)) != -1) {
83 if (ioctl(master
, TIOCPTMGET
, &pt
) != -1) {
94 (void)getgrnam_r("tty", &grs
, grbuf
, sizeof(grbuf
), &grp
);
97 mode
= S_IRUSR
|S_IWUSR
|S_IWGRP
;
100 mode
= S_IRUSR
|S_IWUSR
;
103 for (cp1
= TTY_LETTERS
; *cp1
; cp1
++) {
105 for (cp
= cp2
= TTY_OLD_SUFFIX TTY_NEW_SUFFIX
; *cp2
; cp2
++) {
108 if ((master
= open(line
, O_RDWR
| O_NOCTTY
, 0)) == -1) {
111 if ((size_t)(cp2
- cp
+ 1) < sizeof(TTY_OLD_SUFFIX
))
112 return -1; /* out of ptys */
114 break; /* out of ptys in this group */
118 if (chown(line
, getuid(), ttygid
) == 0 &&
119 chmod(line
, mode
) == 0 &&
123 (slave
= open(line
, O_RDWR
| O_NOCTTY
, 0)) != -1) {
130 (void)strcpy(name
, linep
);
132 (void)tcsetattr(slave
, TCSAFLUSH
, term
);
134 (void)ioctl(slave
, TIOCSWINSZ
, winp
);
140 errno
= ENOENT
; /* out of ptys */
145 forkpty(int *amaster
, char *name
, struct termios
*term
, struct winsize
*winp
)
150 _DIAGASSERT(amaster
!= NULL
);
151 /* name may be NULL */
152 /* term may be NULL */
153 /* winp may be NULL */
155 if (openpty(&master
, &slave
, name
, term
, winp
) == -1)
157 switch (pid
= fork()) {