简介

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

终端判断函数:

  • int isatty(int fd)

终端属性的获取与设置:

  • int tcgetattr(int fd,struct termios *termptr)
  • int tcsetattr(int fd,int opt,const struct termios *termptr),opt选项如下

    TCSANOW:不等数据传输完毕就立即改变属性。

    TCSADRAIN:等待所有数据传输结束才改变属性。

    TCSAFLUSH:等待所有数据传输结束,清空输入输出缓冲区才改变属性。

终端名称的获取:

  • char *ctermid(char *ptr),如果ptr非空,则将终端名称(/dev/tty)写入到此ptr中并返回;若为空,分配空间写入后返回

终端属性结构: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:控制输出格式

  • OPOST:如果屏蔽此关键字,换行后缩进为上一行最后一个字符位置的后一位

c_lflag:本地模式

  • ECHO:回显,如果屏蔽则不显示输入的字符,像输入密码一样
  • ICANON:行模式,屏蔽则变成自定义模式
  • ISIG:使终端产生的信号(ctrl+c/ctrl+z等)起作用,屏蔽则忽略信号

c_iflag:控制输入格式

  • ICRNL:按下回车换行,屏蔽则不换行打印一个^M
  • BRKINT:当在输入行中检测到一个终止状态时,产生一个中断

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标志关闭就使终端处于非行模式,此时回车换行不作为行结束标识返回

自定义模式下有两种结束标识:

  • c_cc数组中的VMIN变量即c_cc[VMIN]作为最少字符结束标识,字符达到VMIN个就返回,c_cc[VMIN]=0表示不限容量
  • c_cc数组中的VTIME变量即c_cc[VTIME]作为最短时间结束标识,从第一个字符输入开始,经过VTIME时间后就返回,c_cc[VTIME]=0表示不限时间

另外,也可以同时指定上述两个变量,只要有一个变量指定的条件成立就返回

以下为简单自定义模式,字符长度达到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;
}

linux终端io笔记的更多相关文章

  1. linux 标准io笔记

    三种缓冲 1.全缓冲:在缓冲区写满时输出到指定的输出端. 比如对磁盘上的文件进行读写通常是全缓冲的. 2.行缓冲:在遇到'\n'时输出到指定的输出端. 比如标准输入和标准输出就是行缓冲, 回车后就会进 ...

  2. storysnail的Linux串口编程笔记

    storysnail的Linux串口编程笔记 作者 He YiJun – storysnail<at>gmail.com 团队 ls 版权 转载请保留本声明! 本文档包含的原创代码根据Ge ...

  3. Linux实战教学笔记08:Linux 文件的属性(上半部分)

    第八节 Linux 文件的属性(上半部分) 标签(空格分隔):Linux实战教学笔记 第1章 Linux中的文件 1.1 文件属性概述(ls -lhi) linux里一切皆文件 Linux系统中的文件 ...

  4. Linux实战教学笔记06:Linux系统基础优化

    第六节 Linux系统基础优化 标签(空格分隔):Linux实战教学笔记-陈思齐 第1章 基础环境 第2章 使用网易163镜像做yum源 默认国外的yum源速度很慢,所以换成国内的. 第一步:先备份 ...

  5. Linux实战教学笔记02:计算机系统硬件核心知识

    标签(空格分隔):Linux实战教学笔记-陈思齐 第1章 互联网企业常见服务器介绍 1.1 互联网公司服务器品牌 - DELL(大多数公司,常用) - HP - IBM(百度在用) 浪潮 联想 航天联 ...

  6. Linux终端打印命令使用介绍

    常用linux打印命令 日常使用中或shell脚本中linux终端打印命令有echo和printf.  echo命令 功能说明:显示文字.语 法:echo [-ne][字符串]或 echo [--he ...

  7. linux标准io的copy

    ---恢复内容开始--- 1.linux标准io的copy #include<stdio.h> int main(int argc,char **argv) { if(argc<3) ...

  8. 如何在 Linux 终端中知道你的公有 IP

    导读 在本文中我将会介绍在几种在 Linux 终端中查看你的公有 IP 地址的方法.这对普通用户来说并无意义,但 Linux 服务器(无GUI或者作为只能使用基本工具的用户登录时)会很有用.无论如何, ...

  9. Linux就这个范儿 第15章 七种武器 linux 同步IO: sync、fsync与fdatasync Linux中的内存大页面huge page/large page David Cutler Linux读写内存数据的三种方式

    Linux就这个范儿 第15章 七种武器  linux 同步IO: sync.fsync与fdatasync   Linux中的内存大页面huge page/large page  David Cut ...

随机推荐

  1. Gradle实战:不同编译类型的包同设备共存

    查看原文:http://blog.csdn.net/u010818425/article/details/52335844 Gradle实战系列文章: <Gradle基本知识点与常用配置> ...

  2. iOS篇之有沙盒缓存

    内存指的就是主板上的存储部件,是CPU直接与之沟通,并用其存储数据的部件,存放当前正在使用的(即执行中)的数据和程序,它的物理实质就是一组或多组具备数据输入输出和数据存储功能的集成电路,内存只用于暂时 ...

  3. 仿jQuery中undelegate()方法功能的函数

    //跨浏览器事件绑定 function addEvent(obj,type,fn){ if(typeof obj.removeEventListener !='undefined'){ /////// ...

  4. Kinect For Windows V2开发日志七:照片合成与背景消除

    上一篇里讲到了Kinect可以从环境中区分出人体来.因此可以利用这个功能,来把摄像头前的人合成进照片里,和利用Photoshop不同的是,这样合成进去的人是动态且实时的. 简单的思路 BodyInde ...

  5. 初识 Asp.Net内置对象之Request对象

    Request对象 Request对象用于检索从浏览器向服务器所发送的请求信息.它提供对当前页请求的访问,包括标题,Cookie,客户端证书等等.它也与HTTP协议的请求消息对应. Request对象 ...

  6. Unity3d之动态连接Mesh Renderer和Collider

    using UnityEngine; using System.Collections; public class dynaMesh : MonoBehaviour {     public Skin ...

  7. Linux勉強

        block 與 inode 的總量: 未使用與已使用的 inode / block 數量: block 與 inode 的大小 (block 為 1, 2, 4K,inode 為 128 by ...

  8. JavaScript:exec()方法的用法及说明

    最近在看某知名js框架的源码,突然间发现自己对exec()方法竟然不太理解,然后就仔细的分析了一下这个方法 下面贴个exec()方法使用的代码出来 rquickExpr = /^(?:\s*(< ...

  9. javascript触摸事件touch使用

    详细内容请点击 Apple在iOS 2.0中引入了触摸事件API,Android正迎头赶上这一事实标准,缩小差距.最近一个W3C工作组正合力制定这一触摸事件规范.        在本文深入研究iOS和 ...

  10. MySQL之不能保存表格问题

    有时候我们制作表格不能保存时出现这样的提示: 我们打开工具: 把“阻止保存要求重新创建表的更改”选项的勾给去了: