142963Smarc /*-
2*67148Sbostic * Copyright (c) 1990, 1993, 1994
361348Sbostic * The Regents of the University of California. All rights reserved.
442963Smarc *
542963Smarc * %sccs.include.redist.c%
642963Smarc */
742963Smarc
842963Smarc #if defined(LIBC_SCCS) && !defined(lint)
9*67148Sbostic static char sccsid[] = "@(#)pty.c 8.3 (Berkeley) 05/16/94";
1042963Smarc #endif /* LIBC_SCCS and not lint */
1142963Smarc
1245348Sbostic #include <sys/types.h>
13*67148Sbostic #include <sys/ioctl.h>
1445348Sbostic #include <sys/stat.h>
15*67148Sbostic
16*67148Sbostic #include <errno.h>
1746724Sbostic #include <fcntl.h>
18*67148Sbostic #include <grp.h>
19*67148Sbostic #include <stdio.h>
20*67148Sbostic #include <stdlib.h>
21*67148Sbostic #include <string.h>
2244569Smarc #include <termios.h>
2346724Sbostic #include <unistd.h>
2442963Smarc
openpty(amaster,aslave,name,termp,winp)2544569Smarc openpty(amaster, aslave, name, termp, winp)
2642963Smarc int *amaster, *aslave;
2742963Smarc char *name;
2844569Smarc struct termios *termp;
2944569Smarc struct winsize *winp;
3042963Smarc {
3146964Sbostic static char line[] = "/dev/ptyXX";
3246724Sbostic register const char *cp1, *cp2;
3345348Sbostic register int master, slave, ttygid;
3444569Smarc struct group *gr;
3542963Smarc
3644569Smarc if ((gr = getgrnam("tty")) != NULL)
3744569Smarc ttygid = gr->gr_gid;
3844569Smarc else
3944569Smarc ttygid = -1;
4044569Smarc
4142963Smarc for (cp1 = "pqrs"; *cp1; cp1++) {
4242963Smarc line[8] = *cp1;
4342963Smarc for (cp2 = "0123456789abcdef"; *cp2; cp2++) {
4467147Sbostic line[5] = 'p';
4542963Smarc line[9] = *cp2;
4642963Smarc if ((master = open(line, O_RDWR, 0)) == -1) {
4747069Smarc if (errno == ENOENT)
4844569Smarc return (-1); /* out of ptys */
4942963Smarc } else {
5042963Smarc line[5] = 't';
5149628Smarc (void) chown(line, getuid(), ttygid);
5249628Smarc (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
5344569Smarc (void) revoke(line);
5442963Smarc if ((slave = open(line, O_RDWR, 0)) != -1) {
5542963Smarc *amaster = master;
5642963Smarc *aslave = slave;
5742963Smarc if (name)
5842963Smarc strcpy(name, line);
5944569Smarc if (termp)
6044569Smarc (void) tcsetattr(slave,
6146724Sbostic TCSAFLUSH, termp);
6244569Smarc if (winp)
6344569Smarc (void) ioctl(slave, TIOCSWINSZ,
6447047Skarels (char *)winp);
6542963Smarc return (0);
6642963Smarc }
6744569Smarc (void) close(master);
6842963Smarc }
6942963Smarc }
7042963Smarc }
7144569Smarc errno = ENOENT; /* out of ptys */
7242963Smarc return (-1);
7342963Smarc }
7444569Smarc
forkpty(amaster,name,termp,winp)7544569Smarc forkpty(amaster, name, termp, winp)
7644569Smarc int *amaster;
7744569Smarc char *name;
7844569Smarc struct termios *termp;
7944569Smarc struct winsize *winp;
8044569Smarc {
8144569Smarc int master, slave, pid;
8244569Smarc
8344569Smarc if (openpty(&master, &slave, name, termp, winp) == -1)
8444569Smarc return (-1);
8544569Smarc switch (pid = fork()) {
8644569Smarc case -1:
8744569Smarc return (-1);
8844569Smarc case 0:
8944569Smarc /*
9044569Smarc * child
9144569Smarc */
9244569Smarc (void) close(master);
9344569Smarc login_tty(slave);
9444569Smarc return (0);
9544569Smarc }
9644569Smarc /*
9744569Smarc * parent
9844569Smarc */
9944569Smarc *amaster = master;
10044569Smarc (void) close(slave);
10144569Smarc return (pid);
10244569Smarc }
103