【问题标题】:Read pipe from another .c with use of exec, c programm使用 exec、c 程序从另一个 .c 读取管道
【发布时间】:2012-05-29 14:45:13
【问题描述】:

我在从另一个 .c 通过 execl 创建的管道读取数据时遇到问题!我已经尝试了很多不同的方法,但我仍然找不到解决方案。如果您能帮助我,我将不胜感激!

这是第一个代码:

...for 循环之前的一些其他代码...

for (counter=0; counter<arithmos; counter++)
   {
       if (pipe(pinakas[counter]) == -1)
       {
           perror("pipe");
           exit(1);
       }
       sem_wait(&sima);
       strcpy(buffer,queueHead(q));
       write(fd[WRITE], buffer, strlen(buffer));
       queueRemove(&q);
       nodes--;
       sem_post(&sima);
       pid = fork();
       if (pid < 0)
       {
           perror("fork error");
           exit(1);
       }
       if (pid == 0)
       {
            execl("./paidi","paidi", (char*)pinakas[counter], (char*)NULL);
            exit(1);
       }
       if (pid > 0)
       {

          printf ("I am the parent with pid %d\n", getpid());
          wait(NULL);

       }
   } 

这就是我的孩子所做的......

包括等等等等……

int main(int argc, char **argv)
 {
    //char fd[2];
    int *fd = (int*) argv[1];
    int nbytes;
    char buffer[256];
    char *command;
    int i;

    for (i=0; i<256; i++)
    {
        buffer[i] = '\0';
    }

    printf("test2 %d\n",fd[READ]);
    //close(fd[WRITE]);
    printf("test3\n");
    read(fd[READ], buffer, 256);
    printf("test4\n");
    close(fd[READ]);
    printf("test5\n");
    printf("Received url : %s", buffer );
    printf("test6\n");
    //sprintf(command,"wget %zd", url);
    //system(command);
    printf("I am a child with pid %d\n", getpid());
    return 0;
}

好像我在 execl 上做错了什么。我正在尝试将指针作为参数传递,并且我有一个管道:地址错误。我也用字符串尝试过,但什么都没有……有什么想法吗?

【问题讨论】:

  • pipe(pinakas[counter]) 这样还能编译吗?
  • 你不能在进程之间传递指针。您不应该尝试在命令参数中将整数作为字符串传递给execv()(将值转换为字符串并传递字符串)。您需要在父子节点中关闭未使用的管道端。从代码中不清楚为什么要使用管道,因为父母既不向孩子发送任何东西,也不从孩子那里读回任何东西。也不清楚为什么你有信号量操作,但我们可以假设它们与作业的其他部分相关。
  • 我正在使用 write 发送...!我的管道被命名为 fd,而 pinakas[] 是一个包含许多 fd 的数组,所以我通过 exec 传递我需要的特定管道
  • 如果父级正在写入子级,父级必须关闭管道的读取端,子级必须关闭管道的写入端,反之亦然,如果父级正在从孩子。如果不这样做会导致“未检测到 EOF”,直到写入过程退出或管道的写入端被 close() 或等效项关闭。在进程之间进行管道连接时,您需要确保您已经考虑了所有文件描述符。如果将管道重定向到标准输入或标准输出,则关闭管道本身的两端。
  • "pinakas[] 是一个包含许多 fd 的数组"——因此您将一个整数(可能为零)传递给 pipe,而不是一个指向两个整数数组的指针。再一次,我很惊讶这个编译,但即使execve(见 Nikolai N Fetissov 的回答),我看不出对pipe 的调用如何不会失败。跨度>

标签: c exec fork pipe


【解决方案1】:

execve(2) 为加载的可执行文件创建了一个全新的内存空间,您不能传递以前程序的指针,它们在新的内存空间中没有任何意义。

这里经过验证的真正方法是使用dup2(2)fork(2) 之后但在execve(2) 之前用pipe(2) 的读取端替换孩子的标准输入(文件描述符0)。

【讨论】:

  • 正确,尽管您对问题的描述并非 100% 准确。他传递的不是指针,而是伪装成一的整数。 execl 需要指向以 NULL 结尾的字符串的指针,它将其复制到其他地方并提供指向副本的指针。所以不会保留原来的指针值。
  • @ugoren,你是对的。看着那段代码,我的眼睛太疼了:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-20
  • 2012-09-14
  • 2014-03-23
  • 2018-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多