我正在尝试使用C代码工作,而不是调用命令行find。
子3'的'功能'通过pi2传递给child2函数'cut'工作正常,当执行时包含所有3个子函数时,程序卡在父进程waitpid()中。
我试图隔离参与套接字的唯一孩子,当我在gdb上运行可执行文件时,我收到消息“find:'standard output':Broken pipe”和“find:write error”
以下是与套接字交互的两个子函数的示例: 孩子1:
void child1()
{
int sock;
struct sockaddr_un remote;
sock = socket(AF_UNIX, SOCK_STREAM, 0)
memset(&remote, 0, sizeof(struct sockaddr_un));
remote.sun_family = AF_UNIX;
strncpy(remote.sun_path, "socket", sizeof(remote.sun_path) - 1);
while((connect(sock, (struct sockaddr *)&remote, (socklen_t)sizeof(remote))) == -1)
{
if(errno != ENOENT && errno != ECONNREFUSED)
erro("child 2 failed to connect to socket");
}
dup2(sock, 1);
close(sock);
execlp("find", "find", ".", "-type" , "f", "-ls", NULL);
}
和Child2:
void child2(int *pipe_fd)
{
int sock;
struct sockaddr_un local, remote;
socklen_t sock_size = (socklen_t)sizeof(remote);
sock= socket(AF_UNIX, SOCK_STREAM, 0);
memset(&local, 0, sizeof(struct sockaddr_un));
memset(&remote, 0, sizeof(struct sockaddr_un));
local.sun_family = AF_UNIX;
strncpy(local.sun_path, "socket", sizeof(local.sun_path) - 1);
unlink("socket");
bind(sock, (struct sockaddr *)&local, sizeof(struct sockaddr_un));
listen(sock, 1);
sock = accept(sock,(struct sockaddr *)&remote, &sock_size));
dup2(sock, STDOUT_FILENO);
close(sock);
close(pipe_fd[0]);
dup2(pipe_fd[1],1);
close(pipe_fd[1]);
execlp("cut", "cut", "-d", " ", "-f", "3-", NULL);
}
没有必要具体解决这个问题,我只是想了解我在创作过程中做错了什么,所以我将来不再这样做了。 我事先得到任何帮助。
答案 0 :(得分:2)
如果我将dup2(sock, STDOUT_FILENO);
更改为dup2(sock, STDIN_FILENO);
中的child2
(输入有袜子,输出是通向child3
的管道),您的示例基本上工作原理:
(需要进行错误检查)
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/un.h>
#include <sys/wait.h>
void child1()
{
int sock;
struct sockaddr_un remote;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
memset(&remote, 0, sizeof(struct sockaddr_un));
remote.sun_family = AF_UNIX;
strncpy(remote.sun_path, "socket", sizeof(remote.sun_path) - 1);
while((connect(sock, (struct sockaddr *)&remote, (socklen_t)sizeof(remote))) == -1)
{
perror("connect");
if(errno != ENOENT && errno != ECONNREFUSED)
perror("child 2 failed to connect to socket");
}
dup2(sock, 1);
close(sock);
execlp("find", "find", ".", "-type" , "f", "-ls", (char*)0);
}
void child2(int *pipe_fd)
{
int sock;
struct sockaddr_un local, remote;
socklen_t sock_size = (socklen_t)sizeof(remote);
sock= socket(AF_UNIX, SOCK_STREAM, 0);
memset(&local, 0, sizeof(struct sockaddr_un));
memset(&remote, 0, sizeof(struct sockaddr_un));
local.sun_family = AF_UNIX;
strncpy(local.sun_path, "socket", sizeof(local.sun_path) - 1);
unlink("socket");
bind(sock, (struct sockaddr *)&local, sizeof(struct sockaddr_un));
listen(sock, 1);
puts("listened");
sock = accept(sock,(struct sockaddr *)&remote, &sock_size);
dup2(sock, STDIN_FILENO);
close(sock);
close(pipe_fd[0]);
dup2(pipe_fd[1],1);
close(pipe_fd[1]);
execlp("cut", "cut", "-d", " ", "-f", "3-", (char*)0);
}
void child3(int *pipe_fd)
{
dup2(pipe_fd[0],0);
close(pipe_fd[0]);
execlp("sort", "sort", (char*)0);
}
int main()
{
int pi[2];
pid_t pid0, pid1, pid2;
pid0 = fork();
if (0==pid0){
child1();
_exit(1);
}
pipe(pi);
pid1 = fork();
if(0==pid1){
child2(pi);
_exit(1);
}
close(pi[1]);
pid2 = fork();
if(0==pid2){
child3(pi);
_exit(1);
}
close(pi[0]);
wait(0);
wait(0);
wait(0);
}
这基本上是一个三重管道:
find | cut | sort
其中第一个|
不是常规管道,而是通过"socket"
的UNIX套接字连接。