Merge pull request #239 from its-pointless/moshfront
[termux-packages] / packages / mosh / pty.cc.patch
1 --- ../mosh/src/frontend/pty.cc 2016-04-29 00:42:37.207832463 +1000
2 +++ ./src/frontend/pty.cc 2016-04-29 00:40:31.306486322 +1000
3 @@ -0,0 +1,147 @@
4 +/*
5 + Mosh: the mobile shell
6 + Copyright 2012 Keith Winstein
7 +
8 + This program is free software: you can redistribute it and/or modify
9 + it under the terms of the GNU General Public License as published by
10 + the Free Software Foundation, either version 3 of the License, or
11 + (at your option) any later version.
12 +
13 + This program is distributed in the hope that it will be useful,
14 + but WITHOUT ANY WARRANTY; without even the implied warranty of
15 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 + GNU General Public License for more details.
17 +
18 + You should have received a copy of the GNU General Public License
19 + along with this program. If not, see <http://www.gnu.org/licenses/>.
20 +*/
21 +
22 +#include "config.h"
23 +
24 +#include <sys/types.h>
25 +#include <sys/stat.h>
26 +#include <sys/ioctl.h>
27 +#include <fcntl.h>
28 +#include <termios.h>
29 +#include <unistd.h>
30 +#include <stdlib.h>
31 +#include <errno.h>
32 +#include <string.h>
33 +#include <pty.h>
34 +
35 +#ifndef HAVE_OPENPTY
36 +/* from dropbear 0.53.1 sshpty.c, original license: "can be used freely for any purpose." */
37 +int my_openpty (int *amaster, int *aslave, char *name, const struct termios *termp,
38 + const struct winsize *winp)
39 +{
40 + int master, slave;
41 + char *name_slave;
42 +
43 + master = open("/dev/ptmx", O_RDWR);
44 + if (master == -1) {
45 +// TRACE(("Fail to open master"))
46 + return -1;
47 + }
48 +
49 + if (grantpt(master))
50 + goto fail;
51 +
52 + if (unlockpt(master))
53 + goto fail;
54 +
55 + name_slave = ptsname(master);
56 +// TRACE(("openpty: slave name %s", name_slave))
57 + slave = open(name_slave, O_RDWR | O_NOCTTY);
58 + if (slave == -1)
59 + {
60 + goto fail;
61 + }
62 +
63 + if(termp)
64 + tcsetattr(slave, TCSAFLUSH, termp);
65 + if (winp)
66 + ioctl (slave, TIOCSWINSZ, winp);
67 +
68 + *amaster = master;
69 + *aslave = slave;
70 + if (name != NULL)
71 + strcpy(name, name_slave);
72 +
73 + return 0;
74 +
75 + fail:
76 + close (master);
77 + return -1;
78 +}
79 +#endif
80 +
81 +#ifndef HAVE_LOGIN_TTY
82 +/* from glibc 2.14, login/login_tty.c, under the BSD license */
83 +int login_tty(int fd)
84 +{
85 + (void) setsid();
86 +#ifdef TIOCSCTTY
87 + if (ioctl(fd, TIOCSCTTY, (char *)NULL) == -1)
88 + return (-1);
89 +#else
90 + {
91 + /* This might work. */
92 + char *fdname = ttyname (fd);
93 + int newfd;
94 + if (fdname)
95 + {
96 + if (fd != 0)
97 + (void) close (0);
98 + if (fd != 1)
99 + (void) close (1);
100 + if (fd != 2)
101 + (void) close (2);
102 + newfd = open (fdname, O_RDWR);
103 + (void) close (newfd);
104 + }
105 + }
106 +#endif
107 + while (dup2(fd, 0) == -1 && errno == EBUSY)
108 + ;
109 + while (dup2(fd, 1) == -1 && errno == EBUSY)
110 + ;
111 + while (dup2(fd, 2) == -1 && errno == EBUSY)
112 + ;
113 + if (fd > 2)
114 + (void) close(fd);
115 + return (0);
116 +}
117 +#endif
118 +
119 +int my_forkpty (int *amaster, char *name, const struct termios *termp, const struct winsize *winp) {
120 +#ifdef HAVE_FORKPTY
121 +//return forkpty(amaster, name, termp, winp);
122 +#else
123 +/* from glibc 2.14, login/forkpty.c, under the LGPL 2.1 (or later) license */
124 + int master, slave, pid;
125 +
126 + if (openpty (&master, &slave, name, termp, winp) == -1)
127 + return -1;
128 +
129 + switch (pid = fork ())
130 + {
131 + case -1:
132 + close (master);
133 + close (slave);
134 + return -1;
135 + case 0:
136 + /* Child. */
137 + close (master);
138 + if (login_tty (slave))
139 + _exit (1);
140 +
141 + return 0;
142 + default:
143 + /* Parent. */
144 + *amaster = master;
145 + close (slave);
146 +
147 + return pid;
148 + }
149 +#endif
150 +}