]> andersk Git - openssh.git/blame - openbsd-compat/bsd-openpty.c
- (dtucker) [openbsd-compat/bsd-misc.c] Include <sys/select.h> for select(2)
[openssh.git] / openbsd-compat / bsd-openpty.c
CommitLineData
a4de1163 1/*
2 * Please note: this implementation of openpty() is far from complete.
3 * it is just enough for portable OpenSSH's needs.
4 */
5
6/*
9cd11896 7 * Copyright (c) 2004 Damien Miller <djm@mindrot.org>
a4de1163 8 *
9cd11896 9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
a4de1163 12 *
9cd11896 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
a4de1163 20 */
21
22/*
23 * Author: Tatu Ylonen <ylo@cs.hut.fi>
24 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
25 * All rights reserved
26 * Allocating a pseudo-terminal, and making it the controlling tty.
27 *
28 * As far as I am concerned, the code I have written for this software
29 * can be used freely for any purpose. Any derived versions of this
30 * software must be clearly marked as such, and if the derived work is
31 * incompatible with the protocol description in the RFC file, it must be
32 * called by a name other than "ssh" or "Secure Shell".
33 */
34
35#include "includes.h"
36#if !defined(HAVE_OPENPTY)
37
37259a8e 38#include <sys/types.h>
39
442a6515 40#include <stdlib.h>
41
37259a8e 42#ifdef HAVE_SYS_STAT_H
43# include <sys/stat.h>
44#endif
45
46#ifdef HAVE_FCNTL_H
47# include <fcntl.h>
48#endif
49
a4de1163 50#ifdef HAVE_UTIL_H
51# include <util.h>
52#endif /* HAVE_UTIL_H */
53
54#ifdef HAVE_PTY_H
55# include <pty.h>
56#endif
57#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H)
58# include <sys/stropts.h>
59#endif
60
b5b88c19 61#include <signal.h>
e204f3ee 62#include <string.h>
63#include <unistd.h>
b5b88c19 64
a4de1163 65#ifndef O_NOCTTY
66#define O_NOCTTY 0
67#endif
68
69int
70openpty(int *amaster, int *aslave, char *name, struct termios *termp,
71 struct winsize *winp)
72{
73#if defined(HAVE__GETPTY)
74 /*
75 * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
76 * pty's automagically when needed
77 */
78 char *slave;
79
80 if ((slave = _getpty(amaster, O_RDWR, 0622, 0)) == NULL)
81 return (-1);
82
83 /* Open the slave side. */
84 if ((*aslave = open(slave, O_RDWR | O_NOCTTY)) == -1) {
85 close(*amaster);
86 return (-1);
87 }
88 return (0);
89
90#elif defined(HAVE_DEV_PTMX)
91 /*
92 * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3
93 * also has bsd-style ptys, but they simply do not work.)
94 */
95 int ptm;
96 char *pts;
97 mysig_t old_signal;
98
99 if ((ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1)
100 return (-1);
101
102 /* XXX: need to close ptm on error? */
103 old_signal = signal(SIGCHLD, SIG_DFL);
104 if (grantpt(ptm) < 0)
105 return (-1);
106 signal(SIGCHLD, old_signal);
107
108 if (unlockpt(ptm) < 0)
109 return (-1);
110
111 if ((pts = ptsname(ptm)) == NULL)
112 return (-1);
113 *amaster = ptm;
114
115 /* Open the slave side. */
116 if ((*aslave = open(pts, O_RDWR | O_NOCTTY)) == -1) {
117 close(*amaster);
118 return (-1);
119 }
120
a4de1163 121 /*
122 * Try to push the appropriate streams modules, as described
123 * in Solaris pts(7).
124 */
125 ioctl(*aslave, I_PUSH, "ptem");
126 ioctl(*aslave, I_PUSH, "ldterm");
127# ifndef __hpux
128 ioctl(*aslave, I_PUSH, "ttcompat");
129# endif /* __hpux */
a4de1163 130
131 return (0);
132
133#elif defined(HAVE_DEV_PTS_AND_PTC)
134 /* AIX-style pty code. */
135 const char *ttname;
136
137 if ((*amaster = open("/dev/ptc", O_RDWR | O_NOCTTY)) == -1)
138 return (-1);
139 if ((ttname = ttyname(*amaster)) == NULL)
140 return (-1);
141 if ((*aslave = open(ttname, O_RDWR | O_NOCTTY)) == -1) {
142 close(*amaster);
143 return (-1);
144 }
145 return (0);
146
147#elif defined(_UNICOS)
148 char ptbuf[64], ttbuf[64];
149 int i;
150 int highpty;
151
152 highpty = 128;
153#ifdef _SC_CRAY_NPTY
154 if ((highpty = sysconf(_SC_CRAY_NPTY)) == -1)
155 highpty = 128;
156#endif /* _SC_CRAY_NPTY */
157
158 for (i = 0; i < highpty; i++) {
159 snprintf(ptbuf, sizeof(ptbuf), "/dev/pty/%03d", i);
6e9f4c0f 160 snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%03d", i);
a4de1163 161 if ((*amaster = open(ptbuf, O_RDWR|O_NOCTTY)) == -1)
162 continue;
163 /* Open the slave side. */
164 if ((*aslave = open(ttbuf, O_RDWR|O_NOCTTY)) == -1) {
165 close(*amaster);
166 return (-1);
167 }
168 return (0);
169 }
170 return (-1);
171
172#else
173 /* BSD-style pty code. */
174 char ptbuf[64], ttbuf[64];
175 int i;
176 const char *ptymajors = "pqrstuvwxyzabcdefghijklmno"
177 "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
178 const char *ptyminors = "0123456789abcdef";
179 int num_minors = strlen(ptyminors);
180 int num_ptys = strlen(ptymajors) * num_minors;
181 struct termios tio;
182
183 for (i = 0; i < num_ptys; i++) {
184 snprintf(ptbuf, sizeof(ptbuf), "/dev/pty%c%c",
185 ptymajors[i / num_minors], ptyminors[i % num_minors]);
186 snprintf(ttbuf, sizeof(ttbuf), "/dev/tty%c%c",
187 ptymajors[i / num_minors], ptyminors[i % num_minors]);
188
189 if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1) {
190 /* Try SCO style naming */
191 snprintf(ptbuf, sizeof(ptbuf), "/dev/ptyp%d", i);
192 snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%d", i);
193 if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1)
194 continue;
195 }
196
197 /* Open the slave side. */
198 if ((*aslave = open(ttbuf, O_RDWR | O_NOCTTY)) == -1) {
199 close(*amaster);
200 return (-1);
201 }
202 /* set tty modes to a sane state for broken clients */
203 if (tcgetattr(*amaster, &tio) != -1) {
204 tio.c_lflag |= (ECHO | ISIG | ICANON);
205 tio.c_oflag |= (OPOST | ONLCR);
206 tio.c_iflag |= ICRNL;
207 tcsetattr(*amaster, TCSANOW, &tio);
208 }
209
210 return (0);
211 }
212 return (-1);
213#endif
214}
215
216#endif /* !defined(HAVE_OPENPTY) */
217
This page took 0.191854 seconds and 5 git commands to generate.