1

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
J. Doe
  • 21
  • 3
  • 1
    hi, you are executing a new image with exec*() family, which completely replaces original image. Like program text, heap, stack etc. – NishanthSpShetty Nov 07 '17 at 05:35
  • Read [ALP](http://www.makelinux.net/alp/) and man pages like [execve(2)](http://man7.org/linux/man-pages/man2/execve.2.html) – Basile Starynkevitch Nov 07 '17 at 05:37
  • Compile with all warnings and debug info: `gcc -Wall -Wextra -g` then **use the debugger `gdb`** and [strace(1)](http://man7.org/linux/man-pages/man1/strace.1.html). Add debugging `printf`. Check that `execlp` did not fail (e.g. by following it with `perror("execlp");` ....) – Basile Starynkevitch Nov 07 '17 at 05:39
  • 1
    You should close `fd[0]` in the child after duplicating it to standard input. This time, you get away with it; you won't always do so. – Jonathan Leffler Nov 07 '17 at 06:10
  • Thanks, guys. I was able to get it working by replacing sizeof(line), with strlen(line). I also added the perror, and close(fd[0]) where you guys mentioned. – J. Doe Nov 07 '17 at 16:13

1 Answers1

1

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 (e.g. 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.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Thank you! strlen fixed it right up. I also put in the code that you, Basile Starynkevitch, and Jonathan Leffler mentioned to error check. This is the first C class I take, and the professor never went over gdb debugger. I'll be sure to look into it. Thanks again everyone. – J. Doe Nov 07 '17 at 16:11
  • You surely need to learn how to use `gdb`. Its documentation has a nice tutorial page. – Basile Starynkevitch Nov 07 '17 at 16:14