简体   繁体   English

C编程fork()多个管道()

[英]C Programming fork() multiple pipe()

Im simulating a shell using pipes() forks() exec() dup(). 我使用pipes()forks()exec()dup()模拟了shell。 Ive seen a few posts on stackoverflow to guide be along the way. 我已经看到了一些关于stackoverflow的文章来指导开发。 But my prog seems to have similar issues as others have encountered here. 但是我的编似乎和在此遇到的其他问题类似。

I use a LinkedList struct contains: char* cmd and char** args (ex. cmd='ls' args = '-l -d') 我使用的LinkedList结构包含:char * cmd和char ** args(例如,cmd ='ls'args ='-l -d')

Here are some output results: ls -l ls -l -a (as many args I want) ls -l | 以下是一些输出结果:ls -l ls -l -a(我想要的许多args)ls -l | sort 分类

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)

It now at least pretend like it is taking the multiple args but invalid results or system hanging. 现在至少假装正在使用多个arg,但是结果无效或系统挂起。

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();

    }
}

Note this thread: Another_Stack_Overflow_Example I used the example there and replaced my function with their "Working" sample. 请注意以下线程: Another_Stack_Overflow_Example我在此处使用了示例,并用其“工作”示例替换了我的函数。 Their working sample seems to work for most everything except a single command with no arguments like "ls" it simply just does nothing. 他们的工作示例似乎适用于大多数情况,除了一个没有参数(例如“ ls”)的命令之外,它只是不执行任何操作。 and asks for input 并要求输入

Here is the requested getCmd() and getArgs() functions, just calls "getNode()" which returns a Node* struct (containing char* and a char** and two ints) the getCmd extracts the char* cmd and the getArgs extracts the char** args. 这是请求的getCmd()和getArgs()函数,只需调用“ getNode()”即可返回Node *结构(包含char *和char **和两个整数),getCmd提取char * cmd,而getArgs提取char **参数。

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

Two things: 两件事情:

1. You should pass a NULL terminated array to execvp() : 1.您应该将NULL终止的数组传递给execvp()

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

This should be: 应该是:

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

2. "Pipe operator" | 2.“管道运算符” | is a shell extension so you cannot use it in exec... functions. 是shell扩展,因此您不能在exec ...函数中使用它。 You can specify only a single executable there. 您只能在此处指定一个可执行文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM