Question

I'm experimenting with this dup2 command in linux. I've written a code as follows:

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

int main()
{
    int pipe1_ends[2];
    int pipe2_ends[2];
    char string[]  = "this \n is \n not \n sorted";
    char buffer[100];
    pid_t pid;

    pipe(pipe1_ends);
    pipe(pipe2_ends);

    pid = fork();


    if(pid > 0) { /* parent */

        close(pipe1_ends[0]);
        close(pipe2_ends[1]);

        write(pipe1_ends[1],string,strlen(string));
        read(pipe2_ends[0], buffer, 100);   
        printf("%s",buffer);
        return 0;
   }

   if(pid == 0) { /* child */
       close(pipe1_ends[1]);
       close(pipe2_ends[0]);
       dup2(pipe1_ends[0], 0);
       dup2(pipe2_ends[1],1);
       char *args[2];
       args[0] = "/usr/bin/sort";
       args[1] = NULL;
       execv("/usr/bin/sort",args);    
   }
  return 0;
}

I expect this program to behave as follows: It should fork a child and replace its image with sort process. And since the stdin and stdout are replaced with dup2 command, I expect sort to read input from the pipe and write the output into the other pipe which is printed by the parent. But the sort program doesn't seem to be reading any input. If no commandline argument is given, sort reads it from the stdin right? Can someone help me with this problem, please.

Many thanks!

Was it helpful?

Solution

Hm. What's happening is that you aren't finishing your write: after sending data to the child process, you have to tell it you're done writing, either by closing pipe1_ends[1] or calling shutdown(2) on it. You should also call write/read in a loop, since it's quite likely in the general case that read at least won't give you all the results in one go. Obviously the full code checks all return values, doesn't it?

One final thing: Your printf is badly broken. It can only accept null-terminated strings, and the result returned by read will not be null-terminated (it's a buffer-with-length, the other common way of knowing where the end is). You want:

int n = read(pipe2_ends[0], buffer, 99);
if (n < 0) { perror("read"); exit(1); }
buffer[n] = 0;
printf("%s",buffer);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top