]> andersk Git - gssapi-openssh.git/blob - openssh/openbsd-compat/bsd-openpty.c
Initial revision
[gssapi-openssh.git] / openssh / openbsd-compat / bsd-openpty.c
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 /*
7  * Copyright (c) 2004 Damien Miller <djm@mindrot.org>
8  *
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.
12  *
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.
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
38 #ifdef HAVE_UTIL_H
39 # include <util.h>
40 #endif /* HAVE_UTIL_H */
41
42 #ifdef HAVE_PTY_H
43 # include <pty.h>
44 #endif
45 #if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H)
46 # include <sys/stropts.h>
47 #endif
48
49 #ifndef O_NOCTTY
50 #define O_NOCTTY 0
51 #endif
52
53 int
54 openpty(int *amaster, int *aslave, char *name, struct termios *termp,
55    struct winsize *winp)
56 {
57 #if defined(HAVE__GETPTY)
58         /*
59          * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
60          * pty's automagically when needed
61          */
62         char *slave;
63
64         if ((slave = _getpty(amaster, O_RDWR, 0622, 0)) == NULL)
65                 return (-1);
66
67         /* Open the slave side. */
68         if ((*aslave = open(slave, O_RDWR | O_NOCTTY)) == -1) {
69                 close(*amaster);
70                 return (-1);
71         }
72         return (0);
73
74 #elif defined(HAVE_DEV_PTMX)
75         /*
76          * This code is used e.g. on Solaris 2.x.  (Note that Solaris 2.3
77          * also has bsd-style ptys, but they simply do not work.)
78          */
79         int ptm;
80         char *pts;
81         mysig_t old_signal;
82
83         if ((ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY)) == -1)
84                 return (-1);
85
86         /* XXX: need to close ptm on error? */
87         old_signal = signal(SIGCHLD, SIG_DFL);
88         if (grantpt(ptm) < 0)
89                 return (-1);
90         signal(SIGCHLD, old_signal);
91
92         if (unlockpt(ptm) < 0)
93                 return (-1);
94
95         if ((pts = ptsname(ptm)) == NULL)
96                 return (-1);
97         *amaster = ptm;
98
99         /* Open the slave side. */
100         if ((*aslave = open(pts, O_RDWR | O_NOCTTY)) == -1) {
101                 close(*amaster);
102                 return (-1);
103         }
104
105         /*
106          * Try to push the appropriate streams modules, as described 
107          * in Solaris pts(7).
108          */
109         ioctl(*aslave, I_PUSH, "ptem");
110         ioctl(*aslave, I_PUSH, "ldterm");
111 # ifndef __hpux
112         ioctl(*aslave, I_PUSH, "ttcompat");
113 # endif /* __hpux */
114
115         return (0);
116
117 #elif defined(HAVE_DEV_PTS_AND_PTC)
118         /* AIX-style pty code. */
119         const char *ttname;
120
121         if ((*amaster = open("/dev/ptc", O_RDWR | O_NOCTTY)) == -1)
122                 return (-1);
123         if ((ttname = ttyname(*amaster)) == NULL)
124                 return (-1);
125         if ((*aslave = open(ttname, O_RDWR | O_NOCTTY)) == -1) {
126                 close(*amaster);
127                 return (-1);
128         }
129         return (0);
130
131 #elif defined(_UNICOS)
132         char ptbuf[64], ttbuf[64];
133         int i;
134         int highpty;
135
136         highpty = 128;
137 #ifdef _SC_CRAY_NPTY
138         if ((highpty = sysconf(_SC_CRAY_NPTY)) == -1)
139                 highpty = 128;
140 #endif /* _SC_CRAY_NPTY */
141
142         for (i = 0; i < highpty; i++) {
143                 snprintf(ptbuf, sizeof(ptbuf), "/dev/pty/%03d", i);
144                 snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%03d", i);
145                 if ((*amaster = open(ptbuf, O_RDWR|O_NOCTTY)) == -1)
146                         continue;
147                 /* Open the slave side. */
148                 if ((*aslave = open(ttbuf, O_RDWR|O_NOCTTY)) == -1) {
149                         close(*amaster);
150                         return (-1);
151                 }
152                 return (0);
153         }
154         return (-1);
155
156 #else
157         /* BSD-style pty code. */
158         char ptbuf[64], ttbuf[64];
159         int i;
160         const char *ptymajors = "pqrstuvwxyzabcdefghijklmno"
161             "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
162         const char *ptyminors = "0123456789abcdef";
163         int num_minors = strlen(ptyminors);
164         int num_ptys = strlen(ptymajors) * num_minors;
165         struct termios tio;
166
167         for (i = 0; i < num_ptys; i++) {
168                 snprintf(ptbuf, sizeof(ptbuf), "/dev/pty%c%c", 
169                     ptymajors[i / num_minors], ptyminors[i % num_minors]);
170                 snprintf(ttbuf, sizeof(ttbuf), "/dev/tty%c%c",
171                     ptymajors[i / num_minors], ptyminors[i % num_minors]);
172
173                 if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1) {
174                         /* Try SCO style naming */
175                         snprintf(ptbuf, sizeof(ptbuf), "/dev/ptyp%d", i);
176                         snprintf(ttbuf, sizeof(ttbuf), "/dev/ttyp%d", i);
177                         if ((*amaster = open(ptbuf, O_RDWR | O_NOCTTY)) == -1)
178                                 continue;
179                 }
180
181                 /* Open the slave side. */
182                 if ((*aslave = open(ttbuf, O_RDWR | O_NOCTTY)) == -1) {
183                         close(*amaster);
184                         return (-1);
185                 }
186                 /* set tty modes to a sane state for broken clients */
187                 if (tcgetattr(*amaster, &tio) != -1) {
188                         tio.c_lflag |= (ECHO | ISIG | ICANON);
189                         tio.c_oflag |= (OPOST | ONLCR);
190                         tio.c_iflag |= ICRNL;
191                         tcsetattr(*amaster, TCSANOW, &tio);
192                 }
193
194                 return (0);
195         }
196         return (-1);
197 #endif
198 }
199
200 #endif /* !defined(HAVE_OPENPTY) */
201
This page took 0.050269 seconds and 5 git commands to generate.