zoukankan      html  css  js  c++  java
  • 终端I/O之规范模式

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

    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 != ' ')

            if(ptr < &buf[MAX_PASS_LEN])

                *ptr++ = c;

        *ptr = 0;    /* null terminate */

        putc(' ', 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 ", ptr);

     

        while(*ptr != 0)

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

        exit(0);

    }

     

    禁止回显运行效果:

    不禁止回显的运行效果:

  • 相关阅读:
    ThreadSafety with the AutoResetEvent, ManualResetEvent Class(Synchronization of .net)
    使用Python SMTP发送邮件
    flask项目中设置logo
    如何解决Bootstrap中分页不能居中的问题
    pip install mysql_python报错解决办法
    git上拉项目
    AttributeError: 'str' object has no attribute 'decode'
    pycharm设置SDK
    为git创建远程仓库
    开发过程中git的使用
  • 原文地址:https://www.cnblogs.com/nufangrensheng/p/3577317.html
Copyright © 2011-2022 走看看