APUE fig 1.10示例代码的完善--对提示符及输入回车的优化
APUE 第3版第15页的shell2.c示例程序,运行效果如下:
gcc ol.shell.c -o origin_shell ./origin_shell
% date
2015年12月13日 星期日 22时04分48秒 CST
% ^Cinterrupt
ls
Makefile getcputc.c mycat.c myls_info.c note.md origin_shell shell2.c uidgid.c
a.out hello.c myls.c myls_sort.c ol.shell.c shell1.c testerror.c
% %
couldn't execute: : No such file or directory
% ls
Makefile getcputc.c mycat.c myls_info.c note.md origin_shell shell2.c uidgid.c
a.out hello.c myls.c myls_sort.c ol.shell.c shell1.c testerror.c
%
从上述示例中可以看出,存在2个小问题:
1. 当通过ctrl+C输入中断信号时,中断捕获程序的输出语句的“%”并没有立即输出来,等到下一次回车时才输出,导致第10行有两个%%号。
2. 当出现%提示符时,直接回车,会提示如11行所示的错误。因为此时传递给execlp函数的buf内容是空的。其中问题1是出现在程序中的如下一句:
while (fgets(buf, MAXLINE, stdin) != NULL) {
}
// 即中断信号中断的是fgets函数,此时系统正在请求输入中,而中断处理程序的输出:
printf("interrupt\n%% ");
// 在换行之后,%并没有立即出来。如果将其修改如下,
printf("interrupt\n%%\n");
// 则显示效果变成这样:
% ^Cinterrupt
%
ls
Makefile mycat.c note.md shell2.c
a.out myls.c ol.shell.c testerror.c
getcputc.c myls_info.c origin_shell uidgid.c
hello.c myls_sort.c shell1.c
如上可见,上述增加一个'\n'后,虽然立即输出了%,但如第3行所见,光标移到%下一行了。
一个解决办法是使用fflush()函数。完整代码,新增为21-24行,以及46行:
#include "../apue.h"
#include <sys/wait.h> static void sig_int(int); /* our signal-catching function */ int
main(void)
{
char buf[MAXLINE]; /* from apue.h */
pid_t pid;
int status; if (signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal error"); printf("%% "); /* print prompt (printf requires %% to print %) */
while (fgets(buf, MAXLINE, stdin) != NULL) {
if (buf[strlen(buf) - ] == '\n')
buf[strlen(buf) - ] = ; /* replace newline with null */ if (strlen(buf) == ) { // 此if语句用于处理直接回车
printf("%% ");
continue;
} if ((pid = fork()) < ) {
err_sys("fork error");
} else if (pid == ) { /* child */
execlp(buf, buf, (char *));
err_ret("couldn't execute: %s", buf);
exit();
} /* parent */
if ((pid = waitpid(pid, &status, )) < )
err_sys("waitpid error");
printf("%% ");
}
exit();
} void
sig_int(int signo)
{
printf(" interrupt!\n%%");
fflush(stdout); //强制输出所有stdout中的字符流
}
完善后效果如下:
% date
2015年12月13日 星期日 22时31分53秒 CST
% ^C interrupt!
% date
2015年12月13日 星期日 22时32分15秒 CST
%
%
APUE fig 1.10示例代码的完善--对提示符及输入回车的优化的更多相关文章
- redis 学习笔记(2)-client端示例代码
redis提供了几乎所有主流语言的client,java中主要使用二种:Jedis与Redisson 一.Jedis的使用 <dependency> <groupId>redi ...
- c# 使用hook来监控鼠标键盘事件的示例代码
如果这个程序在10几年前,QQ刚刚兴起的时候,有了这个代码,就可实现盗号了. 当然使用钩子我们更多的是实现"全局快捷键"的需求. 比如 程序最小化隐藏后要"某快捷键&qu ...
- Ajax原理,技术封装与完整示例代码
在做项目和学习的时候,经常用到Ajax的相关技术,但是这方面的技术总是运用的不是十分好,就寻找相关博客来学习加深Ajax技术相关. 一.Ajax简介 二.同步.异步传输区别 2.1 异步传输 2.2 ...
- ActiveMQ笔记(1):编译、安装、示例代码
一.编译 虽然ActiveMQ提供了发布版本,但是建议同学们自己下载源代码编译,以后万一有坑,还可以尝试自己改改源码. 1.1 https://github.com/apache/activemq/r ...
- php示例代码之类似于C#中的String.Format方法
php示例代码之类似于C#中的String.Format方法 原文来自于 http://stackoverflow.com/questions/1241177/c-string-format-equ ...
- C# 6新特性及示例代码
今天推荐的其实是一个Github开源项目,不过这个开源项目是专门介绍C# 6的最新特性,并给出了示例代码. 我们知道,微软即将发布Windows 10和Visual Studio 2015,在VS20 ...
- C# WebSocket 服务端示例代码 + HTML5客户端示例代码
WebSocket服务端 C#示例代码 using System; using System.Collections.Generic; using System.Linq; using System. ...
- Swift常用语法示例代码(二)
此篇文章整理自我以前学习Swift时的一些练习代码,其存在的意义多是可以通过看示例代码更快地回忆Swift的主要语法. 如果你想系统学习Swift或者是Swift的初学者请绕路,感谢Github上Th ...
- Swift常用语法示例代码(一)
此篇文章整理自我以前学习Swift时的一些练习代码,其存在的意义多是可以通过看示例代码更快地回忆Swift的主要语法. 如果你想系统学习Swift或者是Swift的初学者请绕路,感谢Github上Th ...
随机推荐
- 【调侃】IOC前世今生
前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...
- 【.net 深呼吸】限制执行代码的权限
前面好几篇文章,老周都跟大伙伴们聊了跟应用程序域有关的话题,干脆咱们一聊到底吧,做学问就应该这样,有恒心. App Domain的创建新应用程序域的方法中,有一个特殊的重载: public stati ...
- html与html5
HTML 是一种在 Web 上使用的通用标记语言.HTML 允许你格式化文本,添加图片,创建链接.输入表单.框架和表格等等,并可将之存为文本文件,浏览器即可读取和显示.HTML 的关键是标签,其作用是 ...
- 前端学HTTP之内容协商
前面的话 一个URL常常需要代表若干不同的资源.例如那种需要以多种语言提供其内容的网站站点.如果某个站点有说法语的和说英语的两种用户,它可能想用这两种语言提供网站站点信息.理想情况下,服务器应当向英语 ...
- warensoft unity3d 更新说明
warensoft unity3d 组件的Alpha版本已经发布了将近一年,很多网友发送了改进的Email,感谢大家的支持. Warensoft Unity3D组件将继续更新,将改进的功能如下: 1. ...
- CSS 3学习——box-sizing和背景
box-sizing 在CSS 2中设置元素的width和height仅仅是设置了元素内容区的宽和高,元素实际的尺寸是margin + border + padding + 内容区. CSS 3(截止 ...
- Java进击C#——前言
本章简言 记得三年前笔者来到现在的公司的时候,公司人口不出十个人.那个时候笔者刚从日本回来,想在福州.厦门.青岛找一个合适自己发展的机会.最后我的一个福州的朋友打电话希望我能过去帮他,跟他一起创业.这 ...
- python学习笔记(python介绍)
为什么要学python? python和shell的比较,和PHP.和JAVA比较 运维开发只是用到python的很小一部分 python在一些知名公司的应用: 谷歌:python的创始人原来在谷歌工 ...
- ResponsibleChain(责任链模式)
/** * 责任链模式 * @author TMAC-J * 老板讲任务交给CTO,CTO自然不会亲自去做,又把人物分配给项目经理,项目经理再把任务分配给组长,组长再分配给个人 * 如果中途哪个环节出 ...
- Android MVP+Retrofit+RxJava实践小结
关于MVP.Retrofit.RxJava,之前已经分别做了分享,如果您还没有阅读过,可以猛戳: 1.Android MVP 实例 2.Android Retrofit 2.0使用 3.RxJava ...