1 /*-
2 * Copyright (c) 1990, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)pty.c 8.3 (Berkeley) 05/16/94";
10 #endif /* LIBC_SCCS and not lint */
11
12 #include <sys/types.h>
13 #include <sys/ioctl.h>
14 #include <sys/stat.h>
15
16 #include <errno.h>
17 #include <fcntl.h>
18 #include <grp.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <termios.h>
23 #include <unistd.h>
24
openpty(amaster,aslave,name,termp,winp)25 openpty(amaster, aslave, name, termp, winp)
26 int *amaster, *aslave;
27 char *name;
28 struct termios *termp;
29 struct winsize *winp;
30 {
31 static char line[] = "/dev/ptyXX";
32 register const char *cp1, *cp2;
33 register int master, slave, ttygid;
34 struct group *gr;
35
36 if ((gr = getgrnam("tty")) != NULL)
37 ttygid = gr->gr_gid;
38 else
39 ttygid = -1;
40
41 for (cp1 = "pqrs"; *cp1; cp1++) {
42 line[8] = *cp1;
43 for (cp2 = "0123456789abcdef"; *cp2; cp2++) {
44 line[5] = 'p';
45 line[9] = *cp2;
46 if ((master = open(line, O_RDWR, 0)) == -1) {
47 if (errno == ENOENT)
48 return (-1); /* out of ptys */
49 } else {
50 line[5] = 't';
51 (void) chown(line, getuid(), ttygid);
52 (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
53 (void) revoke(line);
54 if ((slave = open(line, O_RDWR, 0)) != -1) {
55 *amaster = master;
56 *aslave = slave;
57 if (name)
58 strcpy(name, line);
59 if (termp)
60 (void) tcsetattr(slave,
61 TCSAFLUSH, termp);
62 if (winp)
63 (void) ioctl(slave, TIOCSWINSZ,
64 (char *)winp);
65 return (0);
66 }
67 (void) close(master);
68 }
69 }
70 }
71 errno = ENOENT; /* out of ptys */
72 return (-1);
73 }
74
forkpty(amaster,name,termp,winp)75 forkpty(amaster, name, termp, winp)
76 int *amaster;
77 char *name;
78 struct termios *termp;
79 struct winsize *winp;
80 {
81 int master, slave, pid;
82
83 if (openpty(&master, &slave, name, termp, winp) == -1)
84 return (-1);
85 switch (pid = fork()) {
86 case -1:
87 return (-1);
88 case 0:
89 /*
90 * child
91 */
92 (void) close(master);
93 login_tty(slave);
94 return (0);
95 }
96 /*
97 * parent
98 */
99 *amaster = master;
100 (void) close(slave);
101 return (pid);
102 }
103