在浏览器中打开网页
程序需要用机器上的浏览器打开网页,但不同操作系统与程序交互的方式不同,因此实现起来多少有些难度。
好在兼职演员已经为你写好了这部分的代码,它能够在绝大多数系统上打开网页。但他们好像还有要事在身,所以只采用了最简单的实现方式:
代码用了三条命令,它们分别可以在Windows、Linux和 Mac上打开URL。每次都有两条命令会失败,但只要有一条成功就行了。
滑野雪
你能写出比兼职演员更好的代码吗?为何不用
fork()
和exec()
在你喜欢的操作系统中重写这部分代码呢?
练习
大部分代码已经写好了,你只需要填写用管道连接父子进程的那部分。为了节约空间,我们去掉了
#include
语句、error()
和open_url()
函数。别忘了,在这个程序中是子进程对父进程说话,所以请以正确的方式连接管道!
练习解答
大部分代码已经写好了,你只需要填写用管道连接父子进程的那部分。为了节约空间,我们去掉了
#include
语句、error()
和open_url()
函数。
试驾
编译代码并运行程序,出现了:
太棒了,程序工作了。
news_opener
程序在一个独立的进程中运行了rssgossip.py,并让它显示找到新闻的URL。所有本来应该发送到屏幕上的输出现在通过管道重定向到news_opener
父进程,news_opener
就可以在浏览器中打开新闻了。
管道是连接进程的好办法。现在你不但能够运行进程,控制它们的环境,而且还能获取进程的输出,这样就可以实现很多功能。任何一个能够在命令行中运行的程序你都可以在C代码中调用并控制它。
滑野雪
既然你已经知道了如何控制rssgossip.py,为什么不试着控制一些其他程序呢?在类Unix机器或任何使用Cygwin的Windows机器中可以获取以下程序:
curl/wget
可以用这两个程序与网络服务器通信,也可以在C代码中使用它们与网络通信。
mail/mutt
可以在命令行用这两个程序发送邮件。如果在机器上装了它们,C程序就能发送邮件。
convert
convert命令可以转换图片格式。你可以写一个C程序,它输出文本格式的SVG图表,然后用convert命令把SVG转化成PNG图片。
这里没有蠢问题
问:管道是文件吗?
答:这取决于操作系统创建管道的方式,通常用
pipe()
创建的管道都不是文件。问:就是说也有可能是文件?
答:你可以创建基于文件的管道,它们通常叫有名管道或FIFO(First In First Out,先进先出)文件。
问:它能干嘛?
答:因为基于文件的管道有名字,所以两个进程只要知道管道的名字也能用它来通信,即使它们非父子进程。
问:太好了!怎么使用有名管道?
答:使用
mkfifo()
系统调用,详情请见http://tinyurl.com/cdf6ve5。问:如果不用文件来实现管道,那用什么?
答:通常用存储器。数据写到存储器中的某个位置,然后再从另一个位置读取。
问:如果我试图读取一个空的管道会怎么样?
答:程序会等管道中出现东西。
问:父进程如何知道子进程什么时候结束?
答:子进程结束时,管道会关闭。
fgets()
将收到EOF(End Of File,文件结束符),于是fgets()
函数返回0,循环就结束了。问:父进程能对子进程说话吗?
答:当然可以。你完全可以反向连接管道,让数据从父进程发送到子进程。
问:管道能够双向通信吗?这样父子进程不就可以边听边讲了?
答:管道只能单向通信。不过可以创建两个管道,一个从父进程连到子进程,另一个从子进程连到父进程。
要点
父子进程可以用管道通信。
pipe()
函数创建一个管道和两个描述符。一个描述符是管道的读取端,另一个是写入端。
可以把标准输入和标准输出重定向到管道。
父子进程各自使用管道的一端。