所谓单描述符读写管道,就是一个同时允许读写操作的管道描述符。
UNIX下的管道分为匿名管道和有名管道,其中匿名管道通过pipe:
#include <unistd.h>
int pipe(int filedes[2]);
|
创建。filedes[0]和filedes[1]分别用来保存新创建的管道的读端和写端所对应的文件描述符。一般来说,filedes[0]只允许读操作,filedes[1]只允许写操作。有名管道对应于文件系统中一个特殊的文件,这个文件通常通过mkfifo:
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
|
创建。接下来,应用程序就可以调用open打开管道来读或者写,当然,还可以以读写方式打开。
下面分别给出基于pipe和mkfifo的单描述符读写管道的实现:
int rwpipe(void)
{
int fds[2], retval;
char buf[256];
if (pipe(fds) != 0)
return -1;
while (close(fds[0]) != 0 && errno == EINTR)
;
retval = snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fds[1]);
if (retval > 0 && retval < sizeof(buf))
retval = open(buf, O_RDWR);
else
retval = -1;
while (close(fds[1]) != 0 && errno == EINTR)
;
return retval;
}
|
int rwpipe2(void)
{
int fd;
char buf[] = "/tmp/xxxx";
if (mkfifo(buf, S_IRUSR | S_IWUSR) != 0)
return -1;
fd = open(buf, O_RDWR);
unlink(buf);
return fd;
}
|
代码除了有点小技巧外,并不难读,这里也就不再解释。需要注意的是rwpipe2的实现少了类似mkstemp的文件名随机生成机制。
以上代码虽然都能勉强工作,但是谈不上高效,尤其是基于pipe的实现,有点儿迂回曲折。如果系统能直接返回读写管道的文件描述符就好了。本着不引入新的系统调用、充分利用已有系统调用接口的原则,我想到了把pipe参数filedes为NULL的情况进行扩展,
如果filedes为NULL,那么直接用返回值返回新创建的匿名管道的文件描述符。具体的内核补丁请看附件!
|
文件: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| linux-2.6.17-pipe_single_fd.patch.gz |
大小: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1KB |
下载: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 下载 |
|
阅读(2483) | 评论(0) | 转发(0) |