Question

I have been trying to get this to work and am beginning to think its not possible to use pipes in this way.

Is this possible? Keeping a pipe open while the parent uses a fgets while loop to push input to the child process? The child process will then detect the input (passed through stdin) and print it to the screen.

If it is not possible, why not?

pipe.c:

#define MAXINPUTLINE 10240

int pid, p[2];
char input[MAXINPUTLINE];

int main(void)
{
    char* arguments[] = {"./bin/child_program", "arg1", NULL};

    if(pipe(p) == -1) {
        printf("Pipe Failed\n");
        exit(1);
    }
    pid = fork();
    if(pid == -1) {
        printf("Fork Failed\n");
        exit(1);
    }

    int status;

    if(pid == 0) {  //child
        close(p[1]); //close stdout
        dup2(p[0],0); //open stdin
        execvp(arguments[0],arguments);
    }
    else { //parent
        close(p[0]);
        while (fgets(input, sizeof(input), stdin))
            write(p[1],input,strlen(input)+1);
        wait(&status);
    }

    return 0;
}

child_program:

    #define MAXINPUTLINE 

    int main(int argc, char *argv[])
    {   
        char input[MAXINPUTLINE];

        while (fgets(input, sizeof(input), stdin)) { 
            printf(" Input Recieved: %s :",input);
        }

        return 0;
    }
Was it helpful?

Solution

I have a working code for what you are trying to achieve here:

https://sourceware.org/git/?p=netresolve.git;a=blob;f=backends/exec.c;h=026b137973b35a7232b0554a7e7b8dfc1a023051;hb=HEAD#l45

static bool
start_subprocess(char *const command[], int *pid, int *infd, int *outfd)
{
    int p1[2], p2[2];

    if (!pid || !infd || !outfd)
            return false;

    if (pipe(p1) == -1)
            goto err_pipe1;
    if (pipe(p2) == -1)
            goto err_pipe2;
    if ((*pid = fork()) == -1)
            goto err_fork;

    if (*pid) {
            *infd = p1[1];
            *outfd = p2[0];
            close(p1[0]);
            close(p2[1]);
            return true;
    } else {
            dup2(p1[0], 0);
            dup2(p2[1], 1);
            close(p1[0]);
            close(p1[1]);
            close(p2[0]);
            close(p2[1]);
            execvp(*command, command);
            /* Subprocess error occured. */
            fprintf(stderr, "error running %s: %s\n", *command, strerror(errno));
            abort();
    }

err_fork:
    close(p2[1]);
    close(p2[0]);
err_pipe2:
    close(p1[1]);
    close(p1[0]);
err_pipe1:
    return false;
}

You can consider this function public domain. It accepts a NULL-terminated list of command line arguments including the command itself and it sets the process id and file descriptors to talk to stdin and stdout output parameters.

On top of that you would acquire some knowlege about read/write POSIX-style functions (and syscalls), fgets/fputs and similar (buffered) ANSI-style functions and the bridges between them like fdopen.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top