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{ 30char *name; 31 tcflag_t val;}mc_mode; 34 35 typedef struct speed{ 36char *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 };optionoptbuf[] = {, },, },, },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中查找name265 * 如果找不到返回-1,找到则分别返回0, 1, 2, 3, 4mc_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 {298int argi;299int opti; mc_mode mode;302struct termios t;303char *namep;304register int i, c;305 306argi = 0;307opti = 1;308isarg = 0;309opterr = 0;)) ? ++namep : *argv;, optbuf, NULL)) != -1){:314mc_aflg = 1;315mc_gflg = 0;316break;:318mc_gflg = 1;319mc_aflg = 0;320break;:322if(mc_filename){, mc_prog_name);324exit(1);325 }326mc_filename = optarg;327break; 328default: 329opti = 1;330isarg = 1;331optind = 0;332argi += opti;333break; 334 }335while(opti < optind)336argv[argi + opti++] = NULL;337 }338if(isarg && (mc_aflg || mc_gflg)){, mc_prog_name);340exit(3);341 } 342if(mc_filename){343int flg;344if(mc_reopen(STDIN_FILENO, mc_filename, O_RDONLY | O_NONBLOCK, 0) == -1){, mc_prog_name, mc_filename, strerror(errno));346exit(4);347 }348if((flg = fcntl(STDIN_FILENO, F_GETFL)) == -1 ||349fcntl(STDIN_FILENO, F_SETFL, flg & ~O_NONBLOCK) < 0){, mc_prog_name, mc_filename);351exit(4);352 }353 }354if(tcgetattr(STDIN_FILENO, &t) == -1){, mc_prog_name, strerror(errno));356exit(1);357 }358if(mc_aflg || mc_gflg || !isarg){359if(mc_aflg)360mc_show_all(&t);(mc_gflg)362mc_show_save(&t);mc_show_only(&t);;366 }367for(i = 1; i < argc; ++i){368int remove;369register char *p;370 371remove = 0;372p = argv[i];)374continue;){376++p;377remove = 1;378 }379switch(mc_find_mode(p, &mode)){:381mc_set_control_character(&t, &mode, argv[++i]);382break;:384if(remove)385t.c_cflag &= ~mode.val;t.c_cflag |= mode.val;388break;:390if(remove)391t.c_lflag &= ~mode.val;t.c_lflag |= mode.val;394break;:396if(remove)397t.c_iflag &= ~mode.val;t.c_iflag |= mode.val;400break;:402if(remove)403t.c_oflag &= ~mode.val;t.c_oflag |= mode.val;406break;(i == argc – 1){, 410 mc_prog_name, p);411exit(1);412 }, p, 6) == 0){414if(mc_do_set_speed(1, argv[++i], &t) == -1), 416 mc_prog_name, strerror(errno));417 }(memcmp(, p, 6) == 0){419if(mc_do_set_speed(2, argv[++i], &t) == -1),421 mc_prog_name, strerror(errno));422 }(memcmp(, p, 4) == 0)(!memcmp(, p, , p, 7))426mc_set_window_size(-1, atoi(argv[++i]));(memcmp(, p, 4) == 0)428t.c_line = atoi(argv[++i]);(memcmp(, p, 3) == 0)430t.c_cc[VMIN] = atoi(argv[++i]);(memcmp(, p, 4) == 0)432t.c_cc[VTIME] = atoi(argv[++i]);433else{,435 mc_prog_name, p);436exit(5);437 }438break;439 }440 }441if(mode.name){442 free(mode.name);443mode.name = NULL;444 }445if(tcsetattr(STDIN_FILENO, TCSANOW, &t) == -1){, mc_prog_name, strerror(errno));447exit(2);448 };450 }mc_show_only(struct termios *ttyp)454 {455if(ttyp == NULL)456return -1;457 mc_show_speed(ttyp);458putchar(‘ ‘);, ttyp->c_line);460 }mc_show_save(struct termios *ttyp)464 {465register int i;466register cc_t *p;(ttyp == NULL)469return -1;, ttyp->c_iflag, ttyp->c_oflag, ttyp->c_cflag, ttyp->c_lflag); p = ttyp->c_cc;472for(i = 0; i < NCCS; i++), p[i]););475 }mc_show_all(struct termios *ttyp)479 {480if(ttyp == NULL)481return -1;482 mc_show_speed(ttyp);483putchar(‘ ‘);484 mc_show_window_size(); 485putchar(‘ ‘);, ttyp->c_line);487mc_show_control_characters(ttyp->c_cc););489mc_show_flag(mc_cflg_buf, ttyp->c_cflag);490mc_show_flag(mc_iflg_buf, ttyp->c_iflag);491mc_show_flag(mc_oflg_buf, ttyp->c_oflag);492mc_show_flag(mc_lflg_buf, ttyp->c_lflag);493 }mc_show_speed(struct termios *ttyp)497 {498speed_t is, os;(ttyp == NULL)501return -1;502is = cfgetispeed(ttyp);503os = cfgetospeed(ttyp);504if(!is || is == os), mc_show_baud(is));printf(,508mc_show_baud(is), mc_show_baud(os));509 }mc_set_control_character(struct termios *ttyp, mc_mode *mode, char *arg)513 {514unsigned long val;(ttyp == NULL)517return -1;, , 3))(arg[|| arg[)521val = (unsigned char)arg[0];(!memcmp(arg, , , 5))523val = 0;(arg[&& arg[){)526val = 127;val = (unsigned char)arg[1] & ~0140;529 }val = strtoul(arg, NULL, 10);532ttyp->c_cc[mode->val] = val;533 }mc_find_mode(char *name, mc_mode *mode)537 {538intretval;539register mc_mode *p;(retval = 0, p = mc_cc_buf; p->name; p++)543if(memcmp(p->name, name, p->size) == 0);545for(retval = 1, p = mc_cflg_buf; p->name; p++)546if(memcmp(p->name, name, p->size) == 0);548for(retval = 2, p = mc_lflg_buf; p->name; p++)549if(memcmp(p->name, name, p->size) == 0);551for(retval = 3, p = mc_iflg_buf; p->name; p++)552if(memcmp(p->name, name, p->size) == 0);554for(retval = 4, p = mc_oflg_buf; p->name; p++)555if(memcmp(p->name, name, p->size) == 0);557return -1;558 out:559char*p;560if(mode->name)561p = realloc(p->name, p->size * sizeof(char) + 1);p = malloc(p->size * sizeof(char) + 1);564if(p == NULL){,566 mc_prog_name, strerror(errno));567exit(6);568 }569mode->name = p;570memmove(mode->name, p->name, p->size + 1);571mode->val = p->val;572mode->size = p->size;573return retval;574 }mc_reopen(int fd, char *file, int flags, mode_t mode)578 {579int fd1, fd2;580 581fd1 = open(file, flags, mode); fd;584fd2 = dup2(fd1, fd);585 close(fd1);586return fd2;587 }mc_do_set_speed(int flg, char *arg, struct termios *ttyp)591 {592register mc_speed *p;(p = mc_speed_buf; p->name != NULL; p++){595if(memcmp(arg, p->name, p->size) == 0)596break;597 }598if(p->name == NULL);600return mc_set_speed(flg, p->val, ttyp);601 }mc_set_speed(int flg, int speed, struct termios *ttyp)605 {606int err;607 608err = 0;609if(flg == 0 || flg == 1)610err |= cfsetispeed(ttyp, speed);611if(flg == 0 || flg == 2)612err |= cfsetospeed(ttyp, speed);613return err;614 }mc_show_flag(mc_mode *bufp, tcflag_t flg)618 {619register int i;620register char *cp;621register mc_mode *p;(bufp == NULL)624return -1;625p = bufp;626for(i = 0; cp = p[i].name; i++){627if((flg & p[i].val) == 0));, cp);630 });;633 }mc_show_window_size(void)637 {638struct winsize win;(mc_get_window_size(STDIN_FILENO, &win)){, mc_prog_name, strerror(errno));642return -1;643 }, win.ws_row, win.ws_col);; 646 }mc_set_window_size(int row, int col)650 {651struct winsize win;(mc_get_window_size(STDIN_FILENO, &win)){, mc_prog_name, strerror(errno));655return -1;656 }657if(row >= 0)658win.ws_row = row;659if(col >= 0)660win.ws_col = col;661if(ioctl(STDIN_FILENO, TIOCSWINSZ, &win) == -1){, mc_prog_name, strerror(errno));663return -1;664 };666 }mc_get_window_size(int fd, struct winsize *win)670 {671return ioctl(fd, TIOCGWINSZ, win);672 }mc_show_control_characters(cc_t *con_cp)676 {677register inti;678register cc_t *q;679register char *cp;680register mc_mode *p;(con_cp == NULL)683return -1;684q = con_cp;685p = mc_cc_buf;686for(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 {700char *p;buf[10];702 703p = buf;704if (c == 0){, 7);706p += 7;707 }(c >= 32){709if(c > 127){;;712if(c >= 128 + 32){713if(c >= 128 + 127){;;716 }*p++ = c – 128;719 }720else{;722*p++ = c – 128 + 64;723 }724 }(c == 127){;;728 }*p++ = c;731 }732else{;734*p++ = c + 64;735 };*)buf;738 } speed_t 741 mc_show_baud(int speed)742 {743register mc_speed *p;(p = mc_speed_buf; p->name; p++){746if(p->val == speed)747break;748 }p->speed;;752 }只有经历过地狱般的折磨,才有征服天堂的力量。

stty命令的实现

相关文章:

你感兴趣的文章:

标签云: