在其他unix系统中,比如BSD,有一个调用直接连接两个文件描述符来做你想做的事,但不知道在linux中是否有系统调用来做这件事。无论如何,这不能用FILE *
描述符来完成,因为这些是库用来表示文件的缓冲文件的实例。您可以通过调用函数调用来获取实例的<stdio.h>
文件描述符(如系统所知) 。FILE *
getfd(3)
您尝试从系统中获取的语义非常复杂,因为您希望某些东西可以直接将数据从一个文件描述符传递到另一个文件描述符,而无需任何进程(直接在内核中)的干预,并且内核需要一个池线程来完成直接从读取调用复制到写入调用的工作。
这样做的旧方法是创建一个线程,该线程从一个文件描述符(而不是FILE *
指针)读取并写入另一个文件描述符。
要评论的另一件事是,pipe(2)
系统调用为您提供了两个连接的描述符,允许您read(2)
在一个(索引)中的第二个(索引)中的 n 是0
什么。如果您是第二个进程,并且您对这两个进程都进行了调用,那么您将有两个管道(每个都有两个描述符),每个进程中都有一个,它们之间没有任何关系。您将只能与每个进程与其自身进行通信,但不能与另一个进程(它对其他进程的管道描述符一无所知),因此它们之间将无法进行通信。write(2)
1
fork(2)
pipe(2)
接下来是您尝试执行的操作的完整示例:
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#define length 100
#define FMT(fmt) "pid=%d:"__FILE__":%d:%s: " fmt, getpid(), __LINE__, __func__
#define ERR(fmt, ...) do { \
fprintf(stderr, \
FMT(fmt ": %s (errno = %d)\n"), \
##__VA_ARGS__, \
strerror(errno), errno); \
exit(1); \
} while(0)
void copy(int fdi, int fdo)
{
unsigned char buffer[length];
ssize_t res, nread;
while((nread = res = read(fdi, buffer, sizeof buffer)) > 0) {
res = write(fdo, buffer, nread);
if (res < 0) ERR("write");
} /* while */
if (res < 0) ERR("read");
} /* copy */
int main()
{
int pip[2];
int res;
res = pipe(pip);
if (res < 0) ERR("pipe");
char *filename;
switch (res = fork()) {
case -1: /* error */
ERR("fork");
case 0: /* child */
filename = "file1";
res = open(filename, O_RDONLY);
if (res < 0) ERR("open \"%s\"", filename);
close(pip[0]);
copy(res, pip[1]);
break;
default: /* parent, we got the child's pid in res */
filename = "file2";
res = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0666);
if (res < 0) ERR("open \"%s\"", filename);
close(pip[1]);
copy(pip[0], res);
int status;
res = wait(&status); /* wait for the child to finish */
if (res < 0) ERR("wait");
fprintf(stderr,
FMT("The child %d finished with exit code %d\n"),
res,
status);
break;
} /* switch */
exit(0);
} /* main */