Question

I'm trying to imitate the function of the shell command line:

printenv |grep VISUAL

by creating a child process, executing grep in it, and from the parent function writing the environment variables to a pipe connected to grep. This doesn't work though; the grep function keeps printing everything I write to it(whatever string I grep for). This is the code (I removed the checking and handling of error codes):

#define PIPE_READ 0
#define PIPE_WRITE 1
pid_t pid;


int main(int argc, char *argv[], char *envp[])
{
   int pipe_fd[2];
   int return_value, status;
       return_value=pipe(pipe_fd);
       pid=fork();
    if(pid==0)
    {
        dup2(pipe_fd[PIPE_READ], STDIN_FILENO); /*Grep should read from pipe*/
        close(pipe_fd[PIPE_READ]);
        close(pipe_fd[PIPE_WRITE]);
        char *arg_list[] = {"grep", "VISUAL",NULL};
        execvp("grep", arg_list); /*here somewhere is where I think the problem 
  lies, although I've tried everything here. The first argument is the command to
  execute, the second is the name of it again, the thirt should be the string to 
  search for and a file is optional, if there's no file it should read from 
  stdin (the pipe).*/
     }

     else /*parent process*/
     {
         close(pipe_fd[PIPE_READ]);
         int i;
                     /*Write the environment variables to the pipe.*/
         for(i=0; envp[i]!=NULL; i++)
         {
            write(pipe_fd[PIPE_WRITE],envp[i], strlen(envp[i]));
         }
         close(pipe_fd[PIPE_READ]);


     }
}
Was it helpful?

Solution

One obvious problem is that you do not write linefeeds to the pipe, which means that if anything in the whole string you write matches, grep will output the whole string since it is only one line. Try adding a second write after the first:

write(pipe_fd[PIPE_WRITE],"\n",1);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top