鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 编程语言开发 > c语言 > >

stty命令的实现

来源:互联网 作者:佚名 时间:2012-12-23 12:54
stty命令有点复杂,虽然本人已经尽可能的写的简洁,不过还是比较复杂。程序有两个部分是由已有的代码改写的,一个是命令行参数的分析,另一个是控制字符的转换函数(控制字符的转换函数(cat)的原作者:Torbjorn Granland)。 程序实现了部分stty的功能,主

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 程序开源,香港空间美国服务器,任何人可以任意使用和修改

* 程序为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 #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; }mc_mode; 34 35 typedef struct speed{ 36 char *name; speed_t speed; size; }mc_speed; mc_speed mc_speed_buf[] = { , B0, 0, 1 }, , B50, 50, 2 }, , B75, 75, 2 }, , B110, 110, 3 }, , B134, 134, 3 }, , B150, 150, 3 }, , B200, 200, 3 }, , B300, 300, 3 }, , B600, 600, 3 }, , B1200, 1200, 4 }, , B1800, 1800, 4 }, , B2400, 2400, 4 }, , B4800, 4800, 4 }, , B9600, 9600, 4 }, , B19200, 19200, 5 }, , B38400, 38400, 5 }, 59 #ifdef EXTA , B19200, 19200, 5 }, #ifdef EXTB , B38400, 38400, 5 }, #ifdef B57600 , B57600, 57600, 5 }, #ifdef B115200 , B115200, 115200, 6 }, #ifdef B230400 , B230400, 230400, 6 }, #ifdef B460800 , B460800, 460800, 6 }, #ifdef B500000 , B500000, 500000, 6 }, #ifdef B576000 , B576000, 576000, 6 }, #ifdef B921600 , B921600, 921600, 6 }, #ifdef B1000000 , B1000000, 1000000, 7 }, #ifdef B1152000 , B1152000, 1152000, 7 }, #ifdef B1500000 , B1500000, 1500000, 7 }, #ifdef B2000000 , B2000000, 2000000, 7 }, #ifdef B2500000 , B2500000, 2500000, 7 }, #ifdef B3000000 , B3000000, 3000000, 7 }, #ifdef B3500000 , B3500000, 3500000, 7 }, #ifdef B4000000 , B4000000, 4000000, 7 }, { NULL, 0, 0, 0 } 111 }; mc_mode mc_cc_buf[] = { , VINTR, 4 }, , VQUIT, 4 }, , VERASE, 5 }, , VKILL, 4 }, , VEOF, 3 }, , VTIME, 4 }, , VMIN, 3 }, , VSWTC, 5 }, , VSTART, 5 }, , VSTOP, 4 }, , VSUSP, 4 }, , VEOL, 3 }, , VREPRINT, 5 }, , VDISCARD, 7 }, , VWERASE, 6 }, , VLNEXT, 5 }, , VEOL2, 4 }, 131 { NULL, 0, 0 }, 132 }; mc_mode mc_cflg_buf[] = { 135 #ifdef CBAUD , CBAUD, 5 }, #ifdef CBAUDEX , CBAUDEX, 7 }, #ifdef CIBAUD , CIBAUD, 6 }, #ifdef CMSPAR , CMSPAR, 6 }, #ifdef CRTSCTS , CRTSCTS, 7 }, { , CSIZE, 5 }, , CS5, 3 }, , CS6, 3 }, , CS7, 3 }, , CS8, 3 }, , CSTOPB, 6 }, , CREAD, 5 }, , PARENB, 6 }, , PARODD, 6 }, , HUPCL, 5 }, , CLOCAL, 6 }, 161 { NULL, 0, 0 } 162 }; mc_mode mc_lflg_buf[] = { , ISIG, 4 }, , ICANON, 5 }, 167 #ifdef XCASE , XCASE, 5 }, { , ECHO, 4 }, , ECHOE, 5 }, , ECHOK, 5 }, , ECHONL, 6 }, , NOFLSH, 6 }, , TOSTOP, 6 }, 176 #ifdef ECHOCTL , ECHOCTL, 7 }, #ifdef ECHOPRT , ECHOPRT, 7 }, #ifdef ECHOKE , ECHOKE, 6 }, #ifdef ELUSHO , ELUSHO, 6 }, #ifdef PENDIN , PENDIN, 6 }, { , IEXTEN, 6 }, 192 #ifdef EXTPROC , EXTPROC, 7 }, { NULL, 0, 0 } 196 }; mc_mode mc_iflg_buf[] = { , IGNBRK, 6 }, , BRKINT, 6 }, , IGNPAR, 6 }, , PARMRK, 6 }, , INPCK, 5 }, , ISTRIP, 6 }, , INLCR, 5 }, , IGNCR, 5 }, , ICRNL, 5 }, , IUCLC, 5 }, , IXON, 4 }, , IXANY, 5 }, , IXOFF, 5 }, , IMAXBEL, 7 }, , IUTF8, 5 }, 214 { NULL, 0, 0 } 215 }; mc_mode mc_oflg_buf[] = { , OPOST, 5 }, , OLCUC, 5 }, , ONLCR, 5 }, , OCRNL, 5 }, , ONOCR, 5 }, , ONLRET, 6 }, , OFILL, 5 }, , OFDEL, 5 }, 226 #ifdef NLDLY , NLDLY, 5 }, #ifdef CRDLY , CRDLY, 5 }, #ifdef TABDLY , TABDLY, 6 }, #ifdef BSDLY , BSDLY, 5 }, #ifdef FFDLY , FFDLY, 5 }, { , VTDLY, 5 }, 242 #ifdef XTABS , XTABS, 5 }, { NULL, 0, 0 } 246 }; option optbuf[] = { , }, , }, , }, 252 { NULL, 0, NULL, 0 } 253 }; mc_aflg, mc_gflg; *mc_prog_name; *mc_filename; mc_show_window_size(void); mc_set_window_size(int row, int col); * 在mc_cc_buf, mc_cflg_buf, mc_lflg_buf, mc_iflg_buf, mc_oflg_buf中查找name 265 * 如果找不到返回-1,找到则分别返回0, 1, 2, 3, 4 mc_find_mode(char *name, mc_mode *mode); mc_get_window_size(int fd, struct winsize *win); mc_reopen(int fd, char *file, int flags, mode_t mode); mc_do_set_speed(int flg, char *arg, struct termios *ttyp); mc_set_speed(int flg, int speed, struct termios *ttyp); mc_show_speed(struct termios *ttyp); mc_show_all(struct termios *ttyp); mc_show_only(struct termios *ttyp); mc_show_save(struct termios *ttyp); mc_show_flag(mc_mode *bufp, tcflag_t flg); mc_show_control_characters(cc_t *con_cp); mc_set_control_character(struct termios *ttyp, mc_mode *mode, char *arg); speed_t mc_show_baud(int speed); *mc_character_to_visible(cc_t c); main(int argc, char *argv[]) 297 { 298 int argi; 299 int opti; 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; )) ? ++namep : *argv; , optbuf, NULL)) != -1){ : 314 mc_aflg = 1; 315 mc_gflg = 0; 316 break; : 318 mc_gflg = 1; 319 mc_aflg = 0; 320 break; : 322 if(mc_filename){ , 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)){ , 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){ , 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){ , mc_prog_name, mc_filename); 351 exit(4); 352 } 353 } 354 if(tcgetattr(STDIN_FILENO, &t) == -1){ , 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); (mc_gflg) 362 mc_show_save(&t); mc_show_only(&t); ; 366 } 367 for(i = 1; i < argc; ++i){ 368 int remove; 369 register char *p; 370 371 remove = 0; 372 p = argv[i]; ) 374 continue; ){ 376 ++p; 377 remove = 1; 378 } 379 switch(mc_find_mode(p, &mode)){ : 381 mc_set_control_character(&t, &mode, argv[++i]); 382 break; : 384 if(remove) 385 t.c_cflag &= ~mode.val; t.c_cflag |= mode.val; 388 break; : 390 if(remove) 391 t.c_lflag &= ~mode.val; t.c_lflag |= mode.val; 394 break; : 396 if(remove) 397 t.c_iflag &= ~mode.val; t.c_iflag |= mode.val; 400 break; : 402 if(remove) 403 t.c_oflag &= ~mode.val; t.c_oflag |= mode.val; 406 break; (i == argc - 1){ , 410 mc_prog_name, p); 411 exit(1); 412 } , p, 6) == 0){ 414 if(mc_do_set_speed(1, argv[++i], &t) == -1) , 416 mc_prog_name, strerror(errno)); 417 } (memcmp(, p, 6) == 0){ 419 if(mc_do_set_speed(2, argv[++i], &t) == -1) , 421 mc_prog_name, strerror(errno)); 422 } (memcmp(, p, 4) == 0) (!memcmp(, p, , p, 7)) 426 mc_set_window_size(-1, atoi(argv[++i])); (memcmp(, p, 4) == 0) 428 t.c_line = atoi(argv[++i]); (memcmp(, p, 3) == 0) 430 t.c_cc[VMIN] = atoi(argv[++i]); (memcmp(, p, 4) == 0) 432 t.c_cc[VTIME] = atoi(argv[++i]); 433 else{ , 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){ , mc_prog_name, strerror(errno)); 447 exit(2); 448 } ; 450 } mc_show_only(struct termios *ttyp) 454 { 455 if(ttyp == NULL) 456 return -1; 457 mc_show_speed(ttyp); 458 putchar(' '); , ttyp->c_line); 460 } mc_show_save(struct termios *ttyp) 464 { 465 register int i; 466 register cc_t *p; (ttyp == NULL) 469 return -1; , ttyp->c_iflag, ttyp->c_oflag, ttyp->c_cflag, ttyp->c_lflag); p = ttyp->c_cc; 472 for(i = 0; i < NCCS; i++) , p[i]); ); 475 } 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(' '); , ttyp->c_line); 487 mc_show_control_characters(ttyp->c_cc); ); 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 } mc_show_speed(struct termios *ttyp) 497 { 498 speed_t is, os; (ttyp == NULL) 501 return -1; 502 is = cfgetispeed(ttyp); 503 os = cfgetospeed(ttyp); 504 if(!is || is == os) , mc_show_baud(is)); printf(, 508 mc_show_baud(is), mc_show_baud(os)); 509 } mc_set_control_character(struct termios *ttyp, mc_mode *mode, char *arg) 513 { 514 unsigned long val; (ttyp == NULL) 517 return -1; , , 3)) (arg[|| arg[) 521 val = (unsigned char)arg[0]; (!memcmp(arg, , , 5)) 523 val = 0; (arg[&& arg[){ ) 526 val = 127; val = (unsigned char)arg[1] & ~0140; 529 } val = strtoul(arg, NULL, 10); 532 ttyp->c_cc[mode->val] = val; 533 } mc_find_mode(char *name, mc_mode *mode) 537 { 538 int retval; 539 register mc_mode *p; (retval = 0, p = mc_cc_buf; p->name; p++) 543 if(memcmp(p->name, name, p->size) == 0) ; 545 for(retval = 1, p = mc_cflg_buf; p->name; p++) 546 if(memcmp(p->name, name, p->size) == 0) ; 548 for(retval = 2, p = mc_lflg_buf; p->name; p++) 549 if(memcmp(p->name, name, p->size) == 0) ; 551 for(retval = 3, p = mc_iflg_buf; p->name; p++) 552 if(memcmp(p->name, name, p->size) == 0) ; 554 for(retval = 4, p = mc_oflg_buf; p->name; p++) 555 if(memcmp(p->name, name, p->size) == 0) ; 557 return -1; 558 out: 559 char *p; 560 if(mode->name) 561 p = realloc(p->name, p->size * sizeof(char) + 1); p = malloc(p->size * sizeof(char) + 1); 564 if(p == NULL){ , 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 } mc_reopen(int fd, char *file, int flags, mode_t mode) 578 { 579 int fd1, fd2; 580 581 fd1 = open(file, flags, mode); fd; 584 fd2 = dup2(fd1, fd); 585 close(fd1); 586 return fd2; 587 } mc_do_set_speed(int flg, char *arg, struct termios *ttyp) 591 { 592 register mc_speed *p; (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) ; 600 return mc_set_speed(flg, p->val, ttyp); 601 } 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 } mc_show_flag(mc_mode *bufp, tcflag_t flg) 618 { 619 register int i; 620 register char *cp; 621 register mc_mode *p; (bufp == NULL) 624 return -1; 625 p = bufp; 626 for(i = 0; cp = p[i].name; i++){ 627 if((flg & p[i].val) == 0) ); , cp); 630 } ); ; 633 } mc_show_window_size(void) 637 { 638 struct winsize win; (mc_get_window_size(STDIN_FILENO, &win)){ , mc_prog_name, strerror(errno)); 642 return -1; 643 } , win.ws_row, win.ws_col); ; 646 } mc_set_window_size(int row, int col) 650 { 651 struct winsize win; (mc_get_window_size(STDIN_FILENO, &win)){ , 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){ , mc_prog_name, strerror(errno)); 663 return -1; 664 } ; 666 } mc_get_window_size(int fd, struct winsize *win) 670 { 671 return ioctl(fd, TIOCGWINSZ, win); 672 } 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; (con_cp == NULL) 683 return -1; 684 q = con_cp; 685 p = mc_cc_buf; 686 for(i = 0; cp = p[i].name; i++){ , cp); , , 4)) , mc_character_to_visible(q[i])); printf(, q[i]); 692 } ; 694 } * 698 mc_character_to_visible (cc_t c) 699 { 700 char *p; buf[10]; 702 703 p = buf; 704 if (c == 0){ , 7); 706 p += 7; 707 } (c >= 32){ 709 if(c > 127){ ; ; 712 if(c >= 128 + 32){ 713 if(c >= 128 + 127){ ; ; 716 } *p++ = c - 128; 719 } 720 else{ ; 722 *p++ = c - 128 + 64; 723 } 724 } (c == 127){ ; ; 728 } *p++ = c; 731 } 732 else{ ; 734 *p++ = c + 64; 735 } ; *)buf; 738 } speed_t 741 mc_show_baud(int speed) 742 { 743 register mc_speed *p; (p = mc_speed_buf; p->name; p++){ 746 if(p->val == speed) 747 break; 748 } p->speed; ; 752 }

网友评论
<