我想知道如何通过execve()
命令传递文件描述符,然后在另一端访问它。我知道我可以使用dup2
重定向文件描述符,但我不能这样做。我需要将文件描述符实际传递给子进程并在子进程中使用它。
到目前为止我做了什么:
父对pipe
+ args进行如下操作:
int pfd[2];
if(pipe(pfd) == -1)
exitWithError("PIPE FAILED", 1);
char *args_1[] = {"reader", argv[1], (char*) pfd, (char *) 0};
然后,孩子在execve
之后调用fork()
,如下所示:
close(pfd[1]);
execve("./reader", args_1, NULL);
然后,在读者程序中,我尝试访问传递的管道描述符:
int main(int argc, char* argv[]){
...
write(argv[2][1], buf, read_test);
argv[2]
应该引用管道描述符,然后argv[1]
应该转到管道的写端。我几乎肯定我需要在这里做一些不同的类型转换,但我尝试的一切都不太合适。
注意:我有一个使用dup2
的程序的工作版本,可以为孩子们重定向到stdin
和stdout
,但我必须要通过根据项目说明将管道描述符发送给子项。
感谢任何帮助。
答案 0 :(得分:2)
简单地将文件描述符转换为char*
并不是一个好主意。如果操作系统选择复制字符串并停止在0字节,则可能导致数据丢失,因此数据不会完全复制。创建包含文件描述符的字符串会更安全。
int pfd[2];
if(pipe(pfd) == -1)
exitWithError("PIPE FAILED", 1);
char string1[12]; // A 32 bit number can't take more than 11 characters, + a terminating 0
snprintf(string1,12,"%i",pfd[1]); // Copy the file descriptor into a string
char *args_1[] = {"reader", argv[1], &string1[0], (char *) 0};
然后,读者程序使用atoi
将其转换回int。
int fd = atoi(argv[2]);
write(fd,buf,read_test);
如果你真的想要使用演员,那么你需要在你的读者中将argv[2]
作为int*
。
write(((int*)argv[2])[1],buf,read_test);