简体   繁体   中英

C - Pipe input from one program to another program

I'm supposed to create two programs (main and aux), where main forks a child to execute aux. The parent takes input from the user, until blank line '\\n', and the child executes aux, which is supposed to print the input back out. I'm able to get it to work in main with the commented code instead of execlp(), but cannot get execlp(aux) to work correctly. Any help is appreciated.

"main.c"

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    int fd[2], i;
    char line[100], buffer[100];

    pipe(fd);

    pid_t pid = fork();

    if (pid < 0) {
            printf("Fork Failed\n");
            exit(-1);
    }
    else if (pid > 0) {
            close(fd[0]);
            while(fgets(line, sizeof(line), stdin) && line[0] != '\n') {
                    write(fd[1], line, sizeof(line));
            }
            close(fd[1]);
    }
    else {
            close(fd[1]);
            dup2(fd[0], STDIN_FILENO);

            //while(read(fd[0], buffer, sizeof(buffer)))
            //      printf("> %s", buffer);

            execlp("./aux", "aux", (char *)0);
    }
    return 0;
}

"aux.c"

#include <stdio.h>
#include <stdlib.h>

int main() {
    char data[100];

    while(fgets(data, sizeof(data), stdin))
            printf(">%s\n", data);

    return 0;
}

sample input/output

this
>this

is a test
>
> test

only prints larger text with random \n
>
>ts larger text with random \n

Your call to write(2) is wrong (you always write 100 bytes even for shorter line -s):

                write(fd[1], line, sizeof(line)); // WRONG

should probably be using strlen(3)

            size_t ll = strlen(line);
            ssize_t wc = write(fd[1], line, ll);
            if (wc != ll)
              fprintf(stderr, "write was wrong (only %d, wanted %d) - %s\n",
                      (int) wc, (int) ll, strerror(errno));

Since you want to write only the filled bytes of the line buffer, not always 100 bytes each time (some of them not being initialized).

In your case sizeof(data) is 100 since you declared char data[100];

Please read carefully the documentation of every used function (and also ALP or some other book on Unix/POSIX/Linux programming). The documentation of strerror(3) and of errno(3) tells that you need to add:

  #include <string.h>
  #include <errno.h>

Actually, if you want to use read(2) and write(2) directly (without stdio(3) ) you should prefer using larger buffers (eg 4Kbytes each at least for efficiency) and you need to manage partial read -s and write -s and do your buffering by yourself.

BTW, compile with all warnings and debug info: gcc -Wall -Wextra -g and learn to use the gdb debugger and strace(1) (and valgrind ). In general, be scared of undefined behavior (however, at a first glance, your program don't seem to have UB).

Notice that execlp(3) could fail. Consider adding some call to perror(3) after it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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