传递文件描述符 - Execve(类型转换)

发布于 2024-12-03 23:22:28 字数 850 浏览 1 评论 0原文

我想知道如何通过 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};

然后子进程在 fork() 之后调用 execve ,如下所示:

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 为孩子们重定向到 stdinstdout,但我实际上必须按照项目的说明将管道描述符传递给孩子。

任何帮助表示赞赏。

I am wondering how I can pass a file descriptor through the execve() command and then access it on the other side. I know that I can use dup2 to redirect the file-descriptor but I cannot do that. I am required to actually pass the file descriptor to the child and use it in the child.

What I have done so far:

Parent makes pipe + args like the following:

int pfd[2];
if(pipe(pfd) == -1)
    exitWithError("PIPE FAILED", 1);
char *args_1[] = {"reader", argv[1], (char*) pfd, (char *) 0};

Then the child calls execve after fork() like the following:

close(pfd[1]);
execve("./reader", args_1, NULL);

Then, in the reader program I try to access pipe descriptor that was passed:

int main(int argc, char* argv[]){
    ...
    write(argv[2][1], buf, read_test);

argv[2] should be referencing the pipe descriptor, then the argv[1] should go to the write end of the pipe. I am almost positive that I need to do some type-casting differently here, but everything I try doesn't quite work out.

NOTE: I have a working version of this program using dup2 to redirect to stdin and stdout for the children, but I have to actually pass the pipe descriptor to a child as per instructions of the project.

Any help is appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

沫离伤花 2024-12-10 23:22:28

简单地将文件描述符转换为 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);

Simply casting the file descriptor to a char* isn't a good idea. It could cause data loss if the OS chooses to copy the strings and stops at the 0 bytes, so the data isn't entirely copied. It would be safer to create a string containing the file descriptor.

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};

The reader program then uses atoi to convert this back into an int.

int fd = atoi(argv[2]);
write(fd,buf,read_test);

If you really want to use a cast, then you need to cast argv[2] as int* in your reader.

write(((int*)argv[2])[1],buf,read_test);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文