我正在尝试使用共享内存重定向命令。
总结一下:我的程序运行如下:我运行./server等待信息,当我运行./client时写入。客户端通过命名管道(mkfifo)将信息发送到服务器。该信息是:要执行的命令类型,数据和共享内存段的名称(使用shm_open ftruncate shm_unlink在客户端创建,最后在char * addr = mmap()....中创建)。如果我在没有重定向标准输出的情况下启动程序,命令的结果将显示在执行服务器的终端中......不过,我希望它出现在客户端中! 这是服务器中的一段代码:
if ((fd = shm_open(req->shm_name, O_RDWR, S_IRUSR | S_IWUSR)) == -1) {
perror("shm_open");
exit(EXIT_FAILURE);
}
char *dir = malloc(sizeof(char) * 256);
int tube[2];
if (pipe(tube) == -1) {
perror("tube");
exit(EXIT_FAILURE);
}
switch (fork()) {
case -1:
perror("fork");
exit(EXIT_FAILURE);
case 0:
getcwd(dir, 256);
strcat(dir, "/info_proc");
char *pid = malloc(10 * sizeof(char));
sprintf(pid, "%d", req->data);
if (close(tube[0]) == -1) {
perror("close");
exit(EXIT_FAILURE);
}
if (dup2(tube[1], STDOUT_FILENO) == -1) {
perror("dup2");
exit(EXIT_FAILURE);
}
/*if (dup2(fd, STDIN_FILENO) == -1) {
perror("dup2");
exit(EXIT_FAILURE);
}*/
execl(dir, "info_proc", pid, NULL);
perror("execl");
exit(EXIT_FAILURE);
default:
wait(NULL);
/*if (dup2(fd, tube[0]) == -1) {
perror("dup2");
exit(EXIT_FAILURE);
}*/
if (close(tube[1]) == -1) {
perror("close");
exit(EXIT_FAILURE);
}
char *received = malloc(sizeof(char) * BUFFER_SIZE);
while (read(tube[0], &received, sizeof(received)));
//addr = received;
/*fd = tube[0];
if (read(tube[0], &addr, BUFFER_SIZE) == -1) {
perror("write");
exit(EXIT_FAILURE);
}*/
break;
}
我该怎么做?
答案 0 :(得分:0)
虽然您应该能够通过fmemopen()
将流映射到共享内存段,但您需要文件描述符才能通过{{1}执行重定向或其兄弟姐妹。您可以通过dup2()
函数为大多数流提取文件描述符,但我发现这对内存流不起作用,可能是因为这些流与内核中的底层打开文件描述不对应。
因此,如果要捕获已执行命令的标准输出(可能是标准错误?),那么您需要将其重定向到管道,并在管道的另一端使用另一个进程服务将数据复制到共享内存段。
这是一种对我有意义的方法:
注意:
fileno()
将直接重定向到共享内存段,但它仍然可以帮助您fmemopen()
来获取服务器需要知道的共享内存段的大小fstat()
而不是管道,分叉等可以简化孙子的创建和管理。