• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *   Copyright (c) International Business Machines  Corp., 2002
4  *
5  *   This program is free software;  you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  *   the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program;  if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 /* 12/23/2002   Port to LTP     robbiew@us.ibm.com */
21 /* 06/30/2001   Port to Linux   nsharoff@us.ibm.com */
22 
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <termio.h>
28 #include <fcntl.h>
29 #include <sys/stat.h>
30 #include <sys/poll.h>
31 #include <sys/types.h>
32 
33 #ifndef _GNU_SOURCE
34 #define _GNU_SOURCE 1
35 #endif
36 
37 /** LTP Port **/
38 #include "test.h"
39 #include "safe_macros.h"
40 
41 char *TCID = "ptem01";		/* Test program identifier.    */
42 int TST_TOTAL = 6;		/* Total number of test cases. */
43 /**************/
44 
45 /*
46  * pty master clone device
47  */
48 #define MASTERCLONE "/dev/ptmx"
49 
50 #define BUFSZ 4096
51 
52 /*
53  * test termio/termios ioctls
54  */
test1(void)55 int test1(void)
56 {
57 	int masterfd, slavefd;
58 	char *slavename;
59 	struct termio termio;
60 	struct termios termios;
61 
62 	masterfd = SAFE_OPEN(NULL, MASTERCLONE, O_RDWR);
63 
64 	slavename = ptsname(masterfd);
65 	if (slavename == NULL) {
66 		tst_brkm(TBROK | TERRNO, NULL, "ptsname() call failed");
67 	}
68 
69 	if (grantpt(masterfd) != 0) {
70 		tst_brkm(TBROK | TERRNO, NULL, "grantpt() call failed");
71 	}
72 
73 	if (unlockpt(masterfd) != 0) {
74 		tst_brkm(TBROK, NULL, "unlockpt() call failed");
75 	}
76 
77 	if ((slavefd = open(slavename, O_RDWR)) < 0) {
78 		tst_brkm(TFAIL, NULL, "Could not open %s", slavename);
79 	}
80 
81 	if (ioctl(slavefd, TCGETS, &termios) != 0) {
82 		tst_brkm(TFAIL, NULL, "TCGETS");
83 	}
84 
85 	if (ioctl(slavefd, TCSETS, &termios) != 0) {
86 		tst_brkm(TFAIL, NULL, "TCSETS");
87 	}
88 
89 	if (ioctl(slavefd, TCSETSW, &termios) != 0) {
90 		tst_brkm(TFAIL, NULL, "TCSETSW");
91 	}
92 
93 	if (ioctl(slavefd, TCSETSF, &termios) != 0) {
94 		tst_brkm(TFAIL, NULL, "TCSETSF");
95 	}
96 
97 	if (ioctl(slavefd, TCSETS, &termios) != 0) {
98 		tst_brkm(TFAIL, NULL, "TCSETS");
99 	}
100 
101 	if (ioctl(slavefd, TCGETA, &termio) != 0) {
102 		tst_brkm(TFAIL, NULL, "TCGETA");
103 	}
104 
105 	if (ioctl(slavefd, TCSETA, &termio) != 0) {
106 		tst_brkm(TFAIL, NULL, "TCSETA");
107 	}
108 
109 	if (ioctl(slavefd, TCSETAW, &termio) != 0) {
110 		tst_brkm(TFAIL, NULL, "TCSETAW");
111 	}
112 
113 	if (ioctl(slavefd, TCSETAF, &termio) != 0) {
114 		tst_brkm(TFAIL, NULL, "TCSETAF");
115 	}
116 
117 	if (close(slavefd) != 0) {
118 		tst_brkm(TBROK, NULL, "close slave");
119 	}
120 
121 	if (close(masterfd) != 0) {
122 		tst_brkm(TBROK, NULL, "close master");
123 	}
124 	tst_resm(TPASS, "test1");
125 
126 	/** NOT REACHED **/
127 	return 0;
128 }
129 
130 /*
131  * test window size setting and getting
132  */
test2(void)133 int test2(void)
134 {
135 	int masterfd, slavefd;
136 	char *slavename;
137 	struct winsize wsz;
138 	struct winsize wsz1 = { 24, 80, 5, 10 };
139 	struct winsize wsz2 = { 60, 100, 11, 777 };
140 
141 	masterfd = SAFE_OPEN(NULL, MASTERCLONE, O_RDWR);
142 
143 	slavename = ptsname(masterfd);
144 	if (slavename == NULL) {
145 		tst_brkm(TBROK | TERRNO, NULL, "ptsname() call failed");
146 	}
147 
148 	if (grantpt(masterfd) != 0) {
149 		tst_brkm(TBROK | TERRNO, NULL, "grantpt() call failed");
150 	}
151 
152 	if (unlockpt(masterfd) != 0) {
153 		tst_brkm(TBROK, NULL, "unlockpt() call failed");
154 	}
155 
156 	if ((slavefd = open(slavename, O_RDWR)) < 0) {
157 		tst_brkm(TBROK, NULL, "Could not open %s", slavename);
158 	}
159 
160 	if (ioctl(masterfd, TIOCSWINSZ, &wsz1) != 0) {
161 		tst_brkm(TFAIL, NULL, "TIOCSWINSZ");
162 	}
163 
164 	if (ioctl(slavefd, TIOCGWINSZ, &wsz) != 0) {
165 		tst_brkm(TFAIL, NULL, "TIOCGWINSZ");
166 	}
167 
168 	if (wsz.ws_row != wsz1.ws_row || wsz.ws_col != wsz1.ws_col ||
169 	    wsz.ws_xpixel != wsz1.ws_xpixel ||
170 	    wsz.ws_ypixel != wsz1.ws_ypixel) {
171 		tst_brkm(TFAIL, NULL, "unexpected window size returned");
172 	}
173 
174 	if (ioctl(masterfd, TIOCGWINSZ, &wsz) != 0) {
175 		tst_brkm(TFAIL, NULL, "TIOCGWINSZ");
176 	}
177 
178 	if (wsz.ws_row != wsz1.ws_row || wsz.ws_col != wsz1.ws_col ||
179 	    wsz.ws_xpixel != wsz1.ws_xpixel ||
180 	    wsz.ws_ypixel != wsz1.ws_ypixel) {
181 		tst_brkm(TFAIL, NULL, "unexpected window size returned");
182 	}
183 
184 	if (ioctl(slavefd, TIOCSWINSZ, &wsz2) != 0) {
185 		tst_brkm(TFAIL, NULL, "TIOCSWINSZ");
186 	}
187 
188 	if (ioctl(slavefd, TIOCGWINSZ, &wsz) != 0) {
189 		tst_brkm(TFAIL, NULL, "TIOCGWINSZ");
190 	}
191 
192 	if (wsz.ws_row != wsz2.ws_row || wsz.ws_col != wsz2.ws_col ||
193 	    wsz.ws_xpixel != wsz2.ws_xpixel ||
194 	    wsz.ws_ypixel != wsz2.ws_ypixel) {
195 		tst_brkm(TFAIL, NULL, "unexpected window size returned");
196 	}
197 
198 	if (close(slavefd) != 0) {
199 		tst_brkm(TBROK, NULL, "close");
200 	}
201 
202 	if (close(masterfd) != 0) {
203 		tst_brkm(TBROK, NULL, "close");
204 	}
205 	tst_resm(TPASS, "test2");
206 
207 	/** NOT REACHED **/
208 	return 0;
209 }
210 
211 /*
212  * test sending a break
213  */
test3(void)214 int test3(void)
215 {
216 	int masterfd, slavefd;
217 	char *slavename;
218 
219 	masterfd = SAFE_OPEN(NULL, MASTERCLONE, O_RDWR);
220 
221 	slavename = ptsname(masterfd);
222 	if (slavename == NULL) {
223 		tst_brkm(TBROK | TERRNO, NULL, "ptsname() call failed");
224 	}
225 
226 	if (grantpt(masterfd) != 0) {
227 		tst_brkm(TBROK | TERRNO, NULL, "grantpt() call failed");
228 	}
229 
230 	if (unlockpt(masterfd) != 0) {
231 		tst_brkm(TBROK, NULL, "unlockpt() call failed");
232 	}
233 
234 	if ((slavefd = open(slavename, O_RDWR)) < 0) {
235 		tst_brkm(TBROK, NULL, "Could not open %s", slavename);
236 	}
237 
238 	if (tcsendbreak(masterfd, 10) != 0) {
239 		tst_brkm(TFAIL, NULL, "tcsendbreak");
240 	}
241 
242 	if (tcsendbreak(slavefd, 10) != 0) {
243 		tst_brkm(TFAIL, NULL, "tcsendbreak");
244 	}
245 
246 	if (close(slavefd) != 0) {
247 		tst_brkm(TBROK, NULL, "close slave");
248 	}
249 
250 	if (close(masterfd) != 0) {
251 		tst_brkm(TBROK, NULL, "close master");
252 	}
253 	tst_resm(TPASS, "test3");
254 
255 	/** NOT REACHED **/
256 	return 0;
257 }
258 
259 /*
260  * test multiple opens of slave side
261  */
test4(void)262 int test4(void)
263 {
264 	int masterfd, slavefd, slavefd2, slavefd3;
265 	char *slavename;
266 
267 	masterfd = SAFE_OPEN(NULL, MASTERCLONE, O_RDWR);
268 
269 	slavename = ptsname(masterfd);
270 	if (slavename == NULL) {
271 		tst_brkm(TBROK | TERRNO, NULL, "ptsname() call failed");
272 	}
273 
274 	if (grantpt(masterfd) != 0) {
275 		tst_brkm(TBROK | TERRNO, NULL, "grantpt() call failed");
276 	}
277 
278 	if (unlockpt(masterfd) != 0) {
279 		tst_brkm(TBROK, NULL, "unlockpt() call failed");
280 	}
281 
282 	if ((slavefd = open(slavename, O_RDWR)) < 0) {
283 		tst_brkm(TBROK, NULL, "Could not open %s", slavename);
284 	}
285 
286 	if ((slavefd2 = open(slavename, O_RDWR)) < 0) {
287 		tst_brkm(TFAIL, NULL, "Could not open %s (again)", slavename);
288 	}
289 
290 	if ((slavefd3 = open(slavename, O_RDWR)) < 0) {
291 		tst_brkm(TFAIL, NULL, "Could not open %s (once more)",
292 			 slavename);
293 	}
294 
295 	if (close(slavefd) != 0) {
296 		tst_brkm(TBROK, NULL, "close slave");
297 	}
298 	if (close(slavefd2) != 0) {
299 		tst_brkm(TBROK, NULL, "close slave again");
300 	}
301 	if (close(slavefd3) != 0) {
302 		tst_brkm(TBROK, NULL, "close slave once more");
303 	}
304 	if (close(masterfd) != 0) {
305 		tst_brkm(TBROK, NULL, "close master");
306 	}
307 	tst_resm(TPASS, "test4");
308 
309 	/** NOT REACHED **/
310 	return 0;
311 }
312 
313 #define NUMOPENS 6
314 
315 /*
316  * test several simultaneous opens
317  */
test5(void)318 int test5(void)
319 {
320 	static int masterfd[NUMOPENS];
321 	static int slavefd[NUMOPENS];
322 	char *slavename;
323 	int i;
324 
325 	for (i = 0; i < NUMOPENS; ++i) {
326 		masterfd[i] = open(MASTERCLONE, O_RDWR);
327 		if (masterfd[i] < 0) {
328 			tst_resm(TBROK, "%s", MASTERCLONE);
329 			tst_resm(TBROK, "out of ptys");
330 			for (i = 0; i < NUMOPENS; ++i) {
331 				if (masterfd[i] != 0) {
332 					(void)close(masterfd[i]);
333 				}
334 				if (slavefd[i] != 0) {
335 					(void)close(slavefd[i]);
336 				}
337 			}
338 			tst_exit();
339 		}
340 
341 		slavename = ptsname(masterfd[i]);
342 		if (slavename == NULL) {
343 			tst_brkm(TBROK | TERRNO, NULL,
344 				 "ptsname() call failed");
345 		}
346 
347 		if (grantpt(masterfd[i]) != 0) {
348 			tst_brkm(TBROK | TERRNO, NULL,
349 				 "grantpt() call failed");
350 		}
351 
352 		if (unlockpt(masterfd[i]) != 0) {
353 			tst_brkm(TBROK, NULL, "unlockpt() call failed");
354 		}
355 
356 		if ((slavefd[i] = open(slavename, O_RDWR)) < 0) {
357 			tst_brkm(TFAIL, NULL,
358 				 "Iteration %d: Could not open %s", i,
359 				 slavename);
360 		}
361 
362 	}
363 
364 	for (i = 0; i < NUMOPENS; ++i) {
365 		if (close(slavefd[i]) != 0) {
366 			tst_brkm(TBROK, NULL, "Iteration %d: close slave", i);
367 		}
368 		if (close(masterfd[i]) != 0) {
369 			tst_brkm(TBROK, NULL, "close master");
370 		}
371 	}
372 	tst_resm(TPASS, "test5");
373 
374 	/** NOT REACHED **/
375 	return 0;
376 }
377 
378 /*
379  * test hangup semantics
380  */
test6(void)381 int test6(void)
382 {
383 	static int masterfd;
384 	static int slavefd;
385 	char *slavename;
386 	struct termios termios;
387 
388 	masterfd = SAFE_OPEN(NULL, MASTERCLONE, O_RDWR);
389 
390 	slavename = ptsname(masterfd);
391 	if (slavename == NULL) {
392 		tst_brkm(TBROK | TERRNO, NULL, "ptsname() call failed");
393 	}
394 
395 	if (grantpt(masterfd) != 0) {
396 		tst_brkm(TBROK | TERRNO, NULL, "grantpt() call failed");
397 	}
398 
399 	if (unlockpt(masterfd) != 0) {
400 		tst_brkm(TBROK, NULL, "unlockpt() call failed");
401 	}
402 
403 	if ((slavefd = open(slavename, O_RDWR)) < 0) {
404 		tst_brkm(TBROK, NULL, "Could not open %s", slavename);
405 	}
406 
407 	if (ioctl(slavefd, TCGETS, &termios) != 0) {
408 		tst_brkm(TFAIL, NULL, "TCGETS");
409 	}
410 
411 	termios.c_cflag &= ~CBAUD;
412 	termios.c_cflag |= B0 & CBAUD;
413 	if (ioctl(slavefd, TCSETS, &termios) != 0) {
414 		tst_brkm(TFAIL, NULL, "TCGETS");
415 	}
416 
417 	if (close(slavefd) != 0) {
418 		tst_brkm(TBROK, NULL, "close");
419 	}
420 	if (close(masterfd) != 0) {
421 		tst_brkm(TBROK, NULL, "close");
422 	}
423 	tst_resm(TPASS, "test6");
424 
425 	/** NOT REACHED **/
426 	return 0;
427 }
428 
429 /*
430  * main test driver
431  */
main(int argc,char ** argv)432 int main(int argc, char **argv)
433 {
434 	test1();
435 	test2();
436 	test3();
437 	test4();
438 	test5();
439 	test6();
440 	/*
441 	 * all done
442 	 */
443 	tst_exit();
444 }
445