创build一个write()被阻塞的场景

我有这个简单的C程序:

#include <stdio.h> int main (int argc, char *argv[]) { printf ("Hello, world\n"); return 0; } 

如果我把编译后的程序printf()变成write():

 $ strace ./hw > x execve("./hw", ["./hw"], [/* 19 vars */]) = 0 ... write(1, "Hello, world\n", 13) = 13 ... 

我的问题如下:我希望操作系统在执行write()调用后阻止程序执行。 作为一个简单的非root用户,是否有可能创build这样的场景? 请注意,我不能改变任何程序代码。

我的直觉告诉我应该,但是我却找不到解决办法。 想象一下,write()会写入一个文件描述符,并返回给一个没有缓冲的字符设备。 这样的设备,不会强制写入()来阻止?

write系统调用将数据复制到与文件描述符关联的内核缓冲区中。 只要有可能进行缓冲,呼叫就不会被阻塞。 但是,如果你写足够的数据到一个缓慢的输出设备,那么最终write将会阻塞。

写几个字节来阻塞是件有些工作。 以下是一种方法:

首先,创建一个命名管道:

 mkfifo /tmp/the_fifo 

任何试图打开 /tmp/the_fifo进行写入的操作都会阻塞,直到某个进程打开fifo进行读取。 你可以打开阅读的fifo,而不需要阅读任何东西,如:

 sleep 1000 < /tmp/the_fifo & 

现在你可以填充fifo缓冲区了:

 yes > /tmp/the_fifo & 

在这一点上,当你的程序试图写入/tmp/fifo时,你的程序应该被阻塞。

完成后,不要忘记杀死后台进程并删除命名管道。

如果你写入管道,没有人读取管道,它最终会填满。 我可能是错的,默认的Linux管道大小是64KB。

尝试将应用程序的输出传输到从不读取其标准输入的应用程序中,如下所示:

 ./hw | sleep 1000 

sleep永远不会读取其标准输入,这样你就可以很容易地填写管道。