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 程序开源,任何人可以任意使用和修改

  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 }

 

你可能感兴趣的:(tty)