Print this page
12306 XPG4v2 slave pty behaviour should generally be disabled
Reviewed by: Robert Mustacchi <rm@fingolfin.org>
Change-ID: I7ccd399c22866f34dd20c6bb9d28e77ba4e24c67
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libc/port/gen/pt.c
+++ new/usr/src/lib/libc/port/gen/pt.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 +/*
28 + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
29 + */
30 +
27 31 /* Copyright (c) 1988 AT&T */
28 -/* All Rights Reserved */
32 +/* All Rights Reserved */
29 33
30 -#pragma ident "%Z%%M% %I% %E% SMI"
31 -
32 34 #pragma weak _ptsname = ptsname
33 35 #pragma weak _grantpt = grantpt
34 36 #pragma weak _unlockpt = unlockpt
35 37
36 38 #include "lint.h"
37 39 #include "libc.h"
38 40 #include "mtlib.h"
39 41 #include <sys/types.h>
40 42 #include <signal.h>
41 43 #include <sys/param.h>
42 44 #include <sys/mkdev.h>
43 45 #include <sys/stream.h>
44 46 #include <sys/stropts.h>
45 47 #include <sys/wait.h>
46 48 #include <sys/signal.h>
47 49 #include <errno.h>
48 50 #include <fcntl.h>
49 51 #include <sys/stat.h>
50 52 #include <sys/ptms.h>
51 53 #include <string.h>
52 54 #include <stdlib.h>
53 55 #include <unistd.h>
54 56 #include <wait.h>
55 57 #include <spawn.h>
56 58 #include <grp.h>
57 59 #include "tsd.h"
58 60
59 61 #define PTSNAME "/dev/pts/" /* slave name */
60 62 #define PTLEN 32 /* slave name length */
61 63 #define DEFAULT_TTY_GROUP "tty" /* slave device group owner */
62 64
63 65 static void itoa(int, char *);
64 66
65 67 /*
66 68 * Check that fd argument is a file descriptor of an opened master.
67 69 * Do this by sending an ISPTM ioctl message down stream. Ioctl()
68 70 * will fail if:(1) fd is not a valid file descriptor.(2) the file
69 71 * represented by fd does not understand ISPTM(not a master device).
70 72 * If we have a valid master, get its minor number via fstat().
71 73 * Concatenate it to PTSNAME and return it as the name of the slave
72 74 * device.
73 75 */
74 76 static dev_t
75 77 ptsdev(int fd)
76 78 {
77 79 struct stat64 status;
78 80 struct strioctl istr;
79 81
80 82 istr.ic_cmd = ISPTM;
81 83 istr.ic_len = 0;
82 84 istr.ic_timout = 0;
83 85 istr.ic_dp = NULL;
84 86
85 87 if (ioctl(fd, I_STR, &istr) < 0 || fstat64(fd, &status) < 0)
86 88 return (NODEV);
87 89
88 90 return (minor(status.st_rdev));
89 91 }
90 92
91 93 char *
92 94 ptsname(int fd)
93 95 {
94 96 dev_t dev;
95 97 char *sname;
96 98
97 99 if ((dev = ptsdev(fd)) == NODEV)
98 100 return (NULL);
99 101
100 102 sname = tsdalloc(_T_PTSNAME, PTLEN, NULL);
101 103 if (sname == NULL)
102 104 return (NULL);
103 105 (void) strcpy(sname, PTSNAME);
104 106 itoa(dev, sname + strlen(PTSNAME));
105 107
106 108 /*
107 109 * This lookup will create the /dev/pts node (if the corresponding
108 110 * pty exists.
109 111 */
110 112 if (access(sname, F_OK) == 0)
111 113 return (sname);
112 114
113 115 return (NULL);
114 116 }
115 117
116 118 /*
117 119 * Send an ioctl down to the master device requesting the
118 120 * master/slave pair be unlocked.
119 121 */
120 122 int
121 123 unlockpt(int fd)
122 124 {
123 125 struct strioctl istr;
124 126
125 127 istr.ic_cmd = UNLKPT;
↓ open down ↓ |
84 lines elided |
↑ open up ↑ |
126 128 istr.ic_len = 0;
127 129 istr.ic_timout = 0;
128 130 istr.ic_dp = NULL;
129 131
130 132 if (ioctl(fd, I_STR, &istr) < 0)
131 133 return (-1);
132 134
133 135 return (0);
134 136 }
135 137
138 +/*
139 + * XPG4v2 requires that open of a slave pseudo terminal device
140 + * provides the process with an interface that is identical to
141 + * the terminal interface.
142 + *
143 + * To satisfy this, in strict XPG4v2 mode, this routine also sends
144 + * a message down the stream that sets a flag in the kernel module
145 + * so that additional actions are performed when opening an
146 + * associated slave PTY device. When this happens, modules are
147 + * automatically pushed onto the stream to provide terminal
148 + * semantics and those modules are then informed that they should
149 + * behave in strict XPG4v2 mode which modifies their behaviour. In
150 + * particular, in strict XPG4v2 mode, empty blocks will be sent up
151 + * the master side of the stream rather than being suppressed.
152 + *
153 + * Most applications do not expect this behaviour so it is only
154 + * enabled for programs compiled in strict XPG4v2 mode (see
155 + * stdlib.h).
156 + */
157 +int
158 +__unlockpt_xpg4(int fd)
159 +{
160 + int ret;
161 +
162 + if ((ret = unlockpt(fd)) == 0) {
163 + struct strioctl istr;
164 +
165 + istr.ic_cmd = PTSSTTY;
166 + istr.ic_len = 0;
167 + istr.ic_timout = 0;
168 + istr.ic_dp = NULL;
169 +
170 + if (ioctl(fd, I_STR, &istr) < 0)
171 + ret = -1;
172 + }
173 +
174 + return (ret);
175 +}
176 +
136 177 int
137 178 grantpt(int fd)
138 179 {
139 180 struct strioctl istr;
140 181 pt_own_t pto;
141 182 struct group *gr_name;
142 183
143 184 /* validate the file descriptor before proceeding */
144 185 if (ptsdev(fd) == NODEV)
145 186 return (-1);
146 187
147 188 pto.pto_ruid = getuid();
148 189
149 190 gr_name = getgrnam(DEFAULT_TTY_GROUP);
150 191 if (gr_name)
151 192 pto.pto_rgid = gr_name->gr_gid;
152 193 else
153 194 pto.pto_rgid = getgid();
154 195
155 196 istr.ic_cmd = OWNERPT;
156 197 istr.ic_len = sizeof (pt_own_t);
157 198 istr.ic_timout = 0;
158 199 istr.ic_dp = (char *)&pto;
159 200
160 201 if (ioctl(fd, I_STR, &istr) != 0) {
161 202 errno = EACCES;
162 203 return (-1);
163 204 }
164 205
165 206 return (0);
166 207 }
167 208
168 209 /*
169 210 * Send an ioctl down to the master device requesting the master/slave pair
170 211 * be assigned to the given zone.
171 212 */
172 213 int
173 214 zonept(int fd, zoneid_t zoneid)
174 215 {
175 216 struct strioctl istr;
176 217
177 218 istr.ic_cmd = ZONEPT;
178 219 istr.ic_len = sizeof (zoneid);
179 220 istr.ic_timout = 0;
180 221 istr.ic_dp = (char *)&zoneid;
181 222
182 223 if (ioctl(fd, I_STR, &istr) != 0) {
183 224 return (-1);
184 225 }
185 226 return (0);
186 227 }
187 228
188 229
189 230 static void
190 231 itoa(int i, char *ptr)
191 232 {
192 233 int dig = 0;
193 234 int tempi;
194 235
195 236 tempi = i;
196 237 do {
197 238 dig++;
198 239 tempi /= 10;
199 240 } while (tempi);
200 241
201 242 ptr += dig;
202 243 *ptr = '\0';
203 244 while (--dig >= 0) {
204 245 *(--ptr) = i % 10 + '0';
205 246 i /= 10;
206 247 }
207 248 }
208 249
209 250
210 251 /*
211 252 * added for SUSv3 standard
212 253 *
213 254 * Open a pseudo-terminal device. External interface.
214 255 */
215 256
216 257 int
217 258 posix_openpt(int oflag)
218 259 {
219 260 return (open("/dev/ptmx", oflag));
220 261 }
↓ open down ↓ |
75 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX