lldb: Add package (#2341)
[termux-packages] / packages / libutil / pty.c
1 #include <fcntl.h>
2 #include <sys/ioctl.h>
3 #include <sys/param.h>
4 #include <sys/types.h>
5 #include <stdlib.h>
6 #include <termios.h>
7 #include <unistd.h>
8
9
10 int openpty(int* amaster, int* aslave, char* name, const struct termios* termp, const struct winsize* winp)
11 {
12 char buf[512];
13
14 int master = open("/dev/ptmx", O_RDWR);
15 if (master == -1) return -1;
16 if (grantpt(master) || unlockpt(master) || ptsname_r(master, buf, sizeof buf)) goto fail;
17
18 int slave = open(buf, O_RDWR | O_NOCTTY);
19 if (slave == -1) goto fail;
20
21 /* XXX Should we ignore errors here? */
22 if (termp) tcsetattr(slave, TCSAFLUSH, termp);
23 if (winp) ioctl(slave, TIOCSWINSZ, winp);
24
25 *amaster = master;
26 *aslave = slave;
27 if (name != NULL) strcpy(name, buf);
28 return 0;
29
30 fail:
31 close(master);
32 return -1;
33 }
34
35
36 int login_tty(int fd)
37 {
38 setsid();
39 if (ioctl(fd, TIOCSCTTY, NULL) == -1) return -1;
40 dup2(fd, 0);
41 dup2(fd, 1);
42 dup2(fd, 2);
43 if (fd > 2) close(fd);
44 return 0;
45 }
46
47
48 int forkpty(int* amaster, char* name, const struct termios* termp, const struct winsize* winp)
49 {
50 int master, slave;
51 if (openpty(&master, &slave, name, termp, winp) == -1) {
52 return -1;
53 }
54
55 int pid;
56 switch (pid = fork()) {
57 case -1:
58 return -1;
59 case 0:
60 close(master);
61 if (login_tty(slave)) _exit(1);
62 return 0;
63 default:
64 *amaster = master;
65 close (slave);
66 return pid;
67 }
68 }