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 (at) us.ibm.com */ 21 /* 06/30/2001 Port to Linux nsharoff (at) 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 <sys/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 40 char *TCID = "ptem01"; /* Test program identifier. */ 41 int TST_TOTAL = 6; /* Total number of test cases. */ 42 /**************/ 43 44 /* 45 * pty master clone device 46 */ 47 #define MASTERCLONE "/dev/ptmx" 48 49 #define BUFSZ 4096 50 51 /* 52 * test termio/termios ioctls 53 */ 54 int test1(void) 55 { 56 int masterfd, slavefd; 57 char *slavename; 58 struct termio termio; 59 struct termios termios; 60 61 masterfd = open(MASTERCLONE, O_RDWR); 62 if (masterfd < 0) { 63 tst_brkm(TBROK, NULL, "%s", MASTERCLONE); 64 } 65 66 slavename = ptsname(masterfd); 67 if (slavename == NULL) { 68 tst_brkm(TBROK | TERRNO, NULL, "ptsname() call failed"); 69 } 70 71 if (grantpt(masterfd) != 0) { 72 tst_brkm(TBROK | TERRNO, NULL, "grantpt() call failed"); 73 } 74 75 if (unlockpt(masterfd) != 0) { 76 tst_brkm(TBROK, NULL, "unlockpt() call failed"); 77 } 78 79 if ((slavefd = open(slavename, O_RDWR)) < 0) { 80 tst_brkm(TFAIL, NULL, "Could not open %s", slavename); 81 } 82 83 if (ioctl(slavefd, TCGETS, &termios) != 0) { 84 tst_brkm(TFAIL, NULL, "TCGETS"); 85 } 86 87 if (ioctl(slavefd, TCSETS, &termios) != 0) { 88 tst_brkm(TFAIL, NULL, "TCSETS"); 89 } 90 91 if (ioctl(slavefd, TCSETSW, &termios) != 0) { 92 tst_brkm(TFAIL, NULL, "TCSETSW"); 93 } 94 95 if (ioctl(slavefd, TCSETSF, &termios) != 0) { 96 tst_brkm(TFAIL, NULL, "TCSETSF"); 97 } 98 99 if (ioctl(slavefd, TCSETS, &termios) != 0) { 100 tst_brkm(TFAIL, NULL, "TCSETS"); 101 } 102 103 if (ioctl(slavefd, TCGETA, &termio) != 0) { 104 tst_brkm(TFAIL, NULL, "TCGETA"); 105 } 106 107 if (ioctl(slavefd, TCSETA, &termio) != 0) { 108 tst_brkm(TFAIL, NULL, "TCSETA"); 109 } 110 111 if (ioctl(slavefd, TCSETAW, &termio) != 0) { 112 tst_brkm(TFAIL, NULL, "TCSETAW"); 113 } 114 115 if (ioctl(slavefd, TCSETAF, &termio) != 0) { 116 tst_brkm(TFAIL, NULL, "TCSETAF"); 117 } 118 119 if (close(slavefd) != 0) { 120 tst_brkm(TBROK, NULL, "close slave"); 121 } 122 123 if (close(masterfd) != 0) { 124 tst_brkm(TBROK, NULL, "close master"); 125 } 126 tst_resm(TPASS, "test1"); 127 128 /** NOT REACHED **/ 129 return 0; 130 } 131 132 /* 133 * test window size setting and getting 134 */ 135 int test2(void) 136 { 137 int masterfd, slavefd; 138 char *slavename; 139 struct winsize wsz; 140 struct winsize wsz1 = { 24, 80, 5, 10 }; 141 struct winsize wsz2 = { 60, 100, 11, 777 }; 142 143 masterfd = open(MASTERCLONE, O_RDWR); 144 if (masterfd < 0) { 145 tst_brkm(TBROK, NULL, "%s", MASTERCLONE); 146 } 147 148 slavename = ptsname(masterfd); 149 if (slavename == NULL) { 150 tst_brkm(TBROK | TERRNO, NULL, "ptsname() call failed"); 151 } 152 153 if (grantpt(masterfd) != 0) { 154 tst_brkm(TBROK | TERRNO, NULL, "grantpt() call failed"); 155 } 156 157 if (unlockpt(masterfd) != 0) { 158 tst_brkm(TBROK, NULL, "unlockpt() call failed"); 159 } 160 161 if ((slavefd = open(slavename, O_RDWR)) < 0) { 162 tst_brkm(TBROK, NULL, "Could not open %s", slavename); 163 } 164 165 if (ioctl(masterfd, TIOCSWINSZ, &wsz1) != 0) { 166 tst_brkm(TFAIL, NULL, "TIOCSWINSZ"); 167 } 168 169 if (ioctl(slavefd, TIOCGWINSZ, &wsz) != 0) { 170 tst_brkm(TFAIL, NULL, "TIOCGWINSZ"); 171 } 172 173 if (wsz.ws_row != wsz1.ws_row || wsz.ws_col != wsz1.ws_col || 174 wsz.ws_xpixel != wsz1.ws_xpixel || 175 wsz.ws_ypixel != wsz1.ws_ypixel) { 176 tst_brkm(TFAIL, NULL, "unexpected window size returned"); 177 } 178 179 if (ioctl(masterfd, TIOCGWINSZ, &wsz) != 0) { 180 tst_brkm(TFAIL, NULL, "TIOCGWINSZ"); 181 } 182 183 if (wsz.ws_row != wsz1.ws_row || wsz.ws_col != wsz1.ws_col || 184 wsz.ws_xpixel != wsz1.ws_xpixel || 185 wsz.ws_ypixel != wsz1.ws_ypixel) { 186 tst_brkm(TFAIL, NULL, "unexpected window size returned"); 187 } 188 189 if (ioctl(slavefd, TIOCSWINSZ, &wsz2) != 0) { 190 tst_brkm(TFAIL, NULL, "TIOCSWINSZ"); 191 } 192 193 if (ioctl(slavefd, TIOCGWINSZ, &wsz) != 0) { 194 tst_brkm(TFAIL, NULL, "TIOCGWINSZ"); 195 } 196 197 if (wsz.ws_row != wsz2.ws_row || wsz.ws_col != wsz2.ws_col || 198 wsz.ws_xpixel != wsz2.ws_xpixel || 199 wsz.ws_ypixel != wsz2.ws_ypixel) { 200 tst_brkm(TFAIL, NULL, "unexpected window size returned"); 201 } 202 203 if (close(slavefd) != 0) { 204 tst_brkm(TBROK, NULL, "close"); 205 } 206 207 if (close(masterfd) != 0) { 208 tst_brkm(TBROK, NULL, "close"); 209 } 210 tst_resm(TPASS, "test2"); 211 212 /** NOT REACHED **/ 213 return 0; 214 } 215 216 /* 217 * test sending a break 218 */ 219 int test3(void) 220 { 221 int masterfd, slavefd; 222 char *slavename; 223 224 masterfd = open(MASTERCLONE, O_RDWR); 225 if (masterfd < 0) { 226 tst_brkm(TBROK, NULL, "%s", MASTERCLONE); 227 } 228 229 slavename = ptsname(masterfd); 230 if (slavename == NULL) { 231 tst_brkm(TBROK | TERRNO, NULL, "ptsname() call failed"); 232 } 233 234 if (grantpt(masterfd) != 0) { 235 tst_brkm(TBROK | TERRNO, NULL, "grantpt() call failed"); 236 } 237 238 if (unlockpt(masterfd) != 0) { 239 tst_brkm(TBROK, NULL, "unlockpt() call failed"); 240 } 241 242 if ((slavefd = open(slavename, O_RDWR)) < 0) { 243 tst_brkm(TBROK, NULL, "Could not open %s", slavename); 244 } 245 246 if (tcsendbreak(masterfd, 10) != 0) { 247 tst_brkm(TFAIL, NULL, "tcsendbreak"); 248 } 249 250 if (tcsendbreak(slavefd, 10) != 0) { 251 tst_brkm(TFAIL, NULL, "tcsendbreak"); 252 } 253 254 if (close(slavefd) != 0) { 255 tst_brkm(TBROK, NULL, "close slave"); 256 } 257 258 if (close(masterfd) != 0) { 259 tst_brkm(TBROK, NULL, "close master"); 260 } 261 tst_resm(TPASS, "test3"); 262 263 /** NOT REACHED **/ 264 return 0; 265 } 266 267 /* 268 * test multiple opens of slave side 269 */ 270 int test4(void) 271 { 272 int masterfd, slavefd, slavefd2, slavefd3; 273 char *slavename; 274 275 masterfd = open(MASTERCLONE, O_RDWR); 276 if (masterfd < 0) { 277 tst_brkm(TBROK, NULL, "%s", MASTERCLONE); 278 } 279 280 slavename = ptsname(masterfd); 281 if (slavename == NULL) { 282 tst_brkm(TBROK | TERRNO, NULL, "ptsname() call failed"); 283 } 284 285 if (grantpt(masterfd) != 0) { 286 tst_brkm(TBROK | TERRNO, NULL, "grantpt() call failed"); 287 } 288 289 if (unlockpt(masterfd) != 0) { 290 tst_brkm(TBROK, NULL, "unlockpt() call failed"); 291 } 292 293 if ((slavefd = open(slavename, O_RDWR)) < 0) { 294 tst_brkm(TBROK, NULL, "Could not open %s", slavename); 295 } 296 297 if ((slavefd2 = open(slavename, O_RDWR)) < 0) { 298 tst_brkm(TFAIL, NULL, "Could not open %s (again)", slavename); 299 } 300 301 if ((slavefd3 = open(slavename, O_RDWR)) < 0) { 302 tst_brkm(TFAIL, NULL, "Could not open %s (once more)", 303 slavename); 304 } 305 306 if (close(slavefd) != 0) { 307 tst_brkm(TBROK, NULL, "close slave"); 308 } 309 if (close(slavefd2) != 0) { 310 tst_brkm(TBROK, NULL, "close slave again"); 311 } 312 if (close(slavefd3) != 0) { 313 tst_brkm(TBROK, NULL, "close slave once more"); 314 } 315 if (close(masterfd) != 0) { 316 tst_brkm(TBROK, NULL, "close master"); 317 } 318 tst_resm(TPASS, "test4"); 319 320 /** NOT REACHED **/ 321 return 0; 322 } 323 324 #define NUMOPENS 6 325 326 /* 327 * test several simultaneous opens 328 */ 329 int test5(void) 330 { 331 static int masterfd[NUMOPENS]; 332 static int slavefd[NUMOPENS]; 333 char *slavename; 334 int i; 335 336 for (i = 0; i < NUMOPENS; ++i) { 337 masterfd[i] = open(MASTERCLONE, O_RDWR); 338 if (masterfd[i] < 0) { 339 tst_resm(TBROK, "%s", MASTERCLONE); 340 tst_resm(TBROK, "out of ptys"); 341 for (i = 0; i < NUMOPENS; ++i) { 342 if (masterfd[i] != 0) { 343 (void)close(masterfd[i]); 344 } 345 if (slavefd[i] != 0) { 346 (void)close(slavefd[i]); 347 } 348 } 349 tst_exit(); 350 } 351 352 slavename = ptsname(masterfd[i]); 353 if (slavename == NULL) { 354 tst_brkm(TBROK | TERRNO, NULL, 355 "ptsname() call failed"); 356 } 357 358 if (grantpt(masterfd[i]) != 0) { 359 tst_brkm(TBROK | TERRNO, NULL, 360 "grantpt() call failed"); 361 } 362 363 if (unlockpt(masterfd[i]) != 0) { 364 tst_brkm(TBROK, NULL, "unlockpt() call failed"); 365 } 366 367 if ((slavefd[i] = open(slavename, O_RDWR)) < 0) { 368 tst_brkm(TFAIL, NULL, 369 "Iteration %d: Could not open %s", i, 370 slavename); 371 } 372 373 } 374 375 for (i = 0; i < NUMOPENS; ++i) { 376 if (close(slavefd[i]) != 0) { 377 tst_brkm(TBROK, NULL, "Iteration %d: close slave", i); 378 } 379 if (close(masterfd[i]) != 0) { 380 tst_brkm(TBROK, NULL, "close master"); 381 } 382 } 383 tst_resm(TPASS, "test5"); 384 385 /** NOT REACHED **/ 386 return 0; 387 } 388 389 /* 390 * test hangup semantics 391 */ 392 int test6(void) 393 { 394 static int masterfd; 395 static int slavefd; 396 char *slavename; 397 struct termios termios; 398 399 masterfd = open(MASTERCLONE, O_RDWR); 400 if (masterfd < 0) { 401 tst_brkm(TBROK, NULL, "%s", MASTERCLONE); 402 } 403 404 slavename = ptsname(masterfd); 405 if (slavename == NULL) { 406 tst_brkm(TBROK | TERRNO, NULL, "ptsname() call failed"); 407 } 408 409 if (grantpt(masterfd) != 0) { 410 tst_brkm(TBROK | TERRNO, NULL, "grantpt() call failed"); 411 } 412 413 if (unlockpt(masterfd) != 0) { 414 tst_brkm(TBROK, NULL, "unlockpt() call failed"); 415 } 416 417 if ((slavefd = open(slavename, O_RDWR)) < 0) { 418 tst_brkm(TBROK, NULL, "Could not open %s", slavename); 419 } 420 421 if (ioctl(slavefd, TCGETS, &termios) != 0) { 422 tst_brkm(TFAIL, NULL, "TCGETS"); 423 } 424 425 termios.c_cflag &= ~CBAUD; 426 termios.c_cflag |= B0 & CBAUD; 427 if (ioctl(slavefd, TCSETS, &termios) != 0) { 428 tst_brkm(TFAIL, NULL, "TCGETS"); 429 } 430 431 if (close(slavefd) != 0) { 432 tst_brkm(TBROK, NULL, "close"); 433 } 434 if (close(masterfd) != 0) { 435 tst_brkm(TBROK, NULL, "close"); 436 } 437 tst_resm(TPASS, "test6"); 438 439 /** NOT REACHED **/ 440 return 0; 441 } 442 443 /* 444 * main test driver 445 */ 446 int main(int argc, char **argv) 447 { 448 test1(); 449 test2(); 450 test3(); 451 test4(); 452 test5(); 453 test6(); 454 /* 455 * all done 456 */ 457 tst_exit(); 458 } 459