规范模式很简单:发一个读请求,输入完一行后,终端驱动程序即刻返回。下列几个条件都会造成读返回:

  1. 所要求的字节数已经读到时,读返回。无需读一个完整的行。如果都了部分行,也不会丢失任何信息,下一次读从前一次读的停止处开始。
  2. 当读到一个行定界符时,读返回。在规范模式中以下5个字符被解释为"行结束":NL、EOL、EOL2、EOF、设置了ICRNL但未设置IGNCR时的CR字符。在这5个行定界符中,其中只有一个EOF字符在终端驱动程序对其进行处理后即被删除,其他4个字符则作为该行的最后一个字符返回给调用者。
  3. 如果捕捉到信号而且该函数并不自动重启动(http://www.cnblogs.com/nufangrensheng/p/3515035.html),则读也返回。

 

实例:getpass函数

Getpass函数:读入用户在终端上键入的口令。此函数由UNIX login(1)和crypt(1)程序调用。为了读口令(密码),该函数必须禁止回显,但仍可使终端以规范模式进行工作,因为用户在键入口令后,一定要键入回车,这样也就构成了一个完整行。

 

程序清单18-8 getpass函数的典型UNIX实现

#include <signal.h>

#include <stdio.h>

#include <termios.h>

 

#define MAX_PASS_LEN    8    /* max #chars for user to enter */

 

char *

getpass(const char *prompt)

{

    static char    buf[MAX_PASS_LEN + 1];    /* null byte at end */

    char        *ptr;

    sigset_t    sig, osig;

    struct termios    ts, ots;

    FILE        *fp;

    int        c;

    

    if((fp = fopen(ctermid(NULL), "r+")) == NULL)

        return(NULL);

    setbuf(fp, NULL);

    

    sigemptyset(&sig);

    sigaddset(&sig, SIGINT);    /* block SIGINT */

    sigaddset(&sig, SIGTSTP);    /* block SIGTSTP */

    sigprocmask(SIG_BLOCK, &sig, &osig);    /* and save mask */

    

    tcgetattr(fileno(fp), &ts);    /* save tty state */

    ots = ts;            /* sturcture copy */

    ts.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);    /* 禁止回显 */

    tcsetattr(fileno(fp), TCSAFLUSH, &ts);

    fputs(prompt, fp);

 

    ptr = buf;

    while((c = getc(fp)) != EOF && c != '\n')

        if(ptr < &buf[MAX_PASS_LEN])

            *ptr++ = c;

    *ptr = 0;    /* null terminate */

    putc('\n', fp);    /* we echo a newline */

 

    tcsetattr(fileno(fp), TCSAFLUSH, &ots);    /* restore TTY state */

    sigprocmask(SIG_SETMASK, &osig, NULL);    /* restore mask */

    fclose(fp);    /* done with /dev/tty */

    return(buf);

}

 

程序清单18-9 调用getpass函数

#include "apue.h"

 

char    *getpass(const char *);

 

int

main(void)

{

    char *ptr;

    

    if((ptr = getpass("Enter password:")) == NULL)

        err_sys("getpass error");

    printf("password: %s\n", ptr);

 

    while(*ptr != 0)

        *ptr++ = 0;    /* zero it out when we're done with it */

    exit(0);

}

 

禁止回显运行效果:

不禁止回显的运行效果:

