stty命令有点复杂,虽然本人已经尽可能的写的简洁,不过还是比较复杂。程序有两个部分是由已有的代码改写的,一个是命令行参数的分析,另一个是控制字符的转换函数(控制字符的转换函数(cat)的原作者:Torbjorn Granland)。
程序实现了部分stty的功能,主要的功能如下:-a,-g,-F,这三个参数基本的表现和标准一样,不过有的输出会有差别(比如vtdly会以-vtdly或者vtdly的形式输出而不是vt0,vt1这样的格式),所有能够修改的参数都在mc_cc_buf,mc_iflg_buf, mc_oflg_buf,mc_cflg_buf,mc_lflg_buf中已经声明,不在这5个数组中声明的参数无法修改(如果出现这5个数组中没有出现的程序将由于非法参数的出现而结束进程)。
程序的结束时的返回值如下:
1: tcgetattr失败
2: tcsetattr失败
3: 输出终端信息时同时选择设置终端信息
4: 重置文件描述符失败
5: 非法的参数
6: 程序异常(内存错误,内存用尽等)
程序作者:莫尘/mc_nns 程序开源,任何人可以任意使用和修改
1 /* 2 * 程序为stty命令的实现,命令的实现参考了标准,命令支持的参数为-a, -g, -F 3 * -a详细的输出终端信息,-g以不可视的风格输出终端信息,-F替换设备 4 * 所有能修改的信息都在mc_cc_buf, mc_cflg_buf, mc_lflg_buf, mc_iflg_buf, mc_oflg_buf 5 * 程序可以修改这5个程序所指明的终端的特性,除此,程序还能修改 6 * line,ispeed, ospeed, rows, cols/colunms, min, time这7种终端特性 7 * 程序的返回值: 8 * 1: tcgetattr失败 9 * 2: tcsetattr失败 10 * 3: 输出终端信息时同时选择设置终端信息 11 * 4: 重置文件描述符失败 12 * 5: 非法的参数 13 * 6: 程序异常(内存错误,内存用尽等) 14 * 15 * 程序作者:莫尘/mc_nns; 注:mc_character_to_visible源自Torbjorn Granland的cat 16 */ 17 18 #include <fcntl.h> 19 #include <unistd.h> 20 #include <getopt.h> 21 #include <termios.h> 22 #include <sys/ioctl.h> 23 #include <stdio.h> 24 #include <errno.h> 25 #include <limits.h> 26 #include <string.h> 27 #include <stdlib.h> 28 29 typedef struct mode{ 30 char *name; 31 tcflag_t val; 32 int size; /* 名字的长度 */ 33 }mc_mode; 34 35 typedef struct speed{ 36 char *name; 37 int val; /* 比特率的真值 */ 38 speed_t speed; /* 比特率的数值 */ 39 int size; /* 比特率所指字符串的长度 */ 40 }mc_speed; 41 42 static mc_speed mc_speed_buf[] = { 43 { "0", B0, 0, 1 }, 44 { "50", B50, 50, 2 }, 45 { "75", B75, 75, 2 }, 46 { "110", B110, 110, 3 }, 47 { "134", B134, 134, 3 }, 48 { "150", B150, 150, 3 }, 49 { "200", B200, 200, 3 }, 50 { "300", B300, 300, 3 }, 51 { "600", B600, 600, 3 }, 52 { "1200", B1200, 1200, 4 }, 53 { "1800", B1800, 1800, 4 }, 54 { "2400", B2400, 2400, 4 }, 55 { "4800", B4800, 4800, 4 }, 56 { "9600", B9600, 9600, 4 }, 57 { "19200", B19200, 19200, 5 }, 58 { "38400", B38400, 38400, 5 }, 59 #ifdef EXTA 60 { "exta", B19200, 19200, 5 }, 61 #endif 62 #ifdef EXTB 63 { "extb", B38400, 38400, 5 }, 64 #endif 65 #ifdef B57600 66 { "57600", B57600, 57600, 5 }, 67 #endif 68 #ifdef B115200 69 { "115200", B115200, 115200, 6 }, 70 #endif 71 #ifdef B230400 72 { "230400", B230400, 230400, 6 }, 73 #endif 74 #ifdef B460800 75 { "460800", B460800, 460800, 6 }, 76 #endif 77 #ifdef B500000 78 { "500000", B500000, 500000, 6 }, 79 #endif 80 #ifdef B576000 81 { "576000", B576000, 576000, 6 }, 82 #endif 83 #ifdef B921600 84 { "921600", B921600, 921600, 6 }, 85 #endif 86 #ifdef B1000000 87 { "1000000", B1000000, 1000000, 7 }, 88 #endif 89 #ifdef B1152000 90 { "1152000", B1152000, 1152000, 7 }, 91 #endif 92 #ifdef B1500000 93 { "1500000", B1500000, 1500000, 7 }, 94 #endif 95 #ifdef B2000000 96 { "2000000", B2000000, 2000000, 7 }, 97 #endif 98 #ifdef B2500000 99 { "2500000", B2500000, 2500000, 7 }, 100 #endif 101 #ifdef B3000000 102 { "3000000", B3000000, 3000000, 7 }, 103 #endif 104 #ifdef B3500000 105 { "3500000", B3500000, 3500000, 7 }, 106 #endif 107 #ifdef B4000000 108 { "4000000", B4000000, 4000000, 7 }, 109 #endif 110 { NULL, 0, 0, 0 } 111 }; 112 113 static mc_mode mc_cc_buf[] = { 114 { "intr", VINTR, 4 }, 115 { "quit", VQUIT, 4 }, 116 { "erase", VERASE, 5 }, 117 { "kill", VKILL, 4 }, 118 { "eof", VEOF, 3 }, 119 { "time", VTIME, 4 }, 120 { "min", VMIN, 3 }, 121 { "swtch", VSWTC, 5 }, 122 { "start", VSTART, 5 }, 123 { "stop", VSTOP, 4 }, 124 { "susp", VSUSP, 4 }, 125 { "eol", VEOL, 3 }, 126 { "rprnt", VREPRINT, 5 }, 127 { "discard", VDISCARD, 7 }, 128 { "werase", VWERASE, 6 }, 129 { "lnext", VLNEXT, 5 }, 130 { "eol2", VEOL2, 4 }, 131 { NULL, 0, 0 }, 132 }; 133 134 static mc_mode mc_cflg_buf[] = { 135 #ifdef CBAUD 136 { "cbaud", CBAUD, 5 }, 137 #endif 138 #ifdef CBAUDEX 139 { "cbaudex", CBAUDEX, 7 }, 140 #endif 141 #ifdef CIBAUD 142 { "cibaud", CIBAUD, 6 }, 143 #endif 144 #ifdef CMSPAR 145 { "cmspar", CMSPAR, 6 }, 146 #endif 147 #ifdef CRTSCTS 148 { "crtscts", CRTSCTS, 7 }, 149 #endif 150 { "csize", CSIZE, 5 }, 151 { "cs5", CS5, 3 }, 152 { "cs6", CS6, 3 }, 153 { "cs7", CS7, 3 }, 154 { "cs8", CS8, 3 }, 155 { "cstopb", CSTOPB, 6 }, 156 { "cread", CREAD, 5 }, 157 { "parenb", PARENB, 6 }, 158 { "parodd", PARODD, 6 }, 159 { "hupcl", HUPCL, 5 }, 160 { "clocal", CLOCAL, 6 }, 161 { NULL, 0, 0 } 162 }; 163 164 static mc_mode mc_lflg_buf[] = { 165 { "isig", ISIG, 4 }, 166 { "icaon", ICANON, 5 }, 167 #ifdef XCASE 168 { "xcase", XCASE, 5 }, 169 #endif 170 { "echo", ECHO, 4 }, 171 { "echoe", ECHOE, 5 }, 172 { "echok", ECHOK, 5 }, 173 { "echonl", ECHONL, 6 }, 174 { "noflsh", NOFLSH, 6 }, 175 { "tostop", TOSTOP, 6 }, 176 #ifdef ECHOCTL 177 { "echoctl", ECHOCTL, 7 }, 178 #endif 179 #ifdef ECHOPRT 180 { "echoprt", ECHOPRT, 7 }, 181 #endif 182 #ifdef ECHOKE 183 { "echoke", ECHOKE, 6 }, 184 #endif 185 #ifdef ELUSHO 186 { "elusho", ELUSHO, 6 }, 187 #endif 188 #ifdef PENDIN 189 { "pendin", PENDIN, 6 }, 190 #endif 191 { "iexten", IEXTEN, 6 }, 192 #ifdef EXTPROC 193 { "extproc", EXTPROC, 7 }, 194 #endif 195 { NULL, 0, 0 } 196 }; 197 198 static mc_mode mc_iflg_buf[] = { 199 { "ignbrk", IGNBRK, 6 }, 200 { "brkint", BRKINT, 6 }, 201 { "ignpar", IGNPAR, 6 }, 202 { "parmrk", PARMRK, 6 }, 203 { "inpck", INPCK, 5 }, 204 { "istrip", ISTRIP, 6 }, 205 { "inlcr", INLCR, 5 }, 206 { "igncr", IGNCR, 5 }, 207 { "icrnl", ICRNL, 5 }, 208 { "iuclc", IUCLC, 5 }, 209 { "ixon", IXON, 4 }, 210 { "ixany", IXANY, 5 }, 211 { "ixoff", IXOFF, 5 }, 212 { "imaxbel", IMAXBEL, 7 }, 213 { "iutf8", IUTF8, 5 }, 214 { NULL, 0, 0 } 215 }; 216 217 static mc_mode mc_oflg_buf[] = { 218 { "opost", OPOST, 5 }, 219 { "olcuc", OLCUC, 5 }, 220 { "onlcr", ONLCR, 5 }, 221 { "ocrnl", OCRNL, 5 }, 222 { "onocr", ONOCR, 5 }, 223 { "onlret", ONLRET, 6 }, 224 { "ofill", OFILL, 5 }, 225 { "ofdel", OFDEL, 5 }, 226 #ifdef NLDLY 227 { "nldly", NLDLY, 5 }, 228 #endif 229 #ifdef CRDLY 230 { "crdly", CRDLY, 5 }, 231 #endif 232 #ifdef TABDLY 233 { "tabdly", TABDLY, 6 }, 234 #endif 235 #ifdef BSDLY 236 { "bsdly", BSDLY, 5 }, 237 #endif 238 #ifdef FFDLY 239 { "ffdly", FFDLY, 5 }, 240 #endif 241 { "vtdly", VTDLY, 5 }, 242 #ifdef XTABS 243 { "xtabs", XTABS, 5 }, 244 #endif 245 { NULL, 0, 0 } 246 }; 247 248 struct option optbuf[] = { 249 { "all", 0, NULL, 'a' }, 250 { "save", 0, NULL, 'g' }, 251 { "file", 1, NULL, 'F' }, 252 { NULL, 0, NULL, 0 } 253 }; 254 255 static int mc_aflg, mc_gflg; /* -a 和 -g选项相互竞争 */ 256 static char *mc_prog_name; 257 static char *mc_filename; 258 259 /* 输出终端的长度和宽度 */ 260 static int mc_show_window_size(void); 261 /* 设置终端的长度,宽度 */ 262 static int mc_set_window_size(int row, int col); 263 /* 264 * 在mc_cc_buf, mc_cflg_buf, mc_lflg_buf, mc_iflg_buf, mc_oflg_buf中查找name 265 * 如果找不到返回-1,找到则分别返回0, 1, 2, 3, 4 266 */ 267 static int mc_find_mode(char *name, mc_mode *mode); 268 /* 获取终端的长度和宽度信息 */ 269 static int mc_get_window_size(int fd, struct winsize *win); 270 /* 将STDIN_FILENO重置到file */ 271 static int mc_reopen(int fd, char *file, int flags, mode_t mode); 272 /* 设置终端的比特率 */ 273 static int mc_do_set_speed(int flg, char *arg, struct termios *ttyp); 274 /* 根据speed来得出比特率,并调用mc_do_set_speed来设置比特率 */ 275 static int mc_set_speed(int flg, int speed, struct termios *ttyp); 276 /* 输出终端的比特率 */ 277 static int mc_show_speed(struct termios *ttyp); 278 /* 详细输出终端的信息 */ 279 static int mc_show_all(struct termios *ttyp); 280 /* 简单的输出终端信息 */ 281 static int mc_show_only(struct termios *ttyp); 282 /* 以非可视的形式输出终端信息 */ 283 static int mc_show_save(struct termios *ttyp); 284 /* 输出终端的信息 */ 285 static int mc_show_flag(mc_mode *bufp, tcflag_t flg); 286 /* 输出终端的控制字符 */ 287 static int mc_show_control_characters(cc_t *con_cp); 288 /* 设置终端的控制字符 */ 289 static int mc_set_control_character(struct termios *ttyp, mc_mode *mode, char *arg); 290 /* 输出终端的比特率 */ 291 static speed_t mc_show_baud(int speed); 292 /* 转换控制字符 */ 293 static const char *mc_character_to_visible(cc_t c); 294 295 int 296 main(int argc, char *argv[]) 297 { 298 int argi; 299 int opti; 300 int isarg; /* 判断是否存在非-a,-g,-F的参数 */ 301 mc_mode mode; 302 struct termios t; 303 char *namep; 304 register int i, c; 305 306 argi = 0; 307 opti = 1; 308 isarg = 0; 309 opterr = 0; 310 mc_prog_name = (namep = strchr(*argv, '/')) ? ++namep : *argv; 311 while((c = getopt_long(argc - argi, argv + argi, "-agF:", optbuf, NULL)) != -1){ 312 switch(c){ /* 读取命令行参数的办法参考了gnc的源码 */ 313 case 'a': 314 mc_aflg = 1; 315 mc_gflg = 0; 316 break; 317 case 'g': 318 mc_gflg = 1; 319 mc_aflg = 0; 320 break; 321 case 'F': 322 if(mc_filename){ 323 fprintf(stderr, "%s: noly one device may be specified\n", mc_prog_name); 324 exit(1); 325 } 326 mc_filename = optarg; 327 break; 328 default: 329 opti = 1; 330 isarg = 1; 331 optind = 0; 332 argi += opti; 333 break; 334 } 335 while(opti < optind) 336 argv[argi + opti++] = NULL; 337 } 338 if(isarg && (mc_aflg || mc_gflg)){ 339 fprintf(stderr, "%s: when specifying an output style, modes may not be set\n", mc_prog_name); 340 exit(3); 341 } 342 if(mc_filename){ 343 int flg; 344 if(mc_reopen(STDIN_FILENO, mc_filename, O_RDONLY | O_NONBLOCK, 0) == -1){ 345 fprintf(stderr, "%s: %s: %s\n", mc_prog_name, mc_filename, strerror(errno)); 346 exit(4); 347 } 348 if((flg = fcntl(STDIN_FILENO, F_GETFL)) == -1 || 349 fcntl(STDIN_FILENO, F_SETFL, flg & ~O_NONBLOCK) < 0){ 350 fprintf(stderr, "%s: %s: cannot reset non-blocking mode\n", mc_prog_name, mc_filename); 351 exit(4); 352 } 353 } 354 if(tcgetattr(STDIN_FILENO, &t) == -1){ 355 fprintf(stderr, "%s: tcgetattr: %s\n", mc_prog_name, strerror(errno)); 356 exit(1); 357 } 358 if(mc_aflg || mc_gflg || !isarg){ 359 if(mc_aflg) 360 mc_show_all(&t); 361 else if(mc_gflg) 362 mc_show_save(&t); 363 else 364 mc_show_only(&t); 365 return 0; 366 } 367 for(i = 1; i < argc; ++i){ 368 int remove; 369 register char *p; 370 371 remove = 0; 372 p = argv[i]; 373 if(*p == '\0') 374 continue; 375 if(*p == '-'){ 376 ++p; 377 remove = 1; 378 } 379 switch(mc_find_mode(p, &mode)){ 380 case 0: 381 mc_set_control_character(&t, &mode, argv[++i]); 382 break; 383 case 1: 384 if(remove) 385 t.c_cflag &= ~mode.val; 386 else 387 t.c_cflag |= mode.val; 388 break; 389 case 2: 390 if(remove) 391 t.c_lflag &= ~mode.val; 392 else 393 t.c_lflag |= mode.val; 394 break; 395 case 3: 396 if(remove) 397 t.c_iflag &= ~mode.val; 398 else 399 t.c_iflag |= mode.val; 400 break; 401 case 4: 402 if(remove) 403 t.c_oflag &= ~mode.val; 404 else 405 t.c_oflag |= mode.val; 406 break; 407 default: /* 比特率,宽度等的设置 */ 408 if(i == argc - 1){ 409 fprintf(stderr, "%s: missing argument to '%s'\n", 410 mc_prog_name, p); 411 exit(1); 412 } 413 if(memcmp("ispeed", p, 6) == 0){ 414 if(mc_do_set_speed(1, argv[++i], &t) == -1) 415 fprintf(stderr, "%s: %s\n", 416 mc_prog_name, strerror(errno)); 417 } 418 else if(memcmp("ospeed", p, 6) == 0){ 419 if(mc_do_set_speed(2, argv[++i], &t) == -1) 420 fprintf(stderr, "%s: %s\n", 421 mc_prog_name, strerror(errno)); 422 } 423 else if(memcmp("rows", p, 4) == 0) 424 mc_set_window_size(atoi(argv[++i]), -1); /* 没有对是否为数字进行检查,真是抱歉 */ 425 else if(!memcmp("cols", p, 4) || !memcmp("columns", p, 7)) 426 mc_set_window_size(-1, atoi(argv[++i])); 427 else if(memcmp("line", p, 4) == 0) 428 t.c_line = atoi(argv[++i]); 429 else if(memcmp("min", p, 3) == 0) 430 t.c_cc[VMIN] = atoi(argv[++i]); 431 else if(memcmp("time", p, 4) == 0) 432 t.c_cc[VTIME] = atoi(argv[++i]); 433 else{ 434 fprintf(stderr, "%s: invalid argument '%s'\n", 435 mc_prog_name, p); 436 exit(5); 437 } 438 break; 439 } 440 } 441 if(mode.name){ 442 free(mode.name); 443 mode.name = NULL; 444 } 445 if(tcsetattr(STDIN_FILENO, TCSANOW, &t) == -1){ 446 fprintf(stderr, "%s: tcsetattr: %s\n", mc_prog_name, strerror(errno)); 447 exit(2); 448 } 449 return 0; 450 } 451 452 static void 453 mc_show_only(struct termios *ttyp) 454 { 455 if(ttyp == NULL) 456 return -1; 457 mc_show_speed(ttyp); 458 putchar(' '); 459 printf("line = %u;\n", ttyp->c_line); 460 } 461 462 static void 463 mc_show_save(struct termios *ttyp) 464 { 465 register int i; 466 register cc_t *p; 467 468 if(ttyp == NULL) 469 return -1; 470 printf("%x:%x:%x:%x", ttyp->c_iflag, ttyp->c_oflag, ttyp->c_cflag, ttyp->c_lflag); /* 有的平台可能需要%lx */ 471 p = ttyp->c_cc; 472 for(i = 0; i < NCCS; i++) 473 printf(":%x", p[i]); 474 putchar('\n'); 475 } 476 477 static void 478 mc_show_all(struct termios *ttyp) 479 { 480 if(ttyp == NULL) 481 return -1; 482 mc_show_speed(ttyp); 483 putchar(' '); 484 mc_show_window_size(); 485 putchar(' '); 486 printf("line = %u;\n", ttyp->c_line); 487 mc_show_control_characters(ttyp->c_cc); 488 putchar('\n'); 489 mc_show_flag(mc_cflg_buf, ttyp->c_cflag); 490 mc_show_flag(mc_iflg_buf, ttyp->c_iflag); 491 mc_show_flag(mc_oflg_buf, ttyp->c_oflag); 492 mc_show_flag(mc_lflg_buf, ttyp->c_lflag); 493 } 494 495 static void 496 mc_show_speed(struct termios *ttyp) 497 { 498 speed_t is, os; 499 500 if(ttyp == NULL) 501 return -1; 502 is = cfgetispeed(ttyp); 503 os = cfgetospeed(ttyp); 504 if(!is || is == os) 505 printf("speed %u baud;", mc_show_baud(is)); 506 else 507 printf("ispeed %u baud; ospeed %u baud;", 508 mc_show_baud(is), mc_show_baud(os)); 509 } 510 511 static void 512 mc_set_control_character(struct termios *ttyp, mc_mode *mode, char *arg) 513 { 514 unsigned long val; 515 516 if(ttyp == NULL) 517 return -1; 518 if(!memcmp(mode->name, "time", 4) || !memcmp(mode->name, "min", 3)) 519 val = strtoul(arg, NULL, 10); /* 没有对是否为数字进行检查,非常抱歉 */ 520 else if(arg[0] == '\0' || arg[1] == '\0') 521 val = (unsigned char)arg[0]; 522 else if(!memcmp(arg, "^-", 2) || !memcmp(arg, "undef", 5)) 523 val = 0; 524 else if(arg[0] == '^' && arg[1] != '\0'){ 525 if(arg[1] == '?') 526 val = 127; 527 else 528 val = (unsigned char)arg[1] & ~0140; 529 } 530 else 531 val = strtoul(arg, NULL, 10); 532 ttyp->c_cc[mode->val] = val; 533 } 534 535 static int 536 mc_find_mode(char *name, mc_mode *mode) 537 { 538 int retval; 539 register mc_mode *p; 540 541 /* 一次遍历5个数组来查找name */ 542 for(retval = 0, p = mc_cc_buf; p->name; p++) 543 if(memcmp(p->name, name, p->size) == 0) 544 goto out; 545 for(retval = 1, p = mc_cflg_buf; p->name; p++) 546 if(memcmp(p->name, name, p->size) == 0) 547 goto out; 548 for(retval = 2, p = mc_lflg_buf; p->name; p++) 549 if(memcmp(p->name, name, p->size) == 0) 550 goto out; 551 for(retval = 3, p = mc_iflg_buf; p->name; p++) 552 if(memcmp(p->name, name, p->size) == 0) 553 goto out; 554 for(retval = 4, p = mc_oflg_buf; p->name; p++) 555 if(memcmp(p->name, name, p->size) == 0) 556 goto out; 557 return -1; 558 out: 559 char *p; 560 if(mode->name) 561 p = realloc(p->name, p->size * sizeof(char) + 1); 562 else 563 p = malloc(p->size * sizeof(char) + 1); 564 if(p == NULL){ 565 fprintf(stderr, "%s: out of space: %s\n", 566 mc_prog_name, strerror(errno)); 567 exit(6); 568 } 569 mode->name = p; 570 memmove(mode->name, p->name, p->size + 1); 571 mode->val = p->val; 572 mode->size = p->size; 573 return retval; 574 } 575 576 static int 577 mc_reopen(int fd, char *file, int flags, mode_t mode) 578 { 579 int fd1, fd2; 580 581 fd1 = open(file, flags, mode); 582 if(fd1 == fd || fd1 == -1) /* file无法打开或者为同一文件描述符则直接结束 */ 583 return fd; 584 fd2 = dup2(fd1, fd); 585 close(fd1); 586 return fd2; 587 } 588 589 static int 590 mc_do_set_speed(int flg, char *arg, struct termios *ttyp) 591 { 592 register mc_speed *p; 593 594 for(p = mc_speed_buf; p->name != NULL; p++){ 595 if(memcmp(arg, p->name, p->size) == 0) 596 break; 597 } 598 if(p->name == NULL) 599 return 1; 600 return mc_set_speed(flg, p->val, ttyp); 601 } 602 603 static int 604 mc_set_speed(int flg, int speed, struct termios *ttyp) 605 { 606 int err; 607 608 err = 0; 609 if(flg == 0 || flg == 1) 610 err |= cfsetispeed(ttyp, speed); 611 if(flg == 0 || flg == 2) 612 err |= cfsetospeed(ttyp, speed); 613 return err; 614 } 615 616 static int 617 mc_show_flag(mc_mode *bufp, tcflag_t flg) 618 { 619 register int i; 620 register char *cp; 621 register mc_mode *p; 622 623 if(bufp == NULL) 624 return -1; 625 p = bufp; 626 for(i = 0; cp = p[i].name; i++){ 627 if((flg & p[i].val) == 0) 628 putchar('-'); 629 printf("%s ", cp); 630 } 631 putchar('\n'); 632 return 0; 633 } 634 635 static int 636 mc_show_window_size(void) 637 { 638 struct winsize win; 639 640 if(mc_get_window_size(STDIN_FILENO, &win)){ 641 fprintf(stderr, "%s: %s\n", mc_prog_name, strerror(errno)); 642 return -1; 643 } 644 printf("rows = %d; columns = %d;", win.ws_row, win.ws_col); 645 return 0; 646 } 647 648 static int 649 mc_set_window_size(int row, int col) 650 { 651 struct winsize win; 652 653 if(mc_get_window_size(STDIN_FILENO, &win)){ 654 fprintf(stderr, "%s: %s\n", mc_prog_name, strerror(errno)); 655 return -1; 656 } 657 if(row >= 0) 658 win.ws_row = row; 659 if(col >= 0) 660 win.ws_col = col; 661 if(ioctl(STDIN_FILENO, TIOCSWINSZ, &win) == -1){ 662 fprintf(stderr, "%s: %s\n", mc_prog_name, strerror(errno)); 663 return -1; 664 } 665 return 0; 666 } 667 668 static int 669 mc_get_window_size(int fd, struct winsize *win) 670 { 671 return ioctl(fd, TIOCGWINSZ, win); 672 } 673 674 static int 675 mc_show_control_characters(cc_t *con_cp) 676 { 677 register int i; 678 register cc_t *q; 679 register char *cp; 680 register mc_mode *p; 681 682 if(con_cp == NULL) 683 return -1; 684 q = con_cp; 685 p = mc_cc_buf; 686 for(i = 0; cp = p[i].name; i++){ 687 printf("%s = ", cp); 688 if(memcmp(cp, "min", 3) && memcmp(cp, "time", 4)) 689 printf("%s; ", mc_character_to_visible(q[i])); 690 else 691 printf("%d; ", q[i]); 692 } 693 return 0; 694 } 695 696 /* Adapted from `cat' by Torbjorn Granlund. */ 697 static const char * 698 mc_character_to_visible (cc_t c) 699 { 700 char *p; 701 static char buf[10]; 702 703 p = buf; 704 if (c == 0){ 705 memcpy(p, "<undef>", 7); 706 p += 7; 707 } 708 else if(c >= 32){ 709 if(c > 127){ 710 *p++ = 'M'; 711 *p++ = '-'; 712 if(c >= 128 + 32){ 713 if(c >= 128 + 127){ 714 *p++ = '^'; 715 *p++ = '?'; 716 } 717 else 718 *p++ = c - 128; 719 } 720 else{ 721 *p++ = '^'; 722 *p++ = c - 128 + 64; 723 } 724 } 725 else if(c == 127){ 726 *p++ = '^'; 727 *p++ = '?'; 728 } 729 else 730 *p++ = c; 731 } 732 else{ 733 *p++ = '^'; 734 *p++ = c + 64; 735 } 736 *p = '\0'; 737 return (const char *)buf; 738 } 739 740 static speed_t 741 mc_show_baud(int speed) 742 { 743 register mc_speed *p; 744 745 for(p = mc_speed_buf; p->name; p++){ 746 if(p->val == speed) 747 break; 748 } 749 if(p->name) /* 查看是否找到相关的元素 */ 750 return p->speed; 751 return 0; 752 }