Merge pull request #239 from its-pointless/moshfront
[termux-packages] / packages / mosh / pty.cc.patch
CommitLineData
7901d653 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+}