0

Following this SO question & answer

Connecting n commands with pipes in a shell?

I tried executing yes | head but it runs in an infinite loop or it never responds back. What is the issue.

I did made some changes and here is the running code

#include <unistd.h>

struct command
{
    const char **string;
};

Helper Function

pid_t start(command* command, pid_t pid, int* status, int in, int out) {
    (void) pid;
    pid_t cpid;
    int childInt;

    cpid = fork();
    if (cpid == 0) {

        if (in != 0)
        {
            dup2(in, 0);
            close(in);
        }


        if (out != 1)
        {
            dup2(out, 1);
            close(out);
        }

            execvp(c->string[0], c->string);
            _exit(1);
        }

        waitpid(cpid, &childInt, 0);
    }


    *status = childInt;
    return c->pid;
}

and in my main function

for(int i = 0; i < n; i++)
    //New command every loop
    int p = pipe(fd);
    if (p == 0)
    {
        start_command(c, 0, &status, in, fd[1]);
        close(fd[1]);
        in = fd[0];
    }
    continue;
}
dup2(in, 0);
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Basit Anwer
  • 6,742
  • 7
  • 45
  • 88
  • 2
    What is your question? You might take another look at your code and put together a [mcve] that compiles. – Retired Ninja Mar 23 '19 at 20:54
  • 1
    your *start_command* waits for the command's completion... so ask yourself if you do `yes` and wait for *its* completion (which it never does since you're keeping the other end of the pipe open)... and never even get to executing `head` – Antti Haapala -- Слава Україні Mar 23 '19 at 20:56
  • Code works fine. The error lied in reading the file from where i was reading the commands to execute. Caught me completely off guard. – Basit Anwer Mar 25 '19 at 07:28

1 Answers1

4

If you want to execute yes | head, you need to create two processes, yes and head, and you need to connect them with a pipe. You have no code to do that, you just execute yes and pass it | head. This causes yes to output "| head" over and over forever.

You can't just pass yes and | head to execvp. You could execvp a shell and pass it yes | head since shells have the necessary code to create pipelines, spawn multiple processes, and hook them up appropriately.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278