终端I/O之规范模式的更多相关文章

  1. 终端I/O之非规范模式

    关闭termios结构中c_lflag字段的ICANON标志就使终端处于非规范模式.在非规范模式中,输入数据并不组成行,不处理下列特殊字符:ERASE/KILL/EOF/NL/EOL/EOL2/CR/ ...

  2. 规范模式-------From ABP Document

    介绍 规范模式是一种特定的软件设计模式,通过使用布尔逻辑 (维基百科)将业务规则链接在一起,可以重新组合业务规则. 在实际中,它主要用于 为实体或其他业务对象定义可重用的过滤器. 例 在本节中,我们将 ...

  3. 终端I/O之特殊输入字符

    POSIX.1定义了11个在输入时作特殊处理的字符.实现定义了另外一些特殊字符.表18-6摘要列出了这些特殊字符. 表18-6 终端特殊输入字符 在POSIX.1的11个特殊字符中,可将其中9个更改为 ...

  4. 终端I/O之综述

    终端I/O有两种不同的工作模式: 规范模式输入处理(Canonical mode input processing).在这种模式中,终端输入以行为单位进行处理.对于每个读要求,终端驱动程序最多返回一行 ...

  5. APUE读书笔记-第18章-终端I/O

    18.1 引言 *终端I/O的用途很广泛,包括用于终端.计算机之间的直接连线.调制解调器以及打印机等等,所以终端I/O系统非常复杂 18.2 综述 *终端I/O有两种不同的工作模式: (1)规范模式输 ...

  6. Unix环境高级编程(十九)终端I/O

    终端I/O应用很广泛,用于终端.计算机之间的直接连线.调制解调器以及打印机等等.终端I/O有两种不同的工作模式: (1)规范模式输入处理:终端输入以行为单位进行处理,对于每个读要求,终端驱动程序最多返 ...

  7. tcgetattr函数与tcsetattr函数控制终端

    6.4.4  使用tcgetattr函数与tcsetattr函数控制终端 为了便于通过程序来获得和修改终端参数,Linux还提供了tcgetattr函数和tcsetattr函数.tcgetattr用于 ...

  8. Linux终端那件事儿

    我们将会讨论如何更好的控制用户终端:也就说是键盘输入与屏幕输出.除了这些,我们还会了解我们编写的程序如何由用户处读取输入,即使是在输入重定向的情况下,以及确保输出到屏幕的正确位置.这里所提供的一些底层 ...

  9. apue 第18章 终端I/O

    终端I/O有两种不同的工作模式: (1)规范模式:输入以行单位进行处理,每个读请求也最多返回一行. (2)非规范模式:输入字符不装配成行. 终端设备是由通常位于内核中的终端驱动程序控制的.每个终端设备 ...

随机推荐

  1. HDU ACM 1515 Anagrams by Stack

    Anagrams by Stack Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  2. oracle10g库连接报错

  3. poj 2239 Selecting Courses(二分匹配简单模板)

    http://poj.org/problem?id=2239 这里要处理的是构图问题p (1 <= p <= 7), q (1 <= q <= 12)分别表示第i门课在一周的第 ...

  4. Samsung Galaxy S II GT-I9100 指令全集 部分指令请慎用

    英文版 谷歌翻译 Obtain/Change Device Information *#06# (Display IMEI number) *#1234# (Display current firmw ...

  5. URAL 2069 Hard Rock (最短路)

    题意:给定 n + m 个街道,问你从左上角走到右下角的所有路的权值最小的中的最大的. 析:我们只要考虑几种情况就好了,先走行再走列和先走列再走行差不多.要么是先横着,再竖着,要么是先横再竖再横,要么 ...

  6. Twin Prime Conjecture(浙大计算机研究生保研复试上机考试-2011年)

    Twin Prime Conjecture                                            Time Limit: 2000/1000 MS (Java/Othe ...

  7. 设置UIButton文字大小颜色不同

    _loginBtn = [[UIButton alloc]initWithFrame:CGRectMake(iconX, CGRectGetMaxY(passwordBGView.frame)+25, ...

  8. hdoj 5400 Arithmetic Sequence

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5400 水题 #include<stdio.h> typedef long long LL; ...

  9. Spring Bean生命周期

    1.Bean的建立:BeanFactory容器寻找Bean的定义信息,读取Bean定义文件,并将其实例化,生成各个Bean实例.2.属性注入:使用依赖注入,Spring按照Bean定义信息配置Bean ...

  10. CentOS7安装telnet服务

    CentOS7.0 telnet-server 启动的问题.解决方法:    ①.先检查CentOS7.0是否已经安装以下两个安装包:telnet-server.xinetd.命令如下:    rpm ...