求教:终端规范模式下,设置ECHOE不起作用?

zhiys 2011-08-10 10:38:20
如下代码来自 apue , 主要工作是获取用户从终端输入的password , getpass 函数用来获取用户的输入,
在行终端规范模式下:
关闭 ECHO 避免了回显,还关闭了ECHOK ,这样我输入密码有错时,不可以Ctrl+U 来取消整行的输入。
我自己曾经加了一句 ts.c_lflag=ts.c_lfag|ECHOK ; 打开ECHOK , Ctrl+U 能正常取消上一行的输入。

源程序还关闭了 ECHOE ,(根据书上信息,关闭ECHOE后,Ctrl+H 来取消前一个输入字符的功能被屏蔽)
我自己又加了一句 ts.c_lflag = ts.c_lflag|ECHOE; 来打开ECHOE , 但Ctrl+H 功能依然不起作用。

这是为什么? 还请高手解答

char *getpass(const char *);
int main()
{
char *ptr;

if((ptr=getpass("ENTER passwd:"))==NULL){ ERROR_REPORT("getpass failed"); }
fprintf(cgi_out , "passwd=%s\n" , ptr);

while(*ptr!=0)
*ptr++ = 0;
exit(0);
}
char *getpass(const char *prompt)
{
static char buf[9];
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);
sigaddset(&sig , SIGTSTP);
sigprocmask(SIG_BLOCK , &sig , &osig);

tcgetattr(fileno(fp) , &ts);
ots=ts ;
ts.c_lflag &= ~(ECHOE|ECHOK|ECHONL|ECHOPRT|ECHO);
ts.c_lflag = ts.c_lflag|ECHOE; // 这句是我自己添加的,为了测试 ECHOK 的作用
tcsetattr(fileno(fp) , TCSAFLUSH , &ts);
fputs(prompt , fp);

ptr=buf ;
while((c=getc(fp))!=EOF && c != '\n')
if(ptr < &buf[9]) *ptr++ = c ;

*ptr=0 ;
putc('\n' , fp);
tcsetattr(fileno(fp) , TCSAFLUSH , &ots);
sigprocmask(SIG_SETMASK , &osig , NULL);
fclose(fp);
return(buf);
}
...全文
71 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
jernymy 2011-08-10
  • 打赏
  • 举报
回复
使用
printf("\b");
退格
zhiys 2011-08-10
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 icansaymyabc 的回复:]
char *getpass(const char *prompt)
{
static char buf[9];
printf( prompt);
int i=0,ch=0;
while((i<9)&&(13!=(ch=getch()))) buf[i++]=ch;
buf[i]=0;
return buf;
}

这样不好吗?
[/Quote] 当然越简单越好, 不过这样没有修改终端属性,密码输入时会回显到屏幕.
而前面一些步骤主要是考虑屏蔽一些中断,避免恢复终端属性前,密码输入被中断,进程退出
而终端属性却没有复原,造成任何正常输入也不回显了.

我主要是,测试终端属性 ECHOE 不起作用?却查不出原因,困惑。
icansaymyabc 2011-08-10
  • 打赏
  • 举报
回复
怎么要弄得那么麻烦?为了用 getch 需要 #include <conio.h>
icansaymyabc 2011-08-10
  • 打赏
  • 举报
回复
char *getpass(const char *prompt)
{
static char buf[9];
printf( prompt);
int i=0,ch=0;
while((i<9)&&(13!=(ch=getch()))) buf[i++]=ch;
buf[i]=0;
return buf;
}

这样不好吗?
zhiys 2011-08-10
  • 打赏
  • 举报
回复
比如: 我终端登陆linux , 输入用户名后,输入密码,在回车前,如果感觉密码按错键了,ctrl+u 可以取消以前的错误输入,然后再输一遍密码。
icansaymyabc 2011-08-10
  • 打赏
  • 举报
回复
谁让你这么麻烦来着?很少有软件提供输入密码过程中编辑密码的,一般都是密码输入错了就得连用户名也要重输。

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