picolisp: Update from 18.1.24 to 18.4.26
[termux-packages] / packages / libutil / pty.c
CommitLineData
2044012d
FF
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
b833ad7a 10int openpty(int* amaster, int* aslave, char* name, const struct termios* termp, const struct winsize* winp)
2044012d
FF
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
30fail:
31 close(master);
32 return -1;
33}
34
35
36int 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
b833ad7a 48int forkpty(int* amaster, char* name, const struct termios* termp, const struct winsize* winp)
2044012d
FF
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}