首页 > 学院 > 操作系统 > 正文

终端I/O之规范模式

2024-06-28 13:27:42
字体:
来源:转载
供稿:网友
终端I/O之规范模式

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

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

}

?

禁止回显运行效果:

不禁止回显的运行效果:


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表