【问题标题】:send several strings through a pipe to a child process通过管道将多个字符串发送到子进程
【发布时间】:2020-06-14 09:08:18
【问题描述】:

我希望子进程循环监听父进程。如果它从父级接收到“exit”,则终止,如果接收到“cmd”,则将再次读取以使用 system() 执行的实际命令。 到目前为止我有这个代码,但是第二次阅读只是给了我相同的(“cmd”)

孩子:

pid = fork();
            if(pid == 0){           
            close(fd_pipe[1]);  // Close writing end
            dup2(fd_pipe[0],0); close(fd_pipe[0]);
            //close(fd_pipe[0]);

            //create file descriptor for user file
            int userFile_fd = 
            open(users_table.at(get_user(u_id)).get_filename().c_str(), O_APPEND|O_WRONLY);
            //redirect output to user file
            dup2(userFile_fd,1);
            close(userFile_fd);

            //listen in a loop till receive "exit"
            while(true){

                char buf[100];

                read (0, &buf, 100);
                cout << buf << endl;

                //logout
                if(strstr(buf, bye) != NULL){
                    cout << "Exiting..." << endl;
                    kill(getpid(), SIGKILL);
                    break;
                }

                //command
                else if(strcmp(buf, cmd) == 0){

                    read (0, &buf, 100);
                    cout << "reading buf again: "<<buf << endl;

                    system(buf);
                }
            }//end while

            }//end if (child process)

父母:


while(status == true){

    //get input
        cout << ("ucmd>");
        getline (cin, command);

//some preprocessing code and then...

        //this works fine
        else if(command.compare(logout)==0)
        {
            cout << " UM: Loggin out USER-"<<u_id<<" associated pipe ID: "<<user_pipe[u_id]<<endl;
            char exit2[] = "exit";
            write (user_pipe[u_id], exit2, sizeof(exit2));//sends exit message
        }

        //cmd
        else if(command.compare(cmd)==0)
        {   

            write (user_pipe[u_id], cmd, sizeof(cmd));//cmd command
            write (user_pipe[u_id], argument.c_str(), sizeof(argument.c_str()));//cmd command
            //call_cmd(u_id, argument);
        }

【问题讨论】:

  • 您不能在 C 中使用 cout &lt;&lt; ("ucmd&gt;"); — 那是 C++。你需要知道读取了多少字节——你没有捕捉到这些信息,所以你在盲目地工作。您提供的代码不是 MCVE (Minimal, Complete, Verifiable Example)(或 MRE 或 SO 现在使用的任何名称)或 SSCCE (Short, Self-Contained, Correct Example)。这意味着我们必须做太多工作来测试您的代码。
  • 在忽略每个系统调用返回的结果的情况下,您无法编写正确的 Unix 代码。
  • "你不能使用 cout ");"这个问题有标签 c++

标签: c++ pipe fork system-calls dup


【解决方案1】:

这对我来说看起来不对:

write (user_pipe[u_id], cmd, sizeof(cmd));//cmd command
write (user_pipe[u_id], argument.c_str(), sizeof(argument.c_str()));

cmd 是如何定义的?只有将代码定义为固定大小的字符数组时,您的代码才是正确的。第二行看起来肯定是错误的:argument.c_str() 返回一个char const *,所以sizeof(argument.c_str()) 将返回sizeof(char const *) 独立 的实际值argument。你可以试试这样:

char const *carg = argument.c_str();
write(user_pipe[u_id], carg, strlen(carg) + 1);

这样整个字符串(包括终止NUL)应该被传输给孩子。

那么在孩子身上,我认为你也必须更加小心。你会的

read (0, &buf, 100);

然后只使用来自buf 的第一个NUL 终止字符串。 read 操作可能已经读取了更多信息。您应该检查返回值。尤其要确保 read 返回的值 > 0。否则可能没有读取任何内容(可能有错误)并且 buf 的内容保持不变。

【讨论】:

  • 谢谢,是的,这一行是错误的,“write (user_pipe[u_id], argument.c_str(), sizeof(argument.c_str()));”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-19
  • 1970-01-01
  • 2016-06-02
  • 1970-01-01
相关资源
最近更新 更多