【问题标题】:C Programming fork() multiple pipe()C 编程 fork() 多管道()
【发布时间】:2012-10-21 18:40:47
【问题描述】:

我正在使用 pipe() forks() exec() dup() 模拟 shell。我已经在 stackoverflow 上看到了一些帖子来指导前进。但我的 prog 似乎与其他人在这里遇到的类似问题。

我使用的 LinkedList 结构包含:char* cmd 和 char** args(例如 cmd='ls' args = '-l -d')

以下是一些输出结果: ls -l ls -l -a (我想要多少个参数) ls -l |排序

ls -l | wc -w (runs but spits out wrong value)
ls | wc -w (runs, but spits out the wrong value)
ls (alone - no args, spits out A NULL argv[0] was passed through an exec system call.)
ls -l | sort | wc -w (causes system to hang)

它现在至少假装它正在接受多个参数但无效的结果或系统挂起。

void runCommand(Node* head)
{
    int old_fd[2], new_fd[2];
    int isValid, cpid, pid;

    //Loop through all commands
    for(int cmd = 0; cmd < cmdCount; cmd++)
    {
        //if(curr cmd has next cmd)
        if(cmd+1 < cmdCount)
        {
            //Create pipe new_fd
            if( pipe(new_fd) == -1) //pipe error
            {
            perror("Pipe Error.");
            exit(-1);
            }
        }

        //Parent
        if( (pid=fork()) != 0 ) //parent
        {
            //Wait for child process
            //wait(0); //moved below

            //Curr cmd has next command
            if(cmd+1 < cmdCount)
            {
                old_fd[0] = new_fd[0];
                old_fd[1] = new_fd[1];
            }

            //Curr cmd has previous command
            if(cmd-1 > -1)
            {
            close(old_fd[0]);
            close(old_fd[1]);
            }
        }
        //Child process
        else //if fork() == 0
        {
            //Curr cmd has previous command
            if(cmd-1 > -1)
            {
                dup2(old_fd[0], 0); // setting up old_pipe to input into the child
                close(old_fd[0]);
                close(old_fd[1]);
            }

            //Curr cmd has next command
            if(cmd+1 < cmdCount)
            {
                close(new_fd[0]); // setting up new_pipe to get output from child
                dup2(new_fd[1], 1);
                close(new_fd[1]);
            }

            printf("Running command '%s': \n",getCmd(cmd,head));
            printf("Arguments: "); printArgs(cmd,head);
            //Below works for 1 cmd 1+ args, but not 1 cmd 0 arg or mult pipes
            isValid = execvp(getCmd(cmd,head), getArgs(cmd,head));

            if(isValid == -1)
            printf("%s: Command not found.\n", getCmd(cmd,head));
        }
     wait();

    }
}

注意这个线程:Another_Stack_Overflow_Example 我使用了那里的示例并将我的函数替换为他们的“工作”示例。他们的工作示例似乎适用于大多数情况,除了一个没有像“ls”这样的参数的命令,它根本什么都不做。并要求输入

这里是请求的 getCmd() 和 getArgs() 函数,只需调用“getNode()”,它返回一个 Node* 结构(包含 char* 和一个 char** 和两个整数)getCmd 提取 char* cmd 和getArgs 提取 char** args。

char* getCmd(int index, Node* head)
{
  Node* curr = getNode(index,head);
  return curr->cmd;
}
char** getArgs(int index, Node* head)
{
  Node* curr = getNode(index,head);
  return curr->args;
}

【问题讨论】:

  • wait(0); 放错地方了。
  • 如果fork失败了怎么办?您没有正确处理这种情况。
  • 你能添加你的 getCmd() 和 getArgs() 函数吗?
  • @wildplasser: 移动 wait() 查看输出结果.......
  • @Kylo:发布了这两个函数,我应该在里面有 fork 失败代码,但是通过查看它可能有人会发现我哪里出错了。

标签: c unix fork pipe


【解决方案1】:

两件事:

1。 您应该将一个 NULL 终止的数组传递给 execvp()

execvp("ls", NULL); // invalid!!!

这应该是:

const char *args[1] = { NULL };
execvp("ls", args);

2。 “管道操作员” |是一个 shell 扩展,所以你不能在 exec... 函数中使用它。您只能在此处指定一个可执行文件。

【讨论】:

  • 在我的解析函数(终端用户输入)中,它将命令放在 malloc char* 中,并将参数标记为 malloc char**,我对 args char** 做了 malloc + 1 * 并将最后一个值设置为 NULL,因此这些已经完成。 runCommand() 使用 execvp(char*,char** null 终止)。
  • struct(包含 char* 和一个 char** 和两个 int)getCmd 提取 char* cmd,getArgs 提取 char** args。
  • 好的。所以最后一个。我可以看看你如何在这个结构中初始化你的 args 吗?即你把论点放在那里的方式。
猜你喜欢
  • 1970-01-01
  • 2013-05-06
  • 1970-01-01
  • 1970-01-01
  • 2020-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多