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