1

I'm trying to make a program that will simulate unnamed pipes, exactly as is possible to do in the terminal in Ubuntu. The program recieves file names and commands to execute for each file. I want to string the programs' input/output through pipes such that the first program's input will be std.in, and its' output will be the second program's input and so forth. Here's what I have so far:

void np_exec(char* cmd, char** argv)
{


    while(*(++argv) != NULL)
    {
            int pid = fork(); //parent executes
            if(pid < 0)
            {
                    printf("Error forking")
                    exit(1);
            }

            if(pid != 0) // parent
                    if (execvp(cmd, *argv) == -1)
                            perror("execvp failed");

                    //somewhere here i want to pipe input to output

    }
}

int main(int argc, char** argv)
{
    assert(strcmp(argv[argc-1], "-"));

    int i;
    for (i = 1; i < argc; ++i) {
            if (!strcmp(argv[i], "-"))
            {
                    argv[i] = NULL;
                    np_exec(argv[1], &argv[1]);
                    argv = &argv[i];
                    argc -= i;
                    i = 0;
            }
    }

    char* args[argc];
    args[argc-1] = NULL;

    for (i = 1; i < argc; ++i) {
            args[i-1] = argv[i];
    }

    if (execvp(args[0], args) == -1)
            perror("execvp failed");
    return;
}
}

As you can see, I'm struggling with the pipe implementation. Also, is there a way to test if this program works? Is there a command to write to a file (which will then hopefully carry on to the others?)

Mathieu Guindon
  • 69,817
  • 8
  • 107
  • 235
Mark A
  • 11
  • 1
  • you shouldn't have to do anything. just read from stdin, write to stdout, done... `$ app1 | app2 | app3 | etc...` – Marc B May 22 '15 at 17:06
  • What's wrong with using `pipe()`? – Ignacio Vazquez-Abrams May 22 '15 at 17:07
  • Marc, I'm trying to implement exactly that, with my own program. Ignacio, I'm having some trouble unerstanding exactly where to put pipe(). Is it after I fork()? How will I connect all of the pipes together? Thanks for the help. – Mark A May 22 '15 at 17:11
  • FYI, the tag wiki excerpt for the [tag:code-review] tag reads ***DO NOT USE THIS TAG. *Code reviews are off-topic on Stack Overflow, please use codereview.stackexchange.com to request a code review of otherwise working code.*** – Mathieu Guindon May 22 '15 at 17:16
  • I would suggest a different name for the question. What you are trying to do is making a shell functionality. Perhaps you should have led with that. Or whatever, it's ambiguous but not misleading. – ZbyszekKr May 22 '15 at 17:19
  • You do it in exactly the same way as with [socketpair](http://stackoverflow.com/q/11461106/212858) (since I already wrote an answer for that) - create the pipe before forking, and have each child use a different end – Useless May 22 '15 at 17:29
  • 1
    @Mat'sMug *"As you can see, I'm struggling with the pipe implementation. Also, is there a way to test if this program works?"* indicates that it does not belong on Code Review. Please read [Be careful when recommending Code Review to askers](http://meta.stackoverflow.com/questions/253975/be-careful-when-recommending-code-review-to-askers) :) – Simon Forsberg May 22 '15 at 17:39
  • 1
    @SimonAndréForsberg I wasn't recommending CR, merely pointing out that the tags were misused. – Mathieu Guindon May 22 '15 at 17:41

1 Answers1

0

There already exists an article explaining the solution to a similar problem: Using dup2 for piping

Basically, you connect your parent's stdout to the child's stdin.

To test, just write one test program (you could also do this in the parent) that writes characters to stdout with putchar() and another (for the child process) that reads from stdin with getchar().

Community
  • 1
  • 1
greyhairredbear
  • 624
  • 3
  • 10
  • 27