tve*_*eeg 2 c linux fork file-descriptor exec
我在Linux,A和B上有两个进程.我想从进程A与进程B共享文件描述符,现在我只是将它序列化为a char*并将其传递给execl参数,但这不起作用.
Ac看起来像这样:
union descriptor{
char c[sizeof(int)];
int i;
} fd;
pid_t pid;
fd.i = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// Perform other socket functions
pid = fork();
if(pid == 0){
// Read data from socket
if(execl("./B", fd.c, NULL) < 0){
exit(EXIT_FAILURE);
}else(
exit(EXIT_SUCCESS);
}
}else if(pid < 0){
exit(EXIT_FAILURE);
}else{
waitpid(pid, NULL, 0);
}
Run Code Online (Sandbox Code Playgroud)
Bc看起来像这样:
union descriptor{
char c[sizeof(int)];
int i;
} fd;
memcpy(&fd.c[0], argv[0], sizeof(int));
write(fd.i, "TEST", 4);
close(fd.i);
Run Code Online (Sandbox Code Playgroud)
但这不起作用,我不明白为什么不.我怎样才能做到这一点?如果它的工作原理,它是经过共享父母和孩子之间的文件描述符的最佳解决方案fork和一个exec?
问题与我提出的问题无关,它是由@OliCharlesworth指出的传递整数的错误方式引起的.请关闭这个问题.
File descriptors are always passed between a parent and child process
当您fork进行处理时,在父进程中打开的文件描述符(在时间fork())被隐式传递给子进程.没有必要明确发送它们.
例如:
伪代码如下:
在过程A:
fd = open_socket_or_file;
char str_fd[3];
str_fd[0]=fd;
str_fd[1]=fd;
str_fd[2]=0;
if(fork()==0)
{
execl("./B",str_fd,NULL);
}
Run Code Online (Sandbox Code Playgroud)
在子进程B中,您可以执行以下操作:
int fd = argv[1][0];
/* now do whatever you want with the fd...*/
Run Code Online (Sandbox Code Playgroud)
编辑:
如果进程不同,则需要显式传递文件描述符.这通常使用UNIX-Domain套接字完成(如果您使用的是Linux Flavors).对于与此相关的代码,您可以看到此答案
小智 5
是的,即使在 fork 或 exec 或 fork 和 exec 之后,文件描述符仍然保持打开状态。您只需要知道使用 exec 替换的新进程映像中的 fd 值,否则将该 fd 放在已知的进程映像上该过程(例如:0,1,2)。所以你可以通过两种方式做到这一点:
使用 dup2 将 fd 放置在任一标准文件描述符上(注意:据我所知,您将无法重置实际上已知的标准文件描述符)
将 fd 作为字符串参数传递给 6 个 exec 函数之一即可完成这项工作
因此,如果您希望保留标准 fds,我建议您使用第二种方法
这是两种实现方法:
P1.c(使用参数传递)
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
void main()
{
printf("Hello this is process 1\n");
int fd=open("./foo",O_RDONLY);
char buf[255];
//int n=read(fd,buf,255);
int h=fork();
if(h==0)
{
char *fname="./p2";
char *arg[3];
char targ[10];
sprintf(targ,"%d",fd);
arg[0]=fname;
arg[1]=targ;
arg[2]=NULL;
execvp(fname,arg);
}
else
{
printf("This is from p1 process\n");
//write(1,buf,strlen(buf));
//do some process with p1
printf("This is end of p1 process\n");
}
}
Run Code Online (Sandbox Code Playgroud)
P1.c(使用 dup2 带 0)
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
void main()
{
printf("Hello this is process 1\n");
int fd=open("./foo",O_RDONLY);
int h=fork();
if(h==0)
{
dup2(fd,0);//note we will be loosing standard input in p2
execvp(fname,NULL);
}
else
{
printf("This is from p1 process\n");
//write(1,buf,strlen(buf));
//do some process with p1
printf("This is end of p1 process\n");
}
}
Run Code Online (Sandbox Code Playgroud)
P2.c
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
int main(int argc,char *argv[])
{
int fd=atoi(argv[1]); //here fd=0 in case dup2 in process ps1.c
char buf[1024];
int n=read(fd,buf,1024);
buf[n]='\0';
printf("This is from p2\n");
write(1,buf,strlen(buf));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11098 次 |
| 最近记录: |