程序员

linux 终端io笔记

2016-06-13  本文已影响0人  陈伟志

简介终端的两种工作模式:以行为单位的工作模式,以字符数或时间为单位自定义模式

终端判断函数:

终端属性的获取与设置:

终端名称的获取:

终端属性结构:struct termios

struct termios{ 
           tcflag_t c_iflag; 
           tcflag_t c_oflag; 
           tcflag_t c_cflag; 
           tcflag_t c_lflag; 
           cc_t c_cc[NCCS]; 
};


termios关键字

c_oflag:控制输出格式

c_lflag:本地模式

c_iflag:控制输入格式

c_cc:见例2


例子

1.行模式,关闭回显

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
 
#define MAX_PASS_LEN 8
 
char * getpass(const char *prompt){
    static char buf[MAX_PASS_LEN+1];
    char *ptr;
    struct termios ts,ots;
    FILE *fp;
    int c;
 
    if((fp=fopen(ctermid(NULL),"r+")) == NULL)
        return 0;
    setbuf(fp,NULL);
 
    tcgetattr(fileno(fp),&ts);
    ots=ts;
    ts.c_lflag &= ~ECHO;
    tcsetattr(fileno(fp),TCSAFLUSH,&ts);
    fputs(prompt,fp);
 
//ptr < &buf[x] 两个内存地址比较,最多填充到buf[MAX_PASS_LEN-1]
//*ptr=0 在接下来的一位填充0表示结束
    ptr=buf;
    while((c=getc(fp)) != EOF && c != '\n')
        if(ptr < &buf[MAX_PASS_LEN])
            *ptr++ = c;
    *ptr=0;
    putc('\n',fp);
 
    tcsetattr(fileno(fp),TCSAFLUSH,&ots);
    fclose(fp);
    return buf;
}
 
int main(){
    char *ptr;
    if((ptr=getpass("Enter password:")) == NULL)
        perror("getpass word");
    printf("passowrd: %s\n",ptr);
 
//先ptr++移到下一位置,接着ptr副本(未移动前的位置)进行*ptr=0
    while(*ptr != 0)
        *ptr++ =0;
    return 0;
}

2.自定义模式
将termios结构中c_lflag字段的ICANON标志关闭就使终端处于非行模式,此时回车换行不作为行结束标识返回
自定义模式下有两种结束标识:

另外,也可以同时指定上述两个变量,只要有一个变量指定的条件成立就返回
以下为简单自定义模式,字符长度达到10就返回,对SIGINT中断做复位处理

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <signal.h>
 
static struct termios save_termios;
static int ttysavefd=-1;
 
int tty_cbreak(int fd){
    struct termios buf;
    if(tcgetattr(fd,&save_termios) <0){
        perror("tcgetattr error");
        return -1;
    }
 
    buf=save_termios;
    buf.c_lflag &= ~ICANON;
    buf.c_iflag &= ~ICRNL;
    buf.c_cc[VMIN]=10;
    buf.c_cc[VTIME]=0;
 
    if(tcsetattr(fd,TCSAFLUSH,&buf) <0){
        perror("tcsetattr error");
        return -1;
    }
    ttysavefd=fd;
    return 0;
}
 
int tty_reset(int fd){
    if(tcsetattr(fd,TCSAFLUSH,&save_termios) <0){
        return -1;
    }
    return 0;
}

int main(int argc,char *argv[]){
    if(signal(SIGINT,sig_catch) == SIG_ERR)
        perror("signal error");
    if(tty_cbreak(STDIN_FILENO) <0)
        perror("tty_cbreak error");
    char c[11]={0};
    int i;
    puts("cbreak mode,terminate with sigint");
    while(i=read(STDIN_FILENO,&c,10)){
        printf("\n%s\n",c);
    }
    return 0;
}

上一篇 下一篇

猜你喜欢

热点阅读